/* Print a statement for copying an array to or from the device, * or for initializing or clearing the device. * The statement identifier of a copying node is called * "to_device_<array name>" or "from_device_<array name>" and * its user pointer points to the gpu_array_info of the array * that needs to be copied. * The node for initializing the device is called "init_device". * The node for clearing the device is called "clear_device". * * Extract the array (if any) from the identifier and call * init_device, clear_device, copy_array_to_device or copy_array_from_device. */ static __isl_give isl_printer *print_device_node(__isl_take isl_printer *p, __isl_keep isl_ast_node *node, struct gpu_prog *prog) { isl_ast_expr *expr, *arg; isl_id *id; const char *name; struct gpu_array_info *array; expr = isl_ast_node_user_get_expr(node); arg = isl_ast_expr_get_op_arg(expr, 0); id = isl_ast_expr_get_id(arg); name = isl_id_get_name(id); array = isl_id_get_user(id); isl_id_free(id); isl_ast_expr_free(arg); isl_ast_expr_free(expr); if (!name) return isl_printer_free(p); if (!strcmp(name, "init_device")) return init_device(p, prog); if (!strcmp(name, "clear_device")) return clear_device(p, prog); if (!array) return isl_printer_free(p); if (!prefixcmp(name, "to_device")) return copy_array_to_device(p, array); else return copy_array_from_device(p, array); }
expression_ptr cpp_from_isl::process_expr(isl_ast_expr * ast_expr) { expression_ptr expr; auto type = isl_ast_expr_get_type(ast_expr); switch(type) { case isl_ast_expr_op: { expr = process_op(ast_expr); break; } case isl_ast_expr_id: { auto id = isl_ast_expr_get_id(ast_expr); string name(isl_id_get_name(id)); isl_id_free(id); if (m_id_func) expr = m_id_func(name); if (!expr) expr = make_shared<id_expression>(name); break; } case isl_ast_expr_int: { auto val = isl_ast_expr_get_val(ast_expr); if (isl_val_is_int(val) != isl_bool_true) throw error("Value is not an integer."); int ival = isl_val_get_num_si(val); isl_val_free(val); expr = literal(ival); break; } default: throw error("Unexpected AST expression type."); } return expr; }
instruction_list * isl_user_to_noclock (isl_ast_node * user_node) { isl_ast_expr * expr = isl_ast_node_user_get_expr (user_node); instruction * user = instruction_alloc (); user->type = INSTR_CALL; user->content.call.identifier = strdup (isl_id_get_name ( isl_ast_expr_get_id (isl_ast_expr_get_op_arg (expr, 0)))); for (int i = 1; i < isl_ast_expr_get_op_n_arg (expr); ++i) { expression_list * e = expression_list_alloc (); e->element = isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, i)); e->next = NULL; user->content.call.arguments = expression_list_cat ( user->content.call.arguments, e); } instruction_list * list = instruction_list_alloc (); list->element = user; list->next = NULL; return list; }
instruction_list * isl_for_to_noclock (isl_ast_node * for_node) { /* Extract the for loop information. */ isl_ast_expr * iterator = isl_ast_node_for_get_iterator (for_node); isl_id * id = isl_ast_expr_get_id (iterator); isl_ast_expr * init = isl_ast_node_for_get_init (for_node); isl_ast_expr * cond = isl_ast_node_for_get_cond (for_node); isl_ast_node * body = isl_ast_node_for_get_body (for_node); /* Construct the for loop. */ instruction * loop = instruction_for_loop ( strdup (isl_id_get_name (id)), isl_init_to_expr (init), isl_cond_to_expr (cond), isl_ast_to_noclock_ast (body)); /* Wrap the loop in an instruction list node. */ instruction_list * list = instruction_list_alloc (); list->element = loop; list->next = NULL; return list; }
isl_ast_node * ast_gen::after_for(isl_ast_node *node, isl_ast_build * builder) { if (verbose<ast_gen>::enabled()) cout << "-- After for" << endl; bool is_deepest_loop = m_deepest_loop == m_current_loop; bool is_requested_parallel = false; { auto iter_expr = isl_ast_node_for_get_iterator(node); auto id = isl_ast_expr_get_id(iter_expr); if (verbose<ast_gen>::enabled()) cout << " Loop iter: " << isl_id_get_name(id) << endl; auto data = isl_id_get_user(id); if (data == &m_parallel_loop_id) { if (verbose<ast_gen>::enabled()) cout << " Requested as parallel" << endl; is_requested_parallel = true; } id = isl_id_free(id); isl_ast_expr_free(iter_expr); } auto id = isl_ast_node_get_annotation(node); auto info = ast_node_info::get_from_id(id); // Mark loop parallel if parallelizable and // either requested by user or outermost parallizable. if (!m_options.parallel) { if (verbose<ast_gen>::enabled()) cout << " Explicit parallelization not enabled." << endl; } else if (!info->is_parallelizable) { if (verbose<ast_gen>::enabled()) cout << " Not parallelizable." << endl; } else if (m_options.parallel_dim < 0) { if (m_num_parallelizable_loops != 1) { if (verbose<ast_gen>::enabled()) cout << " Not the outermost parallelizable loop." << endl; } else { info->is_parallel = true; } } else { if (!is_requested_parallel) { if (verbose<ast_gen>::enabled()) cout << " Not the requested parallel loop." << endl; } else { if (verbose<ast_gen>::enabled()) cout << " Parallelized." << endl; info->is_parallel = true; } } // Mark loop vectorized if parallelizable and deepest. if (m_options.vectorize && is_deepest_loop && info->is_parallelizable) { if (verbose<ast_gen>::enabled()) cout << "-- Loop vectorized." << endl; info->is_vector = true; } if (info->is_parallel || info->is_vector) { store_parallel_accesses_for_current_dimension(builder); } if (info->is_parallelizable) --m_num_parallelizable_loops; --m_current_loop; id = isl_id_free(id); return node; }
expression * isl_expr_to_noclock_expr (isl_ast_expr * expr) { expression * e = NULL; enum isl_ast_expr_type expr_t = isl_ast_expr_get_type (expr); if (expr_t == isl_ast_expr_id) { e = expression_from_identifier (isl_id_get_name ( isl_ast_expr_get_id (expr))); return e; } else if (expr_t == isl_ast_expr_int) { e = expression_from_number ( isl_val_get_num_si (isl_ast_expr_get_val (expr))); return e; } bool binary = false; enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr); switch (t) { case isl_ast_op_max: e = expression_alloc (); expression_set_type (e, EXPR_MAX); binary = true; break; case isl_ast_op_min: e = expression_alloc (); expression_set_type (e, EXPR_MIN); binary = true; break; case isl_ast_op_minus: e = expression_alloc (); expression_set_type (e, EXPR_NEG); break; case isl_ast_op_add: e = expression_alloc (); expression_set_type (e, EXPR_ADD); binary = true; break; case isl_ast_op_sub: e = expression_alloc (); expression_set_type (e, EXPR_SUB); binary = true; break; case isl_ast_op_mul: e = expression_alloc (); expression_set_type (e, EXPR_MULT); binary = true; break; case isl_ast_op_div: case isl_ast_op_fdiv_q: case isl_ast_op_pdiv_q: case isl_ast_op_pdiv_r: e = expression_alloc (); expression_set_type (e, EXPR_DIV); binary = true; break; case isl_ast_op_member: case isl_ast_op_cond: case isl_ast_op_select: return e; break; case isl_ast_op_eq: e = expression_alloc (); expression_set_type (e, EXPR_EQ); binary = true; break; case isl_ast_op_le: e = expression_alloc (); expression_set_type (e, EXPR_LE); binary = true; break; case isl_ast_op_lt: e = expression_alloc (); expression_set_type (e, EXPR_LT); binary = true; break; case isl_ast_op_ge: e = expression_alloc (); expression_set_type (e, EXPR_GE); binary = true; break; case isl_ast_op_gt: e = expression_alloc (); expression_set_type (e, EXPR_GT); binary = true; break; case isl_ast_op_and: case isl_ast_op_and_then: e = expression_alloc (); expression_set_type (e, EXPR_AND); binary = true; break; case isl_ast_op_or: case isl_ast_op_or_else: e = expression_alloc (); expression_set_type (e, EXPR_OR); binary = true; break; case isl_ast_op_call: case isl_ast_op_access: case isl_ast_op_address_of: default: return e; break; } if (binary) { expression_set_left_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 0))); expression_set_right_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 1))); } else { expression_set_left_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 0))); } return e; }