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

    }
Exemple #3
0
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));
        }
    }
}
Exemple #4
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();
        }
    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));

    }
Exemple #8
0
    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;
    }