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));
            }
        }
    }
    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));
    }
Beispiel #3
0
 void Symbol::set_related_scope(const TL::Scope &sc)
 {
     _symbol->related_decl_context = sc.get_decl_context();
 }
Beispiel #4
0
        void Core::ompss_common_target_handler_pre(TL::PragmaCustomLine pragma_line,
                OmpSs::TargetContext& target_ctx,
                TL::Scope scope,
                bool is_pragma_task)
        {
            PragmaCustomClause onto = pragma_line.get_clause("onto");
            if (onto.is_defined())
            {
                target_ctx.onto = onto.get_arguments_as_expressions(scope);
            }

            PragmaCustomClause device = pragma_line.get_clause("device");
            if (device.is_defined())
            {
                ObjectList<std::string> device_list =
                    device.get_tokenized_arguments()
                          .map<const char *>(&std::string::c_str)
                          .map<std::string>(&strtolower);

                target_ctx.device_list.insert(device_list);
            }
            else
            {
                // In #pragma omp target a device is mandatory, for #pragma omp task
                // add it only if not empty
                std::string default_device = "smp";
                bool set_default_device = false;
                if (!is_pragma_task)
                {
                    warn_printf_at(pragma_line.get_locus(),
                            "'#pragma omp target' without 'device' clause. Assuming 'device(smp)'\n");
                    set_default_device = true;
                }
                else if (target_ctx.device_list.empty())
                {
                    set_default_device = true;
                    //If onto is defined and there is no device, default device is MPI
                    if (onto.is_defined()) default_device = "mpi";
                }

                if (set_default_device)
                {
                    target_ctx.device_list.clear();
                    target_ctx.device_list.append(default_device);
                }
            }

            PragmaCustomClause copy_in = pragma_line.get_clause("copy_in");
            if (copy_in.is_defined())
            {
                target_ctx.copy_in = parse_dependences_ompss_clause(copy_in, scope);
            }

            PragmaCustomClause copy_out = pragma_line.get_clause("copy_out");
            if (copy_out.is_defined())
            {
                target_ctx.copy_out = parse_dependences_ompss_clause(copy_out, scope);
            }

            PragmaCustomClause copy_inout = pragma_line.get_clause("copy_inout");
            if (copy_inout.is_defined())
            {
                target_ctx.copy_inout = parse_dependences_ompss_clause(copy_inout, scope);
            }

            PragmaCustomClause ndrange = pragma_line.get_clause("ndrange");
            if (ndrange.is_defined())
            {
                target_ctx.ndrange = ndrange.get_arguments_as_expressions(scope);
            }

            PragmaCustomClause shmem = pragma_line.get_clause("shmem");
            if (shmem.is_defined())
            {
                if (ndrange.is_defined())
                {
                    target_ctx.shmem = shmem.get_arguments_as_expressions(scope);
                }
                else
                {
                    warn_printf_at(pragma_line.get_locus(), "'shmem' clause cannot be used without the 'ndrange' clause, skipping\n");
                }
            }

            PragmaCustomClause file = pragma_line.get_clause("file");
            if (file.is_defined())
            {
                ObjectList<std::string> file_list = file.get_tokenized_arguments();
                if (file_list.size() != 1)
                {
                    warn_printf_at(pragma_line.get_locus(), "clause 'file' expects one identifier, skipping\n");
                }
                else
                {
                    target_ctx.file = file_list[0];
                }
            }

            PragmaCustomClause name = pragma_line.get_clause("name");
            if (name.is_defined())
            {
                ObjectList<std::string> name_list = name.get_tokenized_arguments();
                if (name_list.size() != 1)
                {
                    warn_printf_at(pragma_line.get_locus(), "clause 'name' expects one identifier, skipping\n");
                }
                else
                {
                    target_ctx.name = name_list[0];
                }
            }

            PragmaCustomClause copy_deps = pragma_line.get_clause("copy_deps");
            PragmaCustomClause no_copy_deps = pragma_line.get_clause("no_copy_deps");

            if (target_ctx.copy_deps == OmpSs::TargetContext::UNDEF_COPY_DEPS)
            {
                target_ctx.copy_deps = OmpSs::TargetContext::NO_COPY_DEPS;

                if (!copy_deps.is_defined()
                        && !no_copy_deps.is_defined())
                {
                    if (this->in_ompss_mode()
                            && _copy_deps_by_default)
                    {
                        // Copy deps is true only if there is no copy_in, copy_out
                        // or copy_inout
                        if ( !copy_in.is_defined()
                                && !copy_out.is_defined()
                                && !copy_inout.is_defined())
                        {
                            target_ctx.copy_deps = OmpSs::TargetContext::COPY_DEPS;

                            if (!_already_informed_new_ompss_copy_deps)
                            {
                                info_printf_at(pragma_line.get_locus(),
                                        "unless 'no_copy_deps' is specified, "
                                        "the default in OmpSs is now 'copy_deps'\n");
                                info_printf_at(pragma_line.get_locus(),
                                        "this diagnostic is only shown for the "
                                        "first task found\n");

                                _already_informed_new_ompss_copy_deps = true;
                            }
                        }
                    }
                }
                else if (copy_deps.is_defined())
                {
                    target_ctx.copy_deps = OmpSs::TargetContext::COPY_DEPS;
                }
                else if (no_copy_deps.is_defined())
                {
                    target_ctx.copy_deps = OmpSs::TargetContext::NO_COPY_DEPS;
                }
                else
                {
                    internal_error("Code unreachable", 0);
                }
            }
            else if (target_ctx.copy_deps == OmpSs::TargetContext::NO_COPY_DEPS
                    || target_ctx.copy_deps == OmpSs::TargetContext::COPY_DEPS)
            {
                if (copy_deps.is_defined())
                {
                    warn_printf_at(pragma_line.get_locus(),
                            "ignoring 'copy_deps' clause because this context is already '%s'\n",
                            target_ctx.copy_deps == OmpSs::TargetContext::NO_COPY_DEPS ? "no_copy_deps" : "copy_deps");
                }
                if (no_copy_deps.is_defined())
                {
                    warn_printf_at(pragma_line.get_locus(),
                            "ignoring 'no_copy_deps' clause because this context is already '%s'\n",
                            target_ctx.copy_deps == OmpSs::TargetContext::NO_COPY_DEPS ? "no_copy_deps" : "copy_deps");
                }
            }
            else
            {
                internal_error("Code unreachable", 0);
            }
            ERROR_CONDITION(target_ctx.copy_deps == OmpSs::TargetContext::UNDEF_COPY_DEPS,
                    "Invalid value for copy_deps at this point", 0)

            PragmaCustomClause implements = pragma_line.get_clause("implements");
            if (implements.is_defined())
            {
                Symbol function_symbol (NULL);
                if (IS_C_LANGUAGE
                        || IS_CXX_LANGUAGE)
                {
                    ObjectList<Nodecl::NodeclBase> implements_list = implements.get_arguments_as_expressions(scope);

                    ERROR_CONDITION(implements_list.size() != 1, "clause 'implements' expects one identifier", 0);

                    Nodecl::NodeclBase implements_name = implements_list[0];

                    if (implements_name.is<Nodecl::Symbol>())
                    {
                        function_symbol = implements_name.get_symbol();
                    }
                    else if (implements_name.is<Nodecl::CxxDepNameSimple>())
                    {
                        ObjectList<TL::Symbol> symbols = scope.get_symbols_from_name(implements_name.get_text());

                        ERROR_CONDITION(symbols.size() != 1,
                                "The argument of the clause 'implements' cannot be an overloaded function identifier", 0);

                        function_symbol = symbols[0];
                    }
                    else
                    {
                        internal_error("Unexpected node", 0);
                    }
                }
                else if (IS_FORTRAN_LANGUAGE)
                {
                    ObjectList<std::string> implements_list = implements.get_tokenized_arguments();

                    ERROR_CONDITION(implements_list.size() != 1, "clause 'implements' expects one identifier", 0);

                    // Restore the scope chain we broke in an INTERFACE block
                    const decl_context_t* decl_context = scope.get_decl_context();
                    TL::Symbol current_procedure = scope.get_related_symbol();
                    decl_context->current_scope->contained_in = current_procedure.get_internal_symbol()->decl_context->current_scope;

                    TL::Scope fixed_scope = TL::Scope(decl_context);

                    ObjectList<TL::Symbol> symbols = fixed_scope.get_symbols_from_name(strtolower(implements_list[0].c_str()));

                    ERROR_CONDITION(symbols.size() != 1,"Unreachable code", 0);

                    function_symbol = symbols[0];
                }
                else
                {
                    internal_error("Unreachable code", 0);
                }

                if (function_symbol.is_valid()
                        && function_symbol.is_function())
                {
                    target_ctx.has_implements = true;
                    target_ctx.implements = function_symbol;
                }
                else
                {
                    warn_printf_at(pragma_line.get_locus(), "the argument of the clause 'implements' is not a valid identifier, skipping\n");
                }
            }
        }
Beispiel #5
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();
        }