Exemplo n.º 1
0
			virtual void run(DTO& data_flow)
			{
				_status = PHASE_STATUS_OK;
				
				try
				{
					PragmaCustomCompilerPhase::run(data_flow);
				}
				catch (FatalException ex)
				{
					_status = PHASE_STATUS_ERROR;
				}
				
				set_phase_status(_status);
			}
Exemplo n.º 2
0
        void OpenMPTransform::adf_task_postorder(PragmaCustomConstruct adf_construct)
        {
            PragmaCustomClause exit_condition_clause = adf_construct.get_clause("exit_condition");

            PragmaCustomClause trigger_set = adf_construct.get_clause("trigger_set");

            PragmaCustomClause group_name_clause = adf_construct.get_clause("name");

            bool group_name_given = group_name_clause.is_defined();
            std::string group_name = "default";
            if (group_name_given)
            {
                group_name = group_name_clause.get_expression_list()[0].prettyprint();
            }

            Source main_code_layout;

            AST_t inner_tree, exit_condition_placeholder, trigger_set_placeholder;

            main_code_layout
                << "{"
                <<    "Transaction * __t = createtx(\"" << adf_construct.get_ast().get_file() 
                <<             "\"," << adf_construct.get_ast().get_line() <<");"
                <<    "addTransactionToADFGroup(\"" << group_name << "\", __t);"
                <<    statement_placeholder(trigger_set_placeholder)
                <<    "while(1)"
                <<    "{"
                <<       "starttx(__t);"
                <<       "if (__t->status == 18 /*TS_ADF_FINISH*/) "
                <<       "  break; "
                <<       statement_placeholder(exit_condition_placeholder)
                <<       "if((__t->nestingLevel > 0) || (0 == setjmp(__t->context)))"
                <<       "{"
                <<          statement_placeholder(inner_tree)
                <<          "if (committx(__t) == 0)"
                <<          "{"
                <<             "retrytx(__t);"
                <<             "break;" 
                <<          "}"
                <<       "}"
                <<    "}"
                <<    "destroytx(__t);"
                << "}"
                ;

            AST_t code_layout_tree = main_code_layout.parse_statement(
                    adf_construct.get_ast(),
                    adf_construct.get_scope_link());

            // empty
            ObjectList<Symbol> unmanaged_symbols;
            ObjectList<Symbol> local_symbols;

            // XXX - Currently using /dev/null as the filter and log files
            std::fstream stm_log_file;
            stm_log_file.open("/dev/null", std::ios_base::out | std::ios_base::trunc);

            STMExpressionReplacement expression_replacement(unmanaged_symbols, local_symbols,
                    "/dev/null", "normal",
                    "/dev/null", "normal",
                    stm_log_file);

            // STMize exit condition
            if (exit_condition_clause.is_defined())
            {
                Expression exit_condition = exit_condition_clause.get_expression_list()[0];
                // Duplicate but by means of parsing (this updates the semantic information)
                Source src = exit_condition.prettyprint();
                AST_t tree = src.parse_expression(inner_tree, adf_construct.get_scope_link());
                Expression expr(tree, adf_construct.get_scope_link());
                expression_replacement.replace_expression(expr);

                Source exit_condition_src;

                exit_condition_src
                    << "if (" << expr.prettyprint() << ")"
                    <<    "break;"
                    ;

                AST_t exit_condition_tree = exit_condition_src.parse_statement(exit_condition_placeholder,
                        adf_construct.get_scope_link());

                exit_condition_placeholder.replace(exit_condition_tree);
            }

            // Main code
            {
                // Duplicate with new contextual info
                Source src = adf_construct.get_statement().prettyprint();
                AST_t task_tree = src.parse_statement(inner_tree,
                        adf_construct.get_scope_link());

                ObjectList<AST_t> expressions = task_tree.depth_subtrees(Expression::predicate, AST_t::NON_RECURSIVE);
                for (ObjectList<AST_t>::iterator it = expressions.begin();
                        it != expressions.end();
                        it++)
                {
                    Expression expression(*it, scope_link);
                    expression_replacement.replace_expression(expression);
                }

                inner_tree.replace(task_tree);
            }

            // Trigger set registration due to 'exit_condition'
            Source trigger_set_registration;
            bool have_some_trigger_set = false;
            if (exit_condition_clause.is_defined())
            {
                ObjectList<IdExpression> id_expression_list = exit_condition_clause.id_expressions();

                for (ObjectList<IdExpression>::iterator it = id_expression_list.begin();
                        it != id_expression_list.end();
                        it++)
                {
                    Symbol sym = it->get_symbol();
                    Type type = sym.get_type();

                    if (!type.is_array())
                    {
                        trigger_set_registration
                            << "add_scalar_to_trigger_set(__t, "
                            <<    "&" << it->prettyprint() << ", "
                            <<    "sizeof(" << it->prettyprint() << ")"
                            << ");"
                            ;
                    }
                    else
                    {
                        std::cerr 
                            << it->get_ast().get_locus() << ": error: exit condition expression '" 
                            << it->prettyprint()
                            << "' involves an array. This is not yet supported" 
                            << std::endl;
                    }
                    have_some_trigger_set = true;
                }

                // Trigger set registration due to 'trigger_set'
                if (trigger_set.is_defined())
                {
                    ObjectList<Expression> trigger_set_expr = trigger_set.get_expression_list();

                    for (ObjectList<Expression>::iterator it = trigger_set_expr.begin();
                            it != trigger_set_expr.end();
                            it++)
                    {
                        Expression &trigger_expr(*it);

                        // This should be improved to handle cases like 'a[2]'
                        if (trigger_expr.is_id_expression())
                        {
                            trigger_set_registration
                                << "add_scalar_to_trigger_set(__t, "
                                <<    "&" << trigger_expr.prettyprint() << ", "
                                <<    "sizeof(" << trigger_expr.prettyprint() << ")"
                                << ");"
                                ;
                        }
                        else if (trigger_expr.is_array_section_range())
                        {
                            ObjectList<Expression> lower_bounds;
                            ObjectList<Expression> upper_bounds;

                            Expression basic_expr = compute_bounds_of_sectioned_expression(trigger_expr, lower_bounds, upper_bounds);

                            // FIXME - Do not be so restrictive, pointers to arrays are useful as well :)
                            if (!basic_expr.is_id_expression())
                            {
                                std::cerr << basic_expr.get_ast().get_locus() 
                                    << ": error: invalid trigger set specification '" << trigger_expr.prettyprint()
                                    << "' since the basic expression '" << basic_expr.prettyprint() << "' is not an id-expression" 
                                    << std::endl;
                                set_phase_status(PHASE_STATUS_ERROR);
                                return;
                            }

                            IdExpression id_expression = basic_expr.get_id_expression();
                            Symbol sym = id_expression.get_symbol();
                            if (!sym.is_valid())
                            {
                                std::cerr << id_expression.get_ast().get_locus() 
                                    << ": error: unknown entity '" << id_expression.prettyprint() << "'" << std::endl;
                                set_phase_status(PHASE_STATUS_ERROR);
                                return;
                            }

                            Type type = sym.get_type();
                            ObjectList<AST_t> array_dimensions = compute_array_dimensions_of_type(type);

                            if (array_dimensions.size() != lower_bounds.size()
                                    || lower_bounds.size() != upper_bounds.size())
                            {
                                std::cerr << id_expression.get_ast().get_locus() 
                                    << ": error: mismatch between array type and array section" << std::endl;
                                set_phase_status(PHASE_STATUS_ERROR);
                                return;
                            }

                            trigger_set_registration
                                << "add_range_to_trigger_set(__t, " << basic_expr.prettyprint() << "," 
                                <<     array_dimensions.size() << ","
                                <<     "sizeof(" << get_basic_type(type).get_declaration(sym.get_scope(), "") << ")"
                                ;

                            // First add dimensions 
                            for (ObjectList<AST_t>::iterator it = array_dimensions.begin();
                                    it != array_dimensions.end();
                                    it++)
                            {
                                trigger_set_registration << "," << it->prettyprint();
                            }

                            // Now lower and upper bounds
                            {
                                ObjectList<Expression>::iterator it_l = lower_bounds.begin();
                                ObjectList<Expression>::iterator it_u = upper_bounds.begin();

                                while (it_l != lower_bounds.end())
                                {
                                    trigger_set_registration << "," << it_l->prettyprint();
                                    trigger_set_registration << "," << it_u->prettyprint();

                                    it_u++;
                                    it_l++;
                                }

                            }

                            // Final parenthesis and semicolon
                            trigger_set_registration
                                << ");"
                                ;
                        }

                        have_some_trigger_set = true;
                    }
                }


            }

            if (have_some_trigger_set)
            {
                AST_t trigger_registration_tree = trigger_set_registration.parse_statement(trigger_set_placeholder,
                        adf_construct.get_scope_link());
                trigger_set_placeholder.replace(trigger_registration_tree);
            }

            // Replace it all
            adf_construct.get_ast().replace(code_layout_tree);
        }