static stmt_code(stream, node, brk, cont, ret) { /* Handle the null expression. */ if ( !node ) return; auto op = node[0]; /* For debugging purposes, put a blank line between each statement. */ fputs("\n", stream); if ( op == 'dcls' ) declaration( stream, node ); else if ( op == 'brea' ) branch( stream, brk ); else if ( op == 'cont' ) branch( stream, cont ); else if ( op == 'retu' ) return_stmt( stream, node, ret ); else if ( op == 'goto' ) goto_stmt( stream, node ); else if ( op == 'if' ) if_stmt( stream, node, brk, cont, ret ); else if ( op == 'whil' ) while_stmt( stream, node, brk, cont, ret ); else if ( op == 'for' ) for_stmt( stream, node, brk, cont, ret ); else if ( op == 'do' ) do_stmt( stream, node, brk, cont, ret ); else if ( op == 'swit' ) switch_stmt( stream, node, brk, cont, ret ); else if ( op == 'case' || op == 'defa' ) case_stmt( stream, node, brk, cont, ret ); else if ( op == ':' ) label_stmt( stream, node, brk, cont, ret ); else if ( op == '{}' ) do_block( stream, node, brk, cont, ret ); else expr_code( stream, node, 0 ); }
LoopNormalize& LoopNormalize::set_loop(Nodecl::NodeclBase loop) { this->_loop = loop; ERROR_CONDITION (!this->_loop.is<Nodecl::ForStatement>(), "Only ForStatement can be unrolled. This is a %s", ast_print_node_type(loop.get_kind())); Nodecl::NodeclBase loop_control = this->_loop.as<Nodecl::ForStatement>().get_loop_header(); ERROR_CONDITION(!loop_control.is<Nodecl::LoopControl>() && !loop_control.is<Nodecl::RangeLoopControl>(), "Only LoopControl or RangeLoopControl can be unrolled", 0); TL::ForStatement for_stmt(loop.as<Nodecl::ForStatement>()); ERROR_CONDITION(!for_stmt.is_omp_valid_loop(), "Loop is too complicated", 0); return *this; }
TreeNode * statement(void) { TreeNode * t = NULL; switch (token) { case IF : t = if_stmt(); break; case REPEAT : t = repeat_stmt(); break; case FOR : t = for_stmt(); break; //ADICIONADO O FOR COMO UMA DECLARAÇÃO case ID : t = assign_stmt(); break; case READ : t = read_stmt(); break; case WRITE : t = write_stmt(); break; default : syntaxError("unexpected token -> "); printToken(token,tokenString); token = getToken(); break; } /* end case */ return t; }
TreeNode * statement(void) //statement -> expression| if_stmt| while_stmt|for_stmt|var_stmt|assign_stmt { TreeNode * t = NULL; switch (token) { case IF : t = if_stmt(); break; case FOR : t = for_stmt(); break; case ID : t = assign_stmt(); break; case WHILE : t = while_stmt(); break; case INT : case CHAR : t = var_stmt(); break; case RBRACE : match(RBRACE); break; default : syntaxError("unexpected token -> "); printToken(token,tokenString); token = getToken(); break; } /* end case */ return t; }
void LoopNormalize::normalize() { Nodecl::ForStatement loop = this->_loop.as<Nodecl::ForStatement>(); TL::Scope orig_loop_scope = loop.retrieve_context(); TL::ForStatement for_stmt(loop); TL::Symbol induction_var = for_stmt.get_induction_variable(); Nodecl::NodeclBase orig_loop_lower = for_stmt.get_lower_bound(); Nodecl::NodeclBase orig_loop_upper = for_stmt.get_upper_bound(); Nodecl::NodeclBase orig_loop_step = for_stmt.get_step(); // Do nothing if the loop is already a normalized loop if ( orig_loop_lower.is_constant() && const_value_is_zero(orig_loop_lower.get_constant()) && orig_loop_step.is_constant() && const_value_is_one(orig_loop_step.get_constant())) { _transformation = _loop.shallow_copy(); return; } // DO I = L, U, S // A(I) // becomes // DO I1 = 0, (U-L)/S, 1 // A(S * I1 + L) // Nodecl::NodeclBase new_upper; if (orig_loop_upper.is_constant() && orig_loop_lower.is_constant()) { new_upper = const_value_to_nodecl( const_value_sub( orig_loop_upper.get_constant(), orig_loop_lower.get_constant())); if (orig_loop_step.is_constant()) { new_upper = const_value_to_nodecl( const_value_div( new_upper.get_constant(), orig_loop_step.get_constant())); } else { new_upper = Nodecl::Div::make( new_upper, orig_loop_step.shallow_copy(), new_upper.get_type()); } } else { new_upper = Nodecl::Div::make( Nodecl::Minus::make( orig_loop_upper.shallow_copy(), orig_loop_lower.shallow_copy(), orig_loop_upper.get_type()), orig_loop_step.shallow_copy(), orig_loop_upper.get_type()); } Nodecl::NodeclBase normalized_loop_body = loop.get_statement().shallow_copy(); ReplaceInductionVar replace_induction_var(induction_var, orig_loop_lower, orig_loop_step); replace_induction_var.walk(normalized_loop_body); Nodecl::NodeclBase normalized_loop_control; if (IS_FORTRAN_LANGUAGE) { normalized_loop_control = Nodecl::RangeLoopControl::make( induction_var.make_nodecl(), const_value_to_nodecl(const_value_get_signed_int(0)), new_upper, const_value_to_nodecl(const_value_get_signed_int(1))); } else // IS_C_LANGUAGE || IS_CXX_LANGUAGE { Nodecl::NodeclBase init; // i = 0 if (for_stmt.induction_variable_in_separate_scope()) { induction_var.set_value(const_value_to_nodecl(const_value_get_signed_int(0))); init = Nodecl::ObjectInit::make(induction_var); } else { init = Nodecl::Assignment::make( induction_var.make_nodecl(/* ref */ true), const_value_to_nodecl(const_value_get_signed_int(0)), induction_var.get_type().no_ref().get_lvalue_reference_to()); } // i <= new_upper Nodecl::NodeclBase cond = Nodecl::LowerOrEqualThan::make( induction_var.make_nodecl(/* set_ref_type */ true), new_upper, ::get_bool_type()); // i = i + 1 Nodecl::NodeclBase next = Nodecl::Assignment::make( induction_var.make_nodecl(/* set_ref_type */ true), Nodecl::Add::make( induction_var.make_nodecl(/* set_ref_type */ true), const_value_to_nodecl(const_value_get_signed_int(1)), induction_var.get_type().no_ref()), induction_var.get_type().no_ref().get_lvalue_reference_to()); normalized_loop_control = Nodecl::LoopControl::make( Nodecl::List::make(init), cond, next); } Nodecl::NodeclBase normalized_for = Nodecl::ForStatement::make( normalized_loop_control, normalized_loop_body, /* loop-name */ Nodecl::NodeclBase::null()); _transformation = normalized_for; // Compute what value the induction variable should take after the loop if (!for_stmt.induction_variable_in_separate_scope()) { Nodecl::NodeclBase induction_variable = for_stmt.get_induction_variable().make_nodecl(/* set_ref_type */ true); Nodecl::NodeclBase expr = HLT::Utils::compute_induction_variable_final_expr(_loop); _post_transformation_stmts.append( Nodecl::ExpressionStatement::make( Nodecl::Assignment::make( induction_variable, expr, induction_variable.get_type()))); } }
void Core::collapse_loop_first(PragmaCustomConstruct& construct) { PragmaCustomClause collapse = construct.get_clause("collapse"); if (!collapse.is_defined()) return; ObjectList<Expression> expr_list = collapse.get_expression_list(); if (expr_list.size() != 1) { running_error("%s: error: 'collapse' clause must have one argument\n", construct.get_ast().get_locus().c_str()); } Expression &expr = expr_list.front(); if (!expr.is_constant()) { running_error("%s: error: 'collapse' clause argument '%s' is not a constant expression\n", expr.get_ast().get_locus().c_str(), expr.prettyprint().c_str()); } bool valid; int nest_level = expr.evaluate_constant_int_expression(valid); if (!valid) { running_error("%s: error: 'collapse' clause argument '%s' is not a constant expression\n", expr.get_ast().get_locus().c_str(), expr.prettyprint().c_str()); } if (nest_level <= 0) { running_error("%s: error: nesting level of 'collapse' clause must be a nonzero positive integer\n", expr.get_ast().get_locus().c_str()); } if (!ForStatement::predicate(construct.get_statement().get_ast())) { running_error("%s: error: collapsed '#pragma omp for' or '#pragma omp parallel for' require a for-statement\n", construct.get_statement().get_ast().get_locus().c_str()); } ForStatement for_stmt(construct.get_statement().get_ast(), construct.get_scope_link()); HLT::LoopCollapse loop_collapse(for_stmt); ObjectList<std::string> ancillary_names; Source header; loop_collapse .set_nesting_level(nest_level) .set_split_transform(header) .set_induction_private(true) .keep_ancillary_names(ancillary_names); Source collapsed_for = loop_collapse; Source transformed_code; AST_t pragma_placeholder; transformed_code << "{" << header << statement_placeholder(pragma_placeholder) << "}" ; AST_t tree = transformed_code.parse_statement(construct.get_ast(), construct.get_scope_link()); Source new_firstprivate_entities; Source pragma_line; Source omp_part_src; omp_part_src << "#pragma omp " << pragma_line << new_firstprivate_entities << "\n" << collapsed_for ; new_firstprivate_entities << "firstprivate(" << concat_strings(ancillary_names, ",") << ")"; pragma_line << construct.get_pragma_line().prettyprint_with_callback(functor(remove_collapse_clause)); AST_t omp_part_tree = omp_part_src.parse_statement(pragma_placeholder, construct.get_scope_link()); // Replace the pragma part pragma_placeholder.replace(omp_part_tree); // Replace the whole construct construct.get_ast().replace(tree); // Now overwrite the old construct with this new one construct = PragmaCustomConstruct(pragma_placeholder, construct.get_scope_link()); }