Beispiel #1
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 #2
0
    void loop_hlt_handler_post(TL::PragmaCustomStatement construct)
    {
        TL::PragmaCustomLine pragma_line = construct.get_pragma_line();
        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_at(construct.get_locus(), "'collapse' clause needs exactly one argument\n");
            return;
        }

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

        int collapse_factor = const_value_cast_to_signed_int(expr.get_constant());

        if (collapse_factor <= 0)
        {
            error_printf_at(
                    construct.get_locus(),
                    "Non-positive factor (%d) is not allowed in the 'collapse' clause\n",
                    collapse_factor);
        }
        else if (collapse_factor == 1)
        {
            // Removing the collapse clause from the pragma
            pragma_line.remove_clause("collapse");
        }
        else if (collapse_factor > 1)
        {
            Nodecl::NodeclBase loop = get_statement_from_pragma(construct);

            HLT::LoopCollapse loop_collapse;
            loop_collapse.set_loop(loop);
            loop_collapse.set_pragma_context(construct.retrieve_context());
            loop_collapse.set_collapse_factor(collapse_factor);

            loop_collapse.collapse();

            Nodecl::NodeclBase transformed_code = loop_collapse.get_whole_transformation();
            TL::ObjectList<TL::Symbol> capture_symbols = loop_collapse.get_omp_capture_symbols();

            // We may need to add some symbols that are used to implement the collapse clause to the pragma
            std::string names;
            for (TL::ObjectList<TL::Symbol>::iterator it = capture_symbols.begin();
                    it != capture_symbols.end();
                    it++)
            {
                if (it != capture_symbols.begin())
                    names += ",";
                names += it->get_name();
            }
            Nodecl::List clauses = pragma_line.get_clauses().as<Nodecl::List>();
            clauses.append(Nodecl::PragmaCustomClause::make(Nodecl::List::make(Nodecl::PragmaClauseArg::make(names)), "firstprivate"));

            // Removing the collapse clause from the pragma
            pragma_line.remove_clause("collapse");

            // Create a new pragma over the new for stmt
            ERROR_CONDITION(!transformed_code.is<Nodecl::Context>(), "Unexpected node\n", 0);
            Nodecl::NodeclBase compound_statement =
                transformed_code.as<Nodecl::Context>().get_in_context().as<Nodecl::List>().front();

            ERROR_CONDITION(!compound_statement.is<Nodecl::CompoundStatement>(), "Unexpected node\n", 0);
            Nodecl::Context context_for_stmt =
                compound_statement.as<Nodecl::CompoundStatement>().get_statements()
                .as<Nodecl::List>().find_first<Nodecl::Context>();

            Nodecl::Utils::remove_from_enclosing_list(context_for_stmt);

            Nodecl::List stmt_list =
                compound_statement.as<Nodecl::CompoundStatement>().get_statements().as<Nodecl::List>();
            ERROR_CONDITION(stmt_list.is_null(), "Unreachable code\n", 0);

            Nodecl::PragmaCustomStatement new_pragma =
                Nodecl::PragmaCustomStatement::make(pragma_line,
                        Nodecl::List::make(context_for_stmt),
                        construct.get_text(),
                        construct.get_locus());

            stmt_list.append(new_pragma);

            construct.replace(transformed_code);
        }
    }