Beispiel #1
0
 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;
 }
Beispiel #2
0
        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);
                    }
            }
        }
Beispiel #3
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();
        }