// 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); }
// 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); }