Beispiel #1
0
 static bool nodecl_is_one( const Nodecl::NodeclBase& n )
 {
     bool res = false;
     
     if( n.is<Nodecl::IntegerLiteral>( ) )
         res = const_value_is_one( n.as<Nodecl::IntegerLiteral>( ).get_constant( ) );
     else if( n.is<Nodecl::FloatingLiteral>( ) )
         res = const_value_is_one( n.as<Nodecl::FloatingLiteral>( ).get_constant( ) );
     
     return res;
 }
Beispiel #2
0
        void Core::collapse_check_loop(TL::PragmaCustomStatement construct)
        {
            TL::PragmaCustomClause collapse = construct.get_pragma_line().get_clause("collapse");
            if (!collapse.is_defined())
                return;

            TL::ObjectList<Nodecl::NodeclBase> expr_list = collapse.get_arguments_as_expressions(construct);

            if (expr_list.size() != 1)
            {
                error_printf("%s: error: collapse clause needs exactly one argument\n", 
                        locus_to_str(construct.get_locus()));
                return;
            }

            Nodecl::NodeclBase expr = expr_list[0];
            if (!expr.is_constant()
                    || !is_any_int_type(expr.get_type().get_internal_type()))
            {
                error_printf("%s: error: collapse clause requires an integer constant expression\n",
                        locus_to_str(construct.get_locus()));
                return;
            }

            const_value_t* cval = expr.get_constant();

            if (!const_value_is_one(cval))
            {
                error_printf("%s: error: only collapse(1) is supported\n",
                        locus_to_str(construct.get_locus()));
                return;
            }
        }
Beispiel #3
0
 bool InductionVariableData::is_increment_one( ) const
 {
     return ( _incr.is_constant( ) && ( const_value_is_one( _incr.get_constant( ) ) ) );
 }
    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())));
        }
    }