示例#1
0
文件: codegen.c 项目: ras52/bootstrap
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;
    }
示例#3
0
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;
}
示例#4
0
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());
        }