void MethodBlock::ret(DexType* rtype, Location loc) { if (rtype != get_void_type()) { ret(loc); } else { ret_void(); } }
void MethodCreator::forward_method_to(DexMethod* meth, DexMethod* smeth) { auto code = meth->get_code(); if (code != nullptr) { meth->set_code(nullptr); delete code; } MethodCreator mc(meth); MethodBlock* block = mc.get_main_block(); std::vector<Location> args; auto proto = smeth->get_proto(); auto rtype = proto->get_rtype(); auto meth_args = proto->get_args(); if (meth_args != nullptr) { uint16_t arg_count = static_cast<uint16_t>(meth_args->get_type_list().size()); for (auto i = 0; i < arg_count; ++i) { args.push_back(mc.get_local(i)); } } block->invoke(smeth, args); if (rtype == get_void_type()) { block->ret_void(); } else { auto ret = mc.make_local(rtype); block->move_result(ret, rtype); block->ret(ret); } mc.create(); }
static void init_spu_types(void) { V16QI_type_node = build_vector_type (intQI_type_node, 16); V8HI_type_node = build_vector_type (intHI_type_node, 16); V4SI_type_node = build_vector_type (intSI_type_node, 16); V2DI_type_node = build_vector_type (intDI_type_node, 16); V4SF_type_node = build_vector_type (float_type_node, 16); V2DF_type_node = build_vector_type (double_type_node, 16); unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16); unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 16); unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 16); unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 16); spu_builtin_types[SPU_BTI_QUADWORD] = V16QI_type_node; spu_builtin_types[SPU_BTI_7] = get_signed_int_type(); spu_builtin_types[SPU_BTI_S7] = get_signed_int_type(); spu_builtin_types[SPU_BTI_U7] = get_signed_int_type(); spu_builtin_types[SPU_BTI_S10] = get_signed_int_type(); spu_builtin_types[SPU_BTI_S10_4] = get_signed_int_type(); spu_builtin_types[SPU_BTI_U14] = get_signed_int_type(); spu_builtin_types[SPU_BTI_16] = get_signed_int_type(); spu_builtin_types[SPU_BTI_S16] = get_signed_int_type(); spu_builtin_types[SPU_BTI_S16_2] = get_signed_int_type(); spu_builtin_types[SPU_BTI_U16] = get_signed_int_type(); spu_builtin_types[SPU_BTI_U16_2] = get_signed_int_type(); spu_builtin_types[SPU_BTI_U18] = get_signed_int_type(); spu_builtin_types[SPU_BTI_INTQI] = get_signed_char_type(); spu_builtin_types[SPU_BTI_INTHI] = get_signed_short_int_type(); spu_builtin_types[SPU_BTI_INTSI] = get_signed_int_type(); spu_builtin_types[SPU_BTI_INTDI] = get_signed_long_long_int_type(); spu_builtin_types[SPU_BTI_UINTQI] = get_unsigned_char_type(); spu_builtin_types[SPU_BTI_UINTHI] = get_unsigned_short_int_type(); spu_builtin_types[SPU_BTI_UINTSI] = get_unsigned_int_type(); spu_builtin_types[SPU_BTI_UINTDI] = get_unsigned_long_long_int_type(); spu_builtin_types[SPU_BTI_FLOAT] = get_float_type(); spu_builtin_types[SPU_BTI_DOUBLE] = get_double_type(); spu_builtin_types[SPU_BTI_VOID] = get_void_type(); spu_builtin_types[SPU_BTI_PTR] = get_cv_qualified_type(get_pointer_type(get_void_type()), CV_CONST | CV_VOLATILE); }
void upc_sign_in_builtins(const decl_context_t* decl_context) { // THREADS scope_entry_t* upc_THREADS; upc_THREADS = new_symbol(decl_context, decl_context->global_scope, UNIQUESTR_LITERAL("THREADS")); upc_THREADS->kind = SK_VARIABLE; upc_THREADS->type_information = get_const_qualified_type(get_signed_int_type()); upc_THREADS->defined = 1; upc_THREADS->do_not_print = 1; upc_THREADS->locus = make_locus("(global scope)", 0, 0); symbol_entity_specs_set_is_builtin(upc_THREADS, 1); if (CURRENT_CONFIGURATION->upc_threads != NULL) { upc_THREADS->value = internal_expression_parse(CURRENT_CONFIGURATION->upc_threads, decl_context); } // MYTHREAD scope_entry_t* upc_MYTHREAD; upc_MYTHREAD = new_symbol(decl_context, decl_context->global_scope, UNIQUESTR_LITERAL("MYTHREAD")); upc_MYTHREAD->kind = SK_VARIABLE; upc_MYTHREAD->type_information = get_const_qualified_type(get_signed_int_type()); upc_MYTHREAD->defined = 1; upc_MYTHREAD->do_not_print = 1; upc_MYTHREAD->locus = make_locus("(global scope)", 0, 0); symbol_entity_specs_set_is_builtin(upc_MYTHREAD, 1); // UPC_MAX_BLOCK_SIZE scope_entry_t* upc_UPC_MAX_BLOCK_SIZE; upc_UPC_MAX_BLOCK_SIZE = new_symbol(decl_context, decl_context->global_scope, UNIQUESTR_LITERAL("UPC_MAX_BLOCK_SIZE")); upc_UPC_MAX_BLOCK_SIZE->kind = SK_VARIABLE; upc_UPC_MAX_BLOCK_SIZE->type_information = get_const_qualified_type(get_signed_int_type()); upc_UPC_MAX_BLOCK_SIZE->defined = 1; upc_UPC_MAX_BLOCK_SIZE->do_not_print = 1; upc_UPC_MAX_BLOCK_SIZE->locus = make_locus("(global scope)", 0, 0); symbol_entity_specs_set_is_builtin(upc_UPC_MAX_BLOCK_SIZE, 1); // upc_lock_t scope_entry_t* upc_lock_t; upc_lock_t = new_symbol(decl_context, decl_context->global_scope, UNIQUESTR_LITERAL("upc_lock_t")); upc_lock_t->kind = SK_TYPEDEF; upc_lock_t->defined = 1; upc_lock_t->type_information = get_void_type(); upc_lock_t->do_not_print = 1; upc_lock_t->locus = make_locus("(global scope)", 0, 0); symbol_entity_specs_set_is_builtin(upc_lock_t, 1); }
type_t* get_implicit_type_for_symbol(decl_context_t decl_context, const char* name) { type_t* implicit_type = NULL; if (decl_context.implicit_info->data->implicit_letter_set != NULL) { implicit_type = (*(decl_context.implicit_info->data->implicit_letter_set))[tolower(name[0]) - 'a']; } if (implicit_type == NULL) implicit_type = get_void_type(); return implicit_type; }
void LoweringVisitor::reduction_initialization_code( OutlineInfo& outline_info, Nodecl::NodeclBase ref_tree, Nodecl::NodeclBase construct) { ERROR_CONDITION(ref_tree.is_null(), "Invalid tree", 0); if (!Nanos::Version::interface_is_at_least("master", 5023)) { running_error("%s: error: a newer version of Nanos++ (>=5023) is required for reductions support\n", construct.get_locus_str().c_str()); } TL::ObjectList<OutlineDataItem*> reduction_items = outline_info.get_data_items().filter( predicate(lift_pointer(functor(&OutlineDataItem::is_reduction)))); ERROR_CONDITION (reduction_items.empty(), "No reductions to process", 0); Source result; Source reduction_declaration, thread_initializing_reduction_info, thread_fetching_reduction_info; result << reduction_declaration << "{" << as_type(get_bool_type()) << " red_single_guard;" << "nanos_err_t err;" << "err = nanos_enter_sync_init(&red_single_guard);" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << "if (red_single_guard)" << "{" << "int nanos_num_threads = nanos_omp_get_num_threads();" << thread_initializing_reduction_info << "err = nanos_release_sync_init();" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << "}" << "else" << "{" << "err = nanos_wait_sync_init();" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << thread_fetching_reduction_info << "}" << "}" ; for (TL::ObjectList<OutlineDataItem*>::iterator it = reduction_items.begin(); it != reduction_items.end(); it++) { std::string nanos_red_name = "nanos_red_" + (*it)->get_symbol().get_name(); std::pair<OpenMP::Reduction*, TL::Type> reduction_info = (*it)->get_reduction_info(); OpenMP::Reduction* reduction = reduction_info.first; TL::Type reduction_type = reduction_info.second; if (reduction_type.is_any_reference()) reduction_type = reduction_type.references_to(); TL::Type reduction_element_type = reduction_type; if (IS_FORTRAN_LANGUAGE) { while (reduction_element_type.is_fortran_array()) reduction_element_type = reduction_element_type.array_element(); } else { while (reduction_element_type.is_array()) reduction_element_type = reduction_element_type.array_element(); } Source element_size; if (IS_FORTRAN_LANGUAGE) { if (reduction_type.is_fortran_array()) { // We need to parse this bit in Fortran Source number_of_bytes; number_of_bytes << "SIZE(" << (*it)->get_symbol().get_name() << ") * " << reduction_element_type.get_size(); element_size << as_expression(number_of_bytes.parse_expression(construct)); } else { element_size << "sizeof(" << as_type(reduction_type) << ")"; } } else { element_size << "sizeof(" << as_type(reduction_type) << ")"; } reduction_declaration << "nanos_reduction_t* " << nanos_red_name << ";" ; Source allocate_private_buffer, cleanup_code; Source num_scalars; TL::Symbol basic_reduction_function, vector_reduction_function; create_reduction_function(reduction, construct, reduction_type, basic_reduction_function, vector_reduction_function); (*it)->reduction_set_basic_function(basic_reduction_function); thread_initializing_reduction_info << "err = nanos_malloc((void**)&" << nanos_red_name << ", sizeof(nanos_reduction_t), " << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << nanos_red_name << "->original = (void*)" << (reduction_type.is_array() ? "" : "&") << (*it)->get_symbol().get_name() << ";" << allocate_private_buffer << nanos_red_name << "->vop = " << (vector_reduction_function.is_valid() ? as_symbol(vector_reduction_function) : "0") << ";" << nanos_red_name << "->bop = (void(*)(void*,void*,int))" << as_symbol(basic_reduction_function) << ";" << nanos_red_name << "->element_size = " << element_size << ";" << nanos_red_name << "->num_scalars = " << num_scalars << ";" << cleanup_code << "err = nanos_register_reduction(" << nanos_red_name << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" ; if (IS_C_LANGUAGE || IS_CXX_LANGUAGE) { if (reduction_type.is_array()) { num_scalars << "sizeof(" << as_type(reduction_type) << ") / sizeof(" << as_type(reduction_element_type) <<")"; } else { num_scalars << "1"; } allocate_private_buffer << "err = nanos_malloc(&" << nanos_red_name << "->privates, sizeof(" << as_type(reduction_type) << ") * nanos_num_threads, " << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << nanos_red_name << "->descriptor = " << nanos_red_name << "->privates;" << "rdv_" << (*it)->get_field_name() << " = (" << as_type( (*it)->get_private_type().get_pointer_to() ) << ")" << nanos_red_name << "->privates;" ; thread_fetching_reduction_info << "err = nanos_reduction_get(&" << nanos_red_name << ", " << (reduction_type.is_array() ? "" : "&") << (*it)->get_symbol().get_name() << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << "rdv_" << (*it)->get_field_name() << " = (" << as_type( (*it)->get_private_type().get_pointer_to() ) << ")" << nanos_red_name << "->privates;" ; cleanup_code << nanos_red_name << "->cleanup = nanos_free0;" ; } else if (IS_FORTRAN_LANGUAGE) { Type private_reduction_vector_type; Source extra_dims; { TL::Type t = (*it)->get_symbol().get_type().no_ref(); int rank = 0; if (t.is_fortran_array()) { rank = t.fortran_rank(); } if (rank != 0) { // We need to parse this bit in Fortran Source size_call; size_call << "SIZE(" << (*it)->get_symbol().get_name() << ")"; num_scalars << as_expression(size_call.parse_expression(construct)); } else { num_scalars << "1"; } private_reduction_vector_type = fortran_get_n_ranked_type_with_descriptor( get_void_type(), rank + 1, construct.retrieve_context().get_decl_context()); int i; for (i = 0; i < rank; i++) { Source lbound_src; lbound_src << "LBOUND(" << (*it)->get_symbol().get_name() << ", DIM = " << (rank - i) << ")"; Source ubound_src; ubound_src << "UBOUND(" << (*it)->get_symbol().get_name() << ", DIM = " << (rank - i) << ")"; extra_dims << "[" << as_expression(lbound_src.parse_expression(construct)) << ":" << as_expression(ubound_src.parse_expression(construct)) << "]"; t = t.array_element(); } } allocate_private_buffer << "@FORTRAN_ALLOCATE@((*rdv_" << (*it)->get_field_name() << ")[0:(nanos_num_threads-1)]" << extra_dims <<");" << nanos_red_name << "->privates = &(*rdv_" << (*it)->get_field_name() << ");" << "err = nanos_malloc(&" << nanos_red_name << "->descriptor, sizeof(" << as_type(private_reduction_vector_type) << "), " << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << "err = nanos_memcpy(" << nanos_red_name << "->descriptor, " "&rdv_" << (*it)->get_field_name() << ", sizeof(" << as_type(private_reduction_vector_type) << "));" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" ; thread_fetching_reduction_info << "err = nanos_reduction_get(&" << nanos_red_name << ", &" << (*it)->get_symbol().get_name() << ");" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" << "err = nanos_memcpy(" << "&rdv_" << (*it)->get_field_name() << "," << nanos_red_name << "->descriptor, " << "sizeof(" << as_type(private_reduction_vector_type) << "));" << "if (err != NANOS_OK)" << "nanos_handle_error(err);" ; TL::Symbol reduction_cleanup = create_reduction_cleanup_function(reduction, construct); cleanup_code << nanos_red_name << "->cleanup = " << as_symbol(reduction_cleanup) << ";" ; } else { internal_error("Code unreachable", 0); } } FORTRAN_LANGUAGE() { Source::source_language = SourceLanguage::C; } ref_tree.replace(result.parse_statement(ref_tree)); FORTRAN_LANGUAGE() { Source::source_language = SourceLanguage::Current; } }