void OpenMPTransform::parallel_for_postorder(PragmaCustomConstruct parallel_for_construct)
        {
            // One more parallel seen
            num_parallels++;

            // Decrease the parallel nesting level 
            parallel_nesting--;

            // Get the enclosing function definition
            FunctionDefinition function_definition = parallel_for_construct.get_enclosing_function();
            Scope function_scope = function_definition.get_scope();
            IdExpression function_name = function_definition.get_function_name();

            // This was computed in the preorder
            ObjectList<Symbol>& shared_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("shared_references");
            ObjectList<Symbol>& private_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("private_references");
            ObjectList<Symbol>& firstprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("firstprivate_references");
            ObjectList<Symbol>& lastprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("lastprivate_references");
            ObjectList<OpenMP::ReductionSymbol>& reduction_references =
                parallel_for_construct.get_data<ObjectList<OpenMP::ReductionSymbol> >("reduction_references");
            ObjectList<Symbol>& copyin_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("copyin_references");
            ObjectList<Symbol>& copyprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("copyprivate_references");

            // Get the construct_body of the statement
            Statement construct_body = parallel_for_construct.get_statement();
            // The construct is in fact a ForStatement in a #pragma omp parallel do
            ForStatement for_statement(construct_body);
            Statement loop_body = for_statement.get_loop_body();

            // Create the replacement map and the pass_by_pointer set
            ObjectList<ParameterInfo> parameter_info_list;
            ReplaceIdExpression replace_references = 
                set_replacements(function_definition,
                        loop_body,
                        shared_references,
                        private_references,
                        firstprivate_references,
                        lastprivate_references,
                        reduction_references,
                        inner_reductions_stack.top(),
                        copyin_references,
                        copyprivate_references,
                        parameter_info_list);

            // Get the outline function name
            Source outlined_function_name = get_outlined_function_name(function_name);

            // Create the outline for parallel for
            AST_t outline_code = get_outline_parallel_for(
                    parallel_for_construct,
                    function_definition,
                    outlined_function_name, 
                    for_statement,
                    loop_body,
                    replace_references,
                    parameter_info_list,
                    private_references,
                    firstprivate_references,
                    lastprivate_references,
                    reduction_references,
                    copyin_references,
                    copyprivate_references);

            // Now prepend the outline
            function_definition.get_ast().prepend_sibling_function(outline_code);

            PragmaCustomClause if_clause = parallel_for_construct.get_clause("if");
            PragmaCustomClause num_threads = parallel_for_construct.get_clause("num_threads");
            PragmaCustomClause groups_clause = parallel_for_construct.get_clause("groups");

            Source instrument_code_before;
            Source instrument_code_after;

            AST_t spawn_code = get_parallel_spawn_code(
                    parallel_for_construct.get_ast(),
                    function_definition,
                    parallel_for_construct.get_scope(),
                    parallel_for_construct.get_scope_link(),
                    parameter_info_list,
                    reduction_references,
                    if_clause,
                    num_threads,
                    groups_clause,
                    instrument_code_before,
                    instrument_code_after
                    );

            // Discard inner reduction information
            inner_reductions_stack.pop();

            // Replace all the whole construct with spawn_code
            parallel_for_construct.get_ast().replace(spawn_code);
        }
Beispiel #2
0
        void OpenMPTransform::parallel_for_postorder(OpenMP::ParallelForConstruct parallel_for_construct)
        {
            // One more parallel seen
            num_parallels++;

            // Remove the induction var from the stack
            induction_var_stack.pop();

            // Decrease the parallel nesting level 
            parallel_nesting--;

            // Get the directive
            OpenMP::Directive directive = parallel_for_construct.directive();

            // Get the enclosing function definition
            FunctionDefinition function_definition = parallel_for_construct.get_enclosing_function();
            Scope function_scope = function_definition.get_scope();
            IdExpression function_name = function_definition.get_function_name();

            // This was computed in the preorder
            ObjectList<Symbol>& shared_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("shared_references");
            ObjectList<Symbol>& private_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("private_references");
            ObjectList<Symbol>& firstprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("firstprivate_references");
            ObjectList<Symbol>& lastprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("lastprivate_references");
            ObjectList<OpenMP::ReductionSymbol>& reduction_references =
                parallel_for_construct.get_data<ObjectList<OpenMP::ReductionSymbol> >("reduction_references");
            ObjectList<Symbol>& copyin_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("copyin_references");
            ObjectList<Symbol>& copyprivate_references = 
                parallel_for_construct.get_data<ObjectList<Symbol> >("copyprivate_references");

            // Get the construct_body of the statement
            Statement construct_body = parallel_for_construct.body();
            // The construct is in fact a ForStatement in a #pragma omp parallel do
            ForStatement for_statement(construct_body);
            Statement loop_body = for_statement.get_loop_body();

            // Create the replacement map and the pass_by_pointer set
            ObjectList<ParameterInfo> parameter_info_list;
            ReplaceIdExpression replace_references = 
                set_replacements(function_definition,
                        directive,
                        loop_body,
                        shared_references,
                        private_references,
                        firstprivate_references,
                        lastprivate_references,
                        reduction_references,
                        inner_reductions_stack.top(),
                        copyin_references,
                        copyprivate_references,
                        parameter_info_list);

            // Get the outline function name
            Source outlined_function_name = get_outlined_function_name(function_name);

            // Create the outline for parallel for
            AST_t outline_code = get_outline_parallel_for(
                    parallel_for_construct,
                    function_definition,
                    outlined_function_name, 
                    for_statement,
                    loop_body,
                    replace_references,
                    parameter_info_list,
                    private_references,
                    firstprivate_references,
                    lastprivate_references,
                    reduction_references,
                    copyin_references,
                    copyprivate_references,
                    directive);

            // Now prepend the outline
            function_definition.get_ast().prepend_sibling_function(outline_code);

            OpenMP::Clause num_threads = directive.num_threads_clause();
            OpenMP::CustomClause groups_clause = directive.custom_clause("groups");

            Source instrument_code_before;
            Source instrument_code_after;
            if (instrumentation_requested())
            {
                instrument_code_before
                    << "const int EVENT_PARALLEL = 60000001;"
                    << "const int VALUE_PARALLEL_FOR = 1;"
                    << "mintaka_event(EVENT_PARALLEL, VALUE_PARALLEL_FOR);"
                    << "mintaka_state_schedule();"
                    ;
                instrument_code_after
                    << "const int VALUE_PARALLEL_CLOSE = 0;"
                    << "mintaka_event(EVENT_PARALLEL, VALUE_PARALLEL_CLOSE);"
                    << "mintaka_state_run();"
                    ;
            }

            AST_t spawn_code = get_parallel_spawn_code(
                    parallel_for_construct.get_ast(),
                    function_definition,
                    parallel_for_construct.get_scope(),
                    parallel_for_construct.get_scope_link(),
                    parameter_info_list,
                    reduction_references,
                    num_threads,
                    groups_clause,
                    instrument_code_before,
                    instrument_code_after
                    );

            // Discard inner reduction information
            inner_reductions_stack.pop();

            // Replace all the whole construct with spawn_code
            parallel_for_construct.get_ast().replace(spawn_code);
        }