// 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);
        }
Exemplo n.º 2
0
        AST_t OpenMPTransform::get_outline_parallel_single(
                OpenMP::Construct &construct,
                FunctionDefinition function_definition,
                Source outlined_function_name,
                Statement construct_body,
                ReplaceIdExpression replace_references,
                ObjectList<ParameterInfo> parameter_info,
                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 --?? */
                )
        {
            ObjectList<IdExpression> pass_by_value;

            Source outline_parallel;
            Source parallel_body;
            Source empty;

            outline_parallel = get_outline_common(
                    function_definition,
                    parallel_body, // The body of the outline
                    outlined_function_name,
                    parameter_info);

            // Replace references using set "replace_references" over construct body
            Statement modified_parallel_body_stmt = replace_references.replace(construct_body);

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

            Source reduction_update = get_reduction_update(reduction_references);

            Source single_source;

            Source barrier_code;

            Source instrumentation_code_before, instrumentation_code_after;
            single_source
                << "{"
                <<   "int nth_low;"
                <<   "int nth_upper;"
                <<   "int nth_step;"
                <<   "int nth_chunk;"
                <<   "int nth_schedule;"
                <<   "int nth_dummy1;"
                <<   "int nth_dummy2;"
                <<   "int nth_dummy3;"
                <<   "int nth_barrier; "

                <<   "nth_low = 0;"
                <<   "nth_upper = 0;"
                <<   "nth_step = 1;"
                <<   "nth_schedule = 2;" // Dynamic
                <<   "nth_chunk = 1;"

                //                    <<   "extern void in__tone_begin_for_(int*, int*, int*, int*, int*);"
                //                    <<   "extern int in__tone_next_iters_(int*, int*, int*);"
                //                    <<   "extern void in__tone_end_for_(int*);"

                <<   "in__tone_begin_for_ (&nth_low, &nth_upper, &nth_step, &nth_chunk, &nth_schedule);"
                <<   "while (in__tone_next_iters_ (&nth_dummy1, &nth_dummy2, &nth_dummy3) != 0)"
                <<   "{"
                <<       instrumentation_code_before
                <<       modified_parallel_body_stmt.prettyprint()
                <<       instrumentation_code_after
                <<   "}"
                <<   barrier_code
                << "}"
                ;

            barrier_code << "nth_barrier = 1;";
            barrier_code << "in__tone_end_for_(&nth_barrier);";

            instrumentation_outline(instrumentation_code_before,
                    instrumentation_code_after, 
                    function_definition,
                    construct_body);

            Source task_block_code;

            parallel_body 
                << private_declarations
                << single_source
                << task_block_code
                ;

            task_block_code = get_task_block_code();

            return finish_outline(function_definition, outline_parallel, parameter_info);
        }
Exemplo n.º 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);
        }