// Create outline for parallel for
        AST_t OpenMPTransform::get_outline_parallel_for(
                PragmaCustomConstruct &construct,
                FunctionDefinition function_definition,
                Source outlined_function_name,
                ForStatement for_statement,
                Statement /* loop_body */,
                ReplaceIdExpression replace_references,
                ObjectList<ParameterInfo> parameter_info_list,
                ObjectList<Symbol> private_references,
                ObjectList<Symbol> firstprivate_references,
                ObjectList<Symbol> lastprivate_references,
                ObjectList<OpenMP::ReductionSymbol> reduction_references,
                ObjectList<Symbol> copyin_references,
                ObjectList<Symbol> copyprivate_references
                )
        {
            // empty
            ObjectList<IdExpression> pass_by_value;

            Source empty;
            Source outline_parallel_for;
            Source parallel_for_body;

            // Get the source of the common parallel X outline
            outline_parallel_for = get_outline_common(
                    function_definition,
                    parallel_for_body,
                    outlined_function_name,
                    parameter_info_list,
                    construct,
                    /* team_parameter */ true);

            Source private_declarations = get_privatized_declarations(
                    construct,
                    private_references,
                    firstprivate_references,
                    lastprivate_references,
                    reduction_references,
                    copyin_references,
                    parameter_info_list
                    ); 

            Source loop_distribution = get_loop_distribution_code(
                    for_statement, 
                    construct,
                    replace_references, 
                    function_definition);

            Source lastprivate_code;

            if (!lastprivate_references.empty())
            {
                Source lastprivate_assignments = get_lastprivate_assignments(
                        firstprivate_references,
                        lastprivate_references, 
                        copyprivate_references,
                        parameter_info_list);

                lastprivate_code
                    << "if (intone_last != 0)"
                    << "{"
                    <<    lastprivate_assignments
                    << "}"
                    ;
            }

            // Barrier is already done at parallel level
            Source loop_finalization = get_loop_finalization(/* do_barrier = */ false);

            Source reduction_update = get_reduction_update(reduction_references);

            Source code_before_entering_team,
                   code_after_leaving_team;
            Source enter_team,
                   leave_team;
            code_before_entering_team
                << "nth_player_t nth_player;"
                << "nth_init_player(&nth_player);"
                ;
            enter_team
                << "nth_enter_team(nth_current_team, &nth_player, 0);"
                ;
            leave_team
                << "nth_leave_team(1);"
                ;
            code_after_leaving_team
                << "nth_end_player(&nth_player);"
                ;

            Source destructor_calls;
            invoke_destructors(parameter_info_list, destructor_calls);

            parallel_for_body 
                << private_declarations

                << comment("Entering team")
                << code_before_entering_team
                << enter_team

                << comment("Construct code")
                << loop_distribution
                << loop_finalization

                << reduction_update
                << lastprivate_code

                << destructor_calls
                << comment("Leaving team")
                << leave_team
                << code_after_leaving_team
                ;

            return finish_outline(function_definition, 
                    outline_parallel_for, 
                    parameter_info_list,
                    /* team_parameter */ true);
        }
        void OpenMPTransform::sections_postorder(PragmaCustomConstruct sections_construct)
        {
            // Get the construct_body of the statement
            Statement construct_body = sections_construct.get_statement();

            // Get the enclosing function definition
            FunctionDefinition function_definition = sections_construct.get_enclosing_function();
            // its scope
            Scope function_scope = function_definition.get_scope();

            ObjectList<Symbol>& shared_references = 
                sections_construct.get_data<ObjectList<Symbol> >("shared_references");
            ObjectList<Symbol>& private_references = 
                sections_construct.get_data<ObjectList<Symbol> >("private_references");
            ObjectList<Symbol>& firstprivate_references = 
                sections_construct.get_data<ObjectList<Symbol> >("firstprivate_references");
            ObjectList<Symbol>& lastprivate_references = 
                sections_construct.get_data<ObjectList<Symbol> >("lastprivate_references");
            ObjectList<OpenMP::ReductionSymbol>& reduction_references =
                sections_construct.get_data<ObjectList<OpenMP::ReductionSymbol> >("reduction_references");
            ObjectList<Symbol>& copyin_references = 
                sections_construct.get_data<ObjectList<Symbol> >("copyin_references");
            ObjectList<Symbol>& copyprivate_references = 
                sections_construct.get_data<ObjectList<Symbol> >("copyprivate_references");

            ObjectList<OpenMP::ReductionSymbol> reduction_empty;

            ReplaceIdExpression replace_references = 
                set_replacements_inline(function_definition,
                        construct_body,
                        shared_references,
                        private_references,
                        firstprivate_references,
                        lastprivate_references,
                        reduction_references,
                        reduction_empty,
                        copyin_references,
                        copyprivate_references);

            int num_sections = num_sections_stack.top();

            Source loop_distribution_code;

            loop_distribution_code = get_loop_distribution_in_sections(num_sections,
                    construct_body,
                    replace_references);

            Source private_declarations = get_privatized_declarations_inline(
                    sections_construct,
                    private_references,
                    firstprivate_references,
                    lastprivate_references,
                    reduction_references,
                    copyin_references
                    ); 

            Source lastprivate_code;

            if (!lastprivate_references.empty())
            {
                Source lastprivate_assignments = get_lastprivate_assignments_inline(
                        lastprivate_references,
                        copyprivate_references);

                lastprivate_code 
                    << "if (intone_last != 0)"
                    << "{"
                    <<    lastprivate_assignments
                    << "}"
                    ;
            }

            PragmaCustomClause nowait_clause = sections_construct.get_clause("nowait");
            Source loop_finalization = get_loop_finalization(/*do_barrier=*/!(nowait_clause.is_defined()));

            Source reduction_code;

            bool orphaned = (parallel_nesting == 0);
            if (orphaned)
            {
                reduction_code = get_critical_reduction_code(reduction_references, sections_construct.get_scope_link());
            }
            else
            {
                reduction_code = get_noncritical_inlined_reduction_code(reduction_references, construct_body);
            }

            Source sections_source;
            sections_source 
                << "{"
                <<    private_declarations
                <<    loop_distribution_code
                <<    lastprivate_code
                <<    reduction_code
                <<    loop_finalization
                << "}"
                ;

            num_sections_stack.pop();

            AST_t sections_tree = sections_source.parse_statement(sections_construct.get_ast(),
                    sections_construct.get_scope_link());

            sections_construct.get_ast().replace(sections_tree);
        }
예제 #3
0
        // Create outline for parallel for
        AST_t OpenMPTransform::get_outline_parallel_for(
                OpenMP::Construct &construct,
                FunctionDefinition function_definition,
                Source outlined_function_name,
                ForStatement for_statement,
                Statement /* loop_body */,
                ReplaceIdExpression replace_references,
                ObjectList<ParameterInfo> parameter_info_list,
                ObjectList<Symbol> private_references,
                ObjectList<Symbol> firstprivate_references,
                ObjectList<Symbol> lastprivate_references,
                ObjectList<OpenMP::ReductionSymbol> reduction_references,
                ObjectList<Symbol> copyin_references,
                ObjectList<Symbol> copyprivate_references,
                OpenMP::Directive directive
                )
        {
            // empty
            ObjectList<IdExpression> pass_by_value;

            Source empty;
            Source outline_parallel_for;
            Source parallel_for_body;

            // Get the source of the common parallel X outline
            outline_parallel_for = get_outline_common(
                    function_definition,
                    parallel_for_body,
                    outlined_function_name,
                    parameter_info_list);

            Source private_declarations = get_privatized_declarations(
                    construct,
                    private_references,
                    firstprivate_references,
                    lastprivate_references,
                    reduction_references,
                    copyin_references,
                    parameter_info_list
                    ); 

            Source loop_distribution = get_loop_distribution_code(for_statement, 
                    replace_references, function_definition, directive);

            Source lastprivate_code;

            if (!lastprivate_references.empty())
            {
                Source lastprivate_assignments = get_lastprivate_assignments(
                        lastprivate_references, 
                        copyprivate_references,
                        parameter_info_list);

                lastprivate_code
                    << "if (intone_last != 0)"
                    << "{"
                    <<    lastprivate_assignments
                    << "}"
                    ;
            }

            // Barrier is already done at parallel level
            Source loop_finalization = get_loop_finalization(/* do_barrier = */ false);

            Source reduction_update = get_reduction_update(reduction_references);

            Source task_block_code;

            parallel_for_body 
                << private_declarations
                << loop_distribution
                << lastprivate_code
                << reduction_update
                << loop_finalization
                << task_block_code
                ;

            task_block_code = get_task_block_code();

            return finish_outline(function_definition, outline_parallel_for, parameter_info_list);
        }