// 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);
        }
Esempio n. 2
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);
        }