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); }
void build_empty_body_for_function( TL::Symbol function_symbol, Nodecl::NodeclBase &function_code, Nodecl::NodeclBase &empty_stmt) { empty_stmt = Nodecl::EmptyStatement::make(make_locus("", 0, 0)); Nodecl::List stmt_list = Nodecl::List::make(empty_stmt); if (IS_C_LANGUAGE || IS_CXX_LANGUAGE) { Nodecl::CompoundStatement compound_statement = Nodecl::CompoundStatement::make(stmt_list, /* destructors */ Nodecl::NodeclBase::null(), make_locus("", 0, 0)); stmt_list = Nodecl::List::make(compound_statement); } Nodecl::NodeclBase context = Nodecl::Context::make( stmt_list, function_symbol.get_related_scope(), make_locus("", 0, 0)); function_symbol.get_internal_symbol()->defined = 1; if (function_symbol.is_dependent_function()) { function_code = Nodecl::TemplateFunctionCode::make(context, // Initializers Nodecl::NodeclBase::null(), function_symbol, make_locus("", 0, 0)); } else { function_code = Nodecl::FunctionCode::make(context, // Initializers Nodecl::NodeclBase::null(), function_symbol, make_locus("", 0, 0)); } function_symbol.get_internal_symbol()->entity_specs.function_code = function_code.get_internal_nodecl(); }
type_t* fortran_rebuild_array_type(type_t* rank0_type, type_t* array_type) { rank0_type = no_ref(rank0_type); ERROR_CONDITION(!fortran_is_scalar_type(rank0_type) && !fortran_is_character_type(rank0_type), "Invalid rank0 type", 0); if (!fortran_is_array_type(array_type)) { return rank0_type; } else { type_t* t = fortran_rebuild_array_type(rank0_type, array_type_get_element_type(array_type)); if (array_type_has_region(array_type)) { return get_array_type_bounds_with_regions(t, array_type_get_array_lower_bound(array_type), array_type_get_array_upper_bound(array_type), array_type_get_array_size_expr_context(array_type), // Why did we do this so difficult? nodecl_make_range( nodecl_shallow_copy(array_type_get_region_lower_bound(array_type)), nodecl_shallow_copy(array_type_get_region_upper_bound(array_type)), nodecl_shallow_copy(array_type_get_region_stride(array_type)), fortran_get_default_integer_type(), make_locus("", 0, 0)), array_type_get_region_size_expr_context(array_type) ); } else if (array_type_with_descriptor(array_type)) { return get_array_type_bounds_with_descriptor(t, array_type_get_array_lower_bound(array_type), array_type_get_array_upper_bound(array_type), array_type_get_array_size_expr_context(array_type)); } else { return get_array_type_bounds(t, array_type_get_array_lower_bound(array_type), array_type_get_array_upper_bound(array_type), array_type_get_array_size_expr_context(array_type)); } } }
void VectorizerVisitorFunction::visit(const Nodecl::FunctionCode& function_code) { // Set up enviroment _environment._external_scope = function_code.retrieve_context(); _environment._local_scope_list.push_back( function_code.get_statements().retrieve_context()); // Get analysis info Vectorizer::initialize_analysis(function_code); // Push FunctionCode as scope for analysis _environment._analysis_scopes.push_back(function_code); //Vectorize function type and parameters TL::Symbol vect_func_sym = function_code.get_symbol(); TL::Type func_type = vect_func_sym.get_type(); TL::ObjectList<TL::Symbol> parameters = vect_func_sym.get_function_parameters(); TL::ObjectList<TL::Type> parameters_type = func_type.parameters(); TL::ObjectList<TL::Type> parameters_vector_type; TL::ObjectList<TL::Type>::iterator it_type; TL::ObjectList<TL::Symbol>::iterator it_param_sym; for(it_param_sym = parameters.begin(), it_type = parameters_type.begin(); it_type != parameters_type.end(); it_param_sym++, it_type++) { TL::Type sym_type = get_qualified_vector_to((*it_type), _environment._vector_length); // Set type to parameter TL::Symbol (*it_param_sym).set_type(sym_type); parameters_vector_type.append(sym_type); } if(_masked_version) { TL::Scope scope = vect_func_sym.get_related_scope(); // Create mask parameter TL::Symbol mask_sym = scope.new_symbol("__mask_param"); mask_sym.get_internal_symbol()->kind = SK_VARIABLE; mask_sym.get_internal_symbol()->entity_specs.is_user_declared = 1; mask_sym.set_type(TL::Type::get_mask_type(_environment._mask_size)); symbol_set_as_parameter_of_function(mask_sym.get_internal_symbol(), vect_func_sym.get_internal_symbol(), parameters.size()); // Add mask symbol and type to parameters parameters.append(mask_sym); parameters_vector_type.append(mask_sym.get_type()); vect_func_sym.set_related_symbols(parameters); // Take care of default_argument_info_t* //TODO: Move this into a function { int num_parameters = vect_func_sym.get_internal_symbol()->entity_specs.num_parameters; default_argument_info_t** default_argument_info = vect_func_sym.get_internal_symbol()->entity_specs.default_argument_info; num_parameters++; default_argument_info = (default_argument_info_t**)xrealloc(default_argument_info, num_parameters * sizeof(*default_argument_info)); default_argument_info[num_parameters-1] = NULL; vect_func_sym.get_internal_symbol()->entity_specs.default_argument_info = default_argument_info; vect_func_sym.get_internal_symbol()->entity_specs.num_parameters = num_parameters; } Nodecl::Symbol mask_nodecl_sym = mask_sym.make_nodecl(true, function_code.get_locus()); _environment._mask_list.push_back(mask_nodecl_sym); } else // Add MaskLiteral to mask_list { Nodecl::MaskLiteral all_one_mask = Nodecl::MaskLiteral::make( TL::Type::get_mask_type(_environment._mask_size), const_value_get_minus_one(_environment._mask_size, 1), make_locus("", 0, 0)); _environment._mask_list.push_back(all_one_mask); } vect_func_sym.set_type(get_qualified_vector_to(func_type.returns(), _environment._vector_length).get_function_returning(parameters_vector_type)); // Vectorize function statements VectorizerVisitorStatement visitor_stmt(_environment); visitor_stmt.walk(function_code.get_statements()); // Add final return if multi-return function if (_environment._function_return.is_valid()) { // Return value Nodecl::Symbol return_value= _environment._function_return.make_nodecl( false, function_code.get_locus()); // VectorizerVisitorExpression visitor_sym(_environment); // visitor_sym.walk(return_value); // Return value at the end of the Compound Statement Nodecl::ReturnStatement return_stmt = Nodecl::ReturnStatement::make(return_value, function_code.get_locus()); function_code.get_statements().as<Nodecl::Context>().get_in_context().as<Nodecl::List>() .front().as<Nodecl::CompoundStatement>().get_statements() .as<Nodecl::List>().append(return_stmt); } _environment._analysis_scopes.pop_back(); _environment._mask_list.pop_back(); // Analysis in functions won't be reused anywhere so it must be freed Vectorizer::finalize_analysis(); }
void Fortran::append_module_to_scope(TL::Symbol module, TL::Scope scope) { ERROR_CONDITION(!module.is_valid() || !module.is_fortran_module(), "Symbol must be a Fortran module", 0); scope_entry_t* used_modules_info = ::get_or_create_used_modules_symbol_info(scope.get_decl_context()); P_LIST_ADD_ONCE(used_modules_info->entity_specs.related_symbols, used_modules_info->entity_specs.num_related_symbols, module.get_internal_symbol()); if (!module.get_internal_symbol()->entity_specs.is_builtin) fortran_load_module(module.get_internal_symbol()->symbol_name, /* intrinsic */ 0, make_locus("", 0, 0)); }
void Fortran::append_used_modules(TL::Scope orig_scope, TL::Scope new_scope) { scope_entry_t* original_used_modules_info = orig_scope.get_related_symbol().get_used_modules().get_internal_symbol(); if (original_used_modules_info != NULL && original_used_modules_info->entity_specs.num_related_symbols != 0) { scope_entry_t* new_used_modules_info = ::get_or_create_used_modules_symbol_info(new_scope.get_decl_context()); // Append all the symbols of the original_used_modules_info to the new list for (int j = 0; j < original_used_modules_info->entity_specs.num_related_symbols; j++) { scope_entry_t* appended_module = original_used_modules_info->entity_specs.related_symbols[j]; P_LIST_ADD_ONCE(new_used_modules_info->entity_specs.related_symbols, new_used_modules_info->entity_specs.num_related_symbols, appended_module); // Make sure the module has been loaded... if (!appended_module->entity_specs.is_builtin) fortran_load_module(appended_module->symbol_name, /* intrinsic */ 0, make_locus("", 0, 0)); } } }
static void handle_ompss_opencl_allocate_intrinsic( Nodecl::FunctionCall function_call, std::map<std::pair<TL::Type, std::pair<int, bool> > , Symbol> &declared_ocl_allocate_functions, Nodecl::NodeclBase expr_stmt) { Nodecl::List arguments = function_call.get_arguments().as<Nodecl::List>(); ERROR_CONDITION(arguments.size() != 1, "More than one argument in 'ompss_opencl_allocate' call\n", 0); Nodecl::NodeclBase actual_argument = arguments[0]; ERROR_CONDITION(!actual_argument.is<Nodecl::FortranActualArgument>(), "Unexpected tree\n", 0); Nodecl::NodeclBase arg = actual_argument.as<Nodecl::FortranActualArgument>().get_argument(); ERROR_CONDITION(!arg.is<Nodecl::ArraySubscript>(), "Unreachable code\n", 0); Nodecl::NodeclBase subscripted = arg.as<Nodecl::ArraySubscript>().get_subscripted(); TL::Symbol subscripted_symbol = ::fortran_data_ref_get_symbol(subscripted.get_internal_nodecl()); ERROR_CONDITION( !(subscripted_symbol.get_type().is_fortran_array() && subscripted_symbol.is_allocatable()) && !(subscripted_symbol.get_type().is_pointer() && subscripted_symbol.get_type().points_to().is_fortran_array()), "The argument of 'ompss_opencl_allocate' intrinsic must be " "an allocatable array or a pointer to an array with all its bounds specified\n", 0); TL::Type array_type; int num_dimensions; bool is_allocatable; if (subscripted_symbol.is_allocatable()) { array_type = subscripted_symbol.get_type(); num_dimensions = subscripted_symbol.get_type().get_num_dimensions(); is_allocatable = true; } else { array_type = subscripted_symbol.get_type().points_to(); num_dimensions = array_type.get_num_dimensions(); is_allocatable = false; } TL::Type element_type = array_type; while (element_type.is_array()) { element_type = element_type.array_element(); } ERROR_CONDITION(!array_type.is_array(), "This type should be an array type", 0); std::pair<TL::Type, std::pair<int, bool> > key = std::make_pair(element_type, std::make_pair(num_dimensions, is_allocatable)); std::map<std::pair<TL::Type, std::pair<int, bool> > , Symbol>::iterator it_new_fun = declared_ocl_allocate_functions.find(key); // Reuse the auxiliar function if it already exists Symbol new_function_sym; if (it_new_fun != declared_ocl_allocate_functions.end()) { new_function_sym = it_new_fun->second; } else { new_function_sym = create_new_function_opencl_allocate( expr_stmt, subscripted_symbol, element_type, num_dimensions, is_allocatable); declared_ocl_allocate_functions[key] = new_function_sym; } // Replace the current intrinsic call by a call to the new function TL::Source actual_arg_array; Nodecl::NodeclBase subscripted_lvalue = subscripted.shallow_copy(); subscripted_lvalue.set_type(subscripted_symbol.get_type().no_ref().get_lvalue_reference_to()); actual_arg_array << as_expression(subscripted_lvalue); TL::Source actual_arg_bounds; Nodecl::List subscripts = arg.as<Nodecl::ArraySubscript>().get_subscripts().as<Nodecl::List>(); for (Nodecl::List::reverse_iterator it = subscripts.rbegin(); it != subscripts.rend(); it++) { Nodecl::NodeclBase subscript = *it, lower, upper; if (it != subscripts.rbegin()) actual_arg_bounds << ", "; if (subscript.is<Nodecl::Range>()) { lower = subscript.as<Nodecl::Range>().get_lower(); upper = subscript.as<Nodecl::Range>().get_upper(); } else { lower = nodecl_make_integer_literal( fortran_get_default_integer_type(), const_value_get_signed_int(1), make_locus("", 0, 0)); upper = subscript; } actual_arg_bounds << as_expression(lower) << "," << as_expression(upper); } TL::Source new_function_call; new_function_call << "CALL " << as_symbol(new_function_sym) << "(" << actual_arg_array << ", " << actual_arg_bounds << ")\n" ; expr_stmt.replace(new_function_call.parse_statement(expr_stmt)); }
TL::Symbol new_function_symbol( TL::Symbol current_function, const std::string& name, TL::Type return_type, TL::ObjectList<std::string> parameter_names, TL::ObjectList<TL::Type> parameter_types) { if (IS_FORTRAN_LANGUAGE && current_function.is_nested_function()) { // Get the enclosing function current_function = current_function.get_scope().get_related_symbol(); } decl_context_t decl_context = current_function.get_scope().get_decl_context(); ERROR_CONDITION(parameter_names.size() != parameter_types.size(), "Mismatch between names and types", 0); decl_context_t function_context; if (IS_FORTRAN_LANGUAGE) { function_context = new_program_unit_context(decl_context); } else { function_context = new_function_context(decl_context); function_context = new_block_context(function_context); } // Build the function type int num_parameters = 0; scope_entry_t** parameter_list = NULL; parameter_info_t* p_types = new parameter_info_t[parameter_types.size()]; parameter_info_t* it_ptypes = &(p_types[0]); TL::ObjectList<TL::Type>::iterator type_it = parameter_types.begin(); for (TL::ObjectList<std::string>::iterator it = parameter_names.begin(); it != parameter_names.end(); it++, it_ptypes++, type_it++) { scope_entry_t* param = new_symbol(function_context, function_context.current_scope, it->c_str()); param->entity_specs.is_user_declared = 1; param->kind = SK_VARIABLE; param->locus = make_locus("", 0, 0); param->defined = 1; param->type_information = get_unqualified_type(type_it->get_internal_type()); P_LIST_ADD(parameter_list, num_parameters, param); it_ptypes->is_ellipsis = 0; it_ptypes->nonadjusted_type_info = NULL; it_ptypes->type_info = get_indirect_type(param); } type_t *function_type = get_new_function_type( return_type.get_internal_type(), p_types, parameter_types.size()); delete[] p_types; // Now, we can create the new function symbol scope_entry_t* new_function_sym = NULL; if (!current_function.get_type().is_template_specialized_type()) { new_function_sym = new_symbol(decl_context, decl_context.current_scope, name.c_str()); new_function_sym->entity_specs.is_user_declared = 1; new_function_sym->kind = SK_FUNCTION; new_function_sym->locus = make_locus("", 0, 0); new_function_sym->type_information = function_type; } else { scope_entry_t* new_template_sym = new_symbol( decl_context, decl_context.current_scope, name.c_str()); new_template_sym->kind = SK_TEMPLATE; new_template_sym->locus = make_locus("", 0, 0); new_template_sym->type_information = get_new_template_type( decl_context.template_parameters, function_type, uniquestr(name.c_str()), decl_context, make_locus("", 0, 0)); template_type_set_related_symbol(new_template_sym->type_information, new_template_sym); // The new function is the primary template specialization new_function_sym = named_type_get_symbol( template_type_get_primary_type( new_template_sym->type_information)); } function_context.function_scope->related_entry = new_function_sym; function_context.block_scope->related_entry = new_function_sym; new_function_sym->related_decl_context = function_context; new_function_sym->entity_specs.related_symbols = parameter_list; new_function_sym->entity_specs.num_related_symbols = num_parameters; for (int i = 0; i < new_function_sym->entity_specs.num_related_symbols; ++i) { symbol_set_as_parameter_of_function( new_function_sym->entity_specs.related_symbols[i], new_function_sym, /* parameter position */ i); } // Make it static new_function_sym->entity_specs.is_static = 1; // Make it member if the enclosing function is member if (current_function.is_member()) { new_function_sym->entity_specs.is_member = 1; new_function_sym->entity_specs.class_type = current_function.get_class_type().get_internal_type(); new_function_sym->entity_specs.access = AS_PUBLIC; ::class_type_add_member(new_function_sym->entity_specs.class_type, new_function_sym); } if (current_function.is_inline()) new_function_sym->entity_specs.is_inline = 1; // new_function_sym->entity_specs.is_defined_inside_class_specifier = // current_function.get_internal_symbol()->entity_specs.is_defined_inside_class_specifier; if (IS_FORTRAN_LANGUAGE && current_function.is_in_module()) { scope_entry_t* module_sym = current_function.in_module().get_internal_symbol(); new_function_sym->entity_specs.in_module = module_sym; P_LIST_ADD( module_sym->entity_specs.related_symbols, module_sym->entity_specs.num_related_symbols, new_function_sym); new_function_sym->entity_specs.is_module_procedure = 1; } return new_function_sym; }