TL::ObjectList<NodeclBase> List::to_object_list() const { TL::ObjectList<NodeclBase> result; for (List::const_iterator it = this->begin(); it != this->end(); ++it) { result.append(*it); } return result; }
static void add_copy_items(PragmaCustomLine construct, DataEnvironment& data_sharing_environment, const ObjectList<Nodecl::NodeclBase>& list, TL::OmpSs::CopyDirection copy_direction, TL::OmpSs::TargetInfo& target_info, bool in_ompss_mode) { TL::ObjectList<TL::OmpSs::CopyItem> items; for (ObjectList<Nodecl::NodeclBase>::const_iterator it = list.begin(); it != list.end(); it++) { DataReference expr(*it); std::string warning; if (!expr.is_valid()) { expr.commit_diagnostic(); warn_printf_at(construct.get_locus(), "'%s' is not a valid copy data-reference, skipping\n", expr.prettyprint().c_str()); continue; } // In OmpSs copies we may fix the data-sharing to something more natural if (in_ompss_mode) { Symbol sym = expr.get_base_symbol(); // In OmpSs, the storage of a copy is always SHARED. Note that with this // definition we aren't defining the data-sharings of the variables involved // in that expression. // // About the data-sharings of the variables involved in the copy expression: // - Fortran: the base symbol of the copy expression is always SHARED // - C/C++: // * The base symbol of a trivial copy (i.e the expression is a symbol) must always be SHARED: // int x, a[10]; // copy_inout(x) -> shared(x) // copy_inout(a) -> shared(a) // * The base symbol of an array expression or a reference to an array must be SHARED too: // copy_int a[10]; // copy_inout(a[4]) -> shared(a) // copy_inout(a[1:2]) -> shared(a) // * The base symbol of a class member access must be shared too: // struct C { int z; } c; // copy_inout(c.z) -> shared(c) // * Otherwise, the data-sharing of the base symbol is FIRSTPRIVATE: // int* p; // copy_inout(*p) -> firstprivate(p) // copy_inout(p[10]) -> firstprivate(p) // copy_inout(p[1:2]) -> firstprivate(p) // copy_inout([10][20] p) -> firstprivate(p) if (IS_FORTRAN_LANGUAGE) { data_sharing_environment.set_data_sharing(sym, DS_SHARED, DSK_IMPLICIT, "the variable is mentioned in a copy and it did not have an explicit data-sharing"); } else if (expr.is<Nodecl::Symbol>()) { data_sharing_environment.set_data_sharing(sym, DS_SHARED, DSK_IMPLICIT, "the variable is mentioned in a copy and it did not have an explicit data-sharing"); } else if (sym.get_type().is_array() || (sym.get_type().is_any_reference() && sym.get_type().references_to().is_array())) { data_sharing_environment.set_data_sharing(sym, DS_SHARED, DSK_IMPLICIT, "the variable is an array mentioned in a non-trivial copy " "and it did not have an explicit data-sharing"); } else if (sym.get_type().is_class()) { data_sharing_environment.set_data_sharing(sym, DS_SHARED, DSK_IMPLICIT, "the variable is an object mentioned in a non-trivial dependence " "and it did not have an explicit data-sharing"); } else { data_sharing_environment.set_data_sharing(sym, DS_FIRSTPRIVATE, DSK_IMPLICIT, "the variable is a non-array mentioned in a non-trivial copy " "and it did not have an explicit data-sharing"); } } TL::OmpSs::CopyItem copy_item(expr, copy_direction); items.append(copy_item); } switch (copy_direction) { case TL::OmpSs::COPY_DIR_IN: { target_info.append_to_copy_in(items); break; } case TL::OmpSs::COPY_DIR_OUT: { target_info.append_to_copy_out(items); break; } case TL::OmpSs::COPY_DIR_INOUT: { target_info.append_to_copy_inout(items); break; } default: { internal_error("Unreachable code", 0); } } }
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(); }