Beispiel #1
0
 void ClausesInfo::set_locus_info(AST_t directive)
 {
     _directive_clauses_map[directive].file = directive.get_file();
     std::stringstream line;
     line << directive.get_line();
     _directive_clauses_map[directive].line = line.str();
 }
    void InstrumentCalls::InstrumentCallsFunctor::postorder(Context ctx, AST_t node)
    {
        ScopeLink scope_link = ctx.scope_link;

        AST_t called_expression_tree = node.get_attribute(LANG_CALLED_EXPRESSION);
        AST_t arguments_tree = node.get_attribute(LANG_FUNCTION_ARGUMENTS);
        Expression called_expression(called_expression_tree, scope_link);

        // Only function-names are considered here
        if (!called_expression.is_id_expression())
        {
            // std::cerr << "Called expression is not an id expression" << std::endl;
            return;
        }

        IdExpression called_id_expression = called_expression.get_id_expression();

        if (!_instrument_filter.match(called_id_expression.prettyprint()))
            return;

        std::string shadow_function_name = 
            "_" + called_id_expression.mangle_id_expression() + "_instr";

        if (defined_shadows.find(shadow_function_name) == defined_shadows.end())
        {
            // The shadow has not been defined, define it here
            if (!define_shadow(called_id_expression, shadow_function_name))
            {
                // Ignore this shadow
                return;
            }
            defined_shadows.insert(shadow_function_name);
        }

        // Now replace the arguments
        Source replaced_arguments;

        replaced_arguments 
            << "\"" << node.get_file() << "\""
            << ","
            << node.get_line()
            ;

        if (arguments_tree.prettyprint() != "")
        {
            replaced_arguments << "," << arguments_tree.prettyprint(/*commas=*/true);
        }

        // Now create an expression tree
        Source shadow_function_call;
        shadow_function_call
            << shadow_function_name << "(" << replaced_arguments << ")"
            ;

        AST_t shadow_function_call_tree = 
            shadow_function_call.parse_expression(node, scope_link);

        node.replace(shadow_function_call_tree);
    }
/**
 *
 * @param function_def  function that contains function calls that will be inlined.
 *                      This means that this function will is actually the callsite
 *                      of the called functions, and that this is the place were
 *                      the code (from the inlined functions) will be written to
 * @param scope_link
 */
void InlinePhase::find_functions(FunctionDefinition function_def, ScopeLink scope_link) {
    FunctionCallsPred function_calls_pred(scope_link);
    Statement function_body = function_def.get_function_body();

    ObjectList<AST_t> list_of_calls = function_body.get_ast().depth_subtrees(function_calls_pred);

    for (ObjectList<AST_t>::iterator it = list_of_calls.begin(); it != list_of_calls.end(); it++, _callNum++) {
//        cout<<_callNum<<endl;
        AST_t element = *it;

        Expression expr(element, scope_link);

        // We already know it is a function call, no need to check again
        Expression _function_call = expr.get_called_expression();
        Expression last_function_call = _function_call;
        set_FCall(&_function_call);

//        cin.get();
        if (_function_call.is_id_expression()) {

            IdExpression id_expr = _function_call.get_id_expression();
            Symbol called_sym = id_expr.get_symbol();
            Symbol last_called_sym =  called_sym;
            set_FSym(&called_sym);
            if (called_sym.is_valid() && called_sym.is_function() && called_sym.is_defined()) {
//                cout << "\nFinding if necessary forward inline for function '" << id_expr << "' in " << element.get_locus() << "\n";
                _functionName = called_sym.get_name();
                _rowOfCall = element.get_line();
                int fnd = 0;
                for(int fN = 0; fN<_inlinedFunctions.size(); ++fN) {
                    if(_inlinedFunctions[fN].get_name().compare(std::string(_functionName))==0) {
                        fnd = 1;
                        break;
                    }
                }

                if(!fnd) {
                    _inlinedFunctions.push_back(called_sym);
//                    cout << "\nForward inline of "<<called_sym.get_name()<<" called on: "<<function_def.get_function_name().get_symbol().get_name()<<" \n";
                    ObjectList<AST_t> list_of_fun_defs = _translation_unit.depth_subtrees(_function_def_pred);
                    for (ObjectList<AST_t>::iterator it = list_of_fun_defs.begin(); it != list_of_fun_defs.end(); it++) {
                        FunctionDefinition function_defNF(*it, scope_link);
                        TL::Symbol function_sym = function_defNF.get_function_symbol();
                        if(function_sym.get_name().compare(called_sym.get_name())==0) {
                            find_functions(function_defNF,scope_link);
                            set_FCall(&last_function_call);
                            set_FSym(&last_called_sym);
                        }
                    }
                }
//                cout << "\nApplying inlining for function" << called_sym.get_name() << "\n {";
                inlineFunction(called_sym, expr);
//                cout<<"} \n";
            } else if(called_sym.is_defined()) {
                cerr << "************************************"<<
                     "\n You can not use "<<called_sym.get_name()<<"inside HMPP codelet.\n"
                     << "************************************";
                exit(-1);
            }
        }
    }
    if(list_of_calls.size()==0) {
        cout<<"No function calls in : "<<function_def.get_function_name().get_symbol().get_name()<<endl;
    } else {
        cout<<function_def.get_function_name().get_symbol().get_name()<< " finished -------------"<<endl;
    }
}