예제 #1
0
void postProcessingSupport (SgNode* node)
{
    // DQ (5/24/2006): Added this test to figue out where Symbol parent pointers are being reset to NULL
    // TestParentPointersOfSymbols::test();

    // DQ (7/25/2005): It is presently an error to call this function with a SgProject
    // or SgDirectory, since there is no way to compute the SgFile from such IR nodes
    // (could be multiply defined).
    // ROSE_ASSERT(isSgProject(node) == NULL && isSgDirectory(node) == NULL);
    // GB (8/19/2009): Removed the assertion against calling this function on
    // SgProject and SgDirectory nodes. Nothing below needs to compute a
    // SgFile, as far as I can tell; also, calling the AstPostProcessing just
    // once on an entire project is more efficient than calling it once per
    // file.

    // JJW (12/5/2008): Turn off C and C++ postprocessing steps when the new EDG
    // interface is being used (it should produce correct, complete ASTs on its
    // own and do its own fixups)
#ifdef ROSE_USE_NEW_EDG_INTERFACE

    // Only do AST post-processing for C/C++
    bool doPostprocessing = (SageInterface::is_Fortran_language() == true) ||
                            (SageInterface::is_PHP_language() == true) ||
                            (SageInterface::is_Python_language() == true);

    // If this is C or C++ then we are using the new EDG translation and althrough fewer
    // fixups should be required, some are still required.
    if (doPostprocessing == false)
    {
#ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION
        printf ("Postprocessing AST build using new EDG/Sage Translation Interface. \n");
#endif
#if 0
        // DQ (4/26/2013): Debugging code.
        printf ("In postProcessingSupport: Test 1: Calling postProcessingTestFunctionCallArguments() \n");
        postProcessingTestFunctionCallArguments(node);
#endif
#ifndef ROSE_USE_CLANG_FRONTEND
        // DQ (10/31/2012): Added fixup for EDG bug which drops variable declarations of some source sequence lists.
        fixupEdgBugDuplicateVariablesInAST();
#endif

        // DQ (5/1/2012): After EDG/ROSE translation, there should be no IR nodes marked as transformations.
        // Liao 11/21/2012. AstPostProcessing() is called within both Frontend and Midend
        // so we have to detect the mode first before asserting no transformation generated file info objects
        if (SageBuilder::SourcePositionClassificationMode != SageBuilder::e_sourcePositionTransformation)
            detectTransformations(node);

        // DQ (8/12/2012): reset all of the type references (to intermediately generated types).
        fixupTypeReferences();

        // Reset and test and parent pointers so that it matches our definition
        // of the AST (as defined by the AST traversal mechanism).
        topLevelResetParentPointer(node);

        // DQ (8/23/2012): Modified to take a SgNode so that we could compute the global scope for use in setting
        // parents of template instantiations that have not be placed into the AST but exist in the memory pool.
        // Another 2nd step to make sure that parents of even IR nodes not traversed can be set properly.
        // resetParentPointersInMemoryPool();
        resetParentPointersInMemoryPool(node);

        // DQ (6/27/2005): fixup the defining and non-defining declarations referenced at each SgDeclarationStatement
        // This is a more sophisticated fixup than that done by fixupDeclarations. See test2009_09.C for an example
        // of a non-defining declaration appearing before a defining declaration and requiring a fixup of the
        // non-defining declaration reference to the defining declaration.
        fixupAstDefiningAndNondefiningDeclarations(node);

        // DQ (6/11/2013): This corrects where EDG can set the scope of a friend declaration to be different from the defining declaration.
        // We need it to be a rule in ROSE that the scope of the declarations are consistant between defining and all non-defining declaration).
        fixupAstDeclarationScope(node);

        // Fixup the symbol tables (in each scope) and the global function type
        // symbol table. This is less important for C, but required for C++.
        // But since the new EDG interface has to handle C and C++ we don't
        // setup the global function type table there to be uniform.
        fixupAstSymbolTables(node);

        // DQ (4/14/2010): Added support for symbol aliases for C++
        // This is the support for C++ "using declarations" which uses symbol aliases in the symbol table to provide
        // correct visability of symbols included from alternative scopes (e.g. namespaces).
        fixupAstSymbolTablesToSupportAliasedSymbols(node);

        // DQ (2/12/2012): Added support for this, since AST_consistancy expects get_nameResetFromMangledForm() == true.
        resetTemplateNames(node);

        // **********************************************************************
        // DQ (4/29/2012): Added some of the template fixup support for EDG 4.3 work.
        // DQ (6/21/2005): This function now only marks the subtrees of all appropriate declarations as compiler generated.
        // DQ (5/27/2005): mark all template instantiations (which we generate as template specializations) as compiler generated.
        // This is required to make them pass the unparser and the phase where comments are attached.  Some fixup of filenames
        // and line numbers might also be required.
        fixupTemplateInstantiations(node);

#if 0
        // DQ (4/26/2013): Debugging code.
        printf ("In postProcessingSupport: Test 2: Calling postProcessingTestFunctionCallArguments() \n");
        postProcessingTestFunctionCallArguments(node);
#endif

        // DQ (8/19/2005): Mark any template specialization (C++ specializations are template instantiations
        // that are explicit in the source code).  Such template specializations are marked for output only
        // if they are present in the source file.  This detail could effect handling of header files later on.
        // Have this phase preceed the markTemplateInstantiationsForOutput() since all specializations should
        // be searched for uses of (references to) instantiated template functions and member functions.
        markTemplateSpecializationsForOutput(node);

        // DQ (6/21/2005): This function marks template declarations for output by the unparser (it is part of a
        // fixed point iteration over the AST to force find all templates that are required (EDG at the moment
        // outputs only though template functions that are required, but this function solves the more general
        // problem of instantiation of both function and member function templates (and static data, later)).
        markTemplateInstantiationsForOutput(node);

        // DQ (10/21/2007): Friend template functions were previously not properly marked which caused their generated template
        // symbols to be added to the wrong symbol tables.  This is a cause of numerous symbol table problems.
        fixupFriendTemplateDeclarations();
        // DQ (4/29/2012): End of new template fixup support for EDG 4.3 work.
        // **********************************************************************

        // DQ (5/14/2012): Fixup source code position information for the end of functions to match the largest values in their subtree.
        // DQ (10/27/2007): Setup any endOfConstruct Sg_File_Info objects (report on where they occur)
        fixupSourcePositionConstructs();

#if 0
        // DQ (4/26/2013): Debugging code.
        printf ("In postProcessingSupport: Test 3: Calling postProcessingTestFunctionCallArguments() \n");
        postProcessingTestFunctionCallArguments(node);
#endif

        // DQ (2/12/2012): This is a problem for test2004_35.C (debugging this issue).
        // printf ("Exiting after calling resetTemplateNames() \n");
        // ROSE_ASSERT(false);

        // DQ (10/4/2012): Added this pass to support command line option to control use of constant folding
        // (fixes bug pointed out by Liao).
        // DQ (9/14/2011): Process the AST to remove constant folded values held in the expression trees.
        // This step defines a consistent AST more suitable for analysis since only the constant folded
        // values will be visited.  However, the default should be to save the original expression trees
        // and remove the constant folded values since this represents the original code.
#if 1
        resetConstantFoldedValues(node);
#else
        // DQ (10/11/2012): This is helpful to allow us to see both expression trees in the AST for debugging.
        printf ("Skipping AST Postprocessing resetConstantFoldedValues() \n");
#endif

#if 0
        // DQ (4/26/2013): Debugging code.
        printf ("In postProcessingSupport: Test 4: Calling postProcessingTestFunctionCallArguments() \n");
        postProcessingTestFunctionCallArguments(node);
#endif

        // DQ (10/5/2012): Fixup known macros that might expand into a recursive mess in the unparsed code.
        fixupSelfReferentialMacrosInAST(node);

        // Make sure that frontend-specific and compiler-generated AST nodes are marked as such. These two must run in this
        // order since checkIsCompilerGenerated depends on correct values of compiler-generated flags.
        checkIsFrontendSpecificFlag(node);
        checkIsCompilerGeneratedFlag(node);

        // This resets the isModified flag on each IR node so that we can record
        // where transformations are done in the AST.  If any transformations on
        // the AST are done, even just building it, this step should be the final
        // step.
        checkIsModifiedFlag(node);

        // DQ (5/2/2012): After EDG/ROSE translation, there should be no IR nodes marked as transformations.
        // Liao 11/21/2012. AstPostProcessing() is called within both Frontend and Midend
        // so we have to detect the mode first before asserting no transformation generated file info objects
        if (SageBuilder::SourcePositionClassificationMode !=SageBuilder::e_sourcePositionTransformation)
            detectTransformations(node);

#if 0
        // DQ (4/26/2013): Debugging code.
        printf ("In postProcessingSupport: Test 10: Calling postProcessingTestFunctionCallArguments() \n");
        postProcessingTestFunctionCallArguments(node);
#endif

        // DQ (4/24/2013): Detect the correct function declaration to declare the use of default arguments.
        // This can only be a single function and it can't be any function (this is a moderately complex issue).
        fixupFunctionDefaultArguments(node);

        // DQ (12/20/2012): We now store the logical and physical source position information.
        // Although they are frequently the same, the use of #line directives causes them to be different.
        // This is part of debugging the physical source position information which is used in the weaving
        // of the comments and CPP directives into the AST.  For this the consistancy check is more helpful
        // if done befor it is used (here), instead of after the comment and CPP directive insertion in the
        // AST Consistancy tests.
        checkPhysicalSourcePosition(node);

#ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION
        printf ("DONE: Postprocessing AST build using new EDG/Sage Translation Interface. \n");
#endif
        return;
    }
#endif // ROSE_USE_NEW_EDG_INTERFACE -- do postprocessing unconditionally when the old EDG interface is used

    // DQ (7/7/2005): Introduce tracking of performance of ROSE.
    // TimingPerformance timer ("AST Fixup: time (sec) = ");

    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing started. */" << endl;

    ROSE_ASSERT(node != NULL);

    // DQ (7/19/2005): Moved to after parent pointer fixup!
    // subTemporaryAstFixes(node);

    // DQ (3/11/2006): Fixup NULL pointers left by users when building the AST
    // (note that the AST translation fixes these directly).  This step is
    // provided as a way to make the AST build by users consistant with what
    // is built elsewhere within ROSE.
    fixupNullPointersInAST(node);

    // DQ (8/9/2005): Some function definitions in Boost are build without
    // a body (example in test2005_102.C, but it appears to work fine).
    fixupFunctionDefinitions(node);

    // DQ (8/10/2005): correct any template declarations mistakenly marked as compiler-generated
    fixupTemplateDeclarations(node);

    // Output progress comments for these relatively expensive operations on the AST
    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing reset parent pointers */" << endl;

    topLevelResetParentPointer (node);

    // DQ (6/10/2007): This is called later, but call it now to reset the parents in SgTemplateInstantiationDecl
    // This is required (I think) so that resetTemplateNames() can compute template argument name qualification correctly.
    // See test2005_28.C for where this is required.
    // resetParentPointersInMemoryPool();
    resetParentPointersInMemoryPool(node);

    // Output progress comments for these relatively expensive operations on the AST
    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing reset parent pointers (done) */" << endl;

    // DQ (7/19/2005): Moved to after parent pointer fixup!
    // subTemporaryAstFixes(node);
    removeInitializedNamePtr(node);

    // DQ (3/17/2007): This should be empty
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (12/1/2004): This should be done before the reset of template names (since that operation requires valid scopes!)
    // DQ (11/29/2004): Added to support new explicit scope information on IR nodes
    // initializeExplicitScopeData(node);
    initializeExplicitScopes(node);

    // DQ (5/28/2006): Fixup names in declarations that are inconsistent (e.g. where more than one non-defining declaration exists)
    resetNamesInAST();

    // DQ (3/17/2007): This should be empty
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // Output progress comments for these relatively expensive operations on the AST
    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing reset template names */" << endl;

#if 0
    // DQ (5/15/2011): I don't feel comfortable with this being called before the AST is finied being post processed.
    // This used to be called in the unparser, but that is after resetTemplateNames() below and that is a problem
    // because template names have already been generated.
    void newBuildHiddenTypeAndDeclarationLists( SgNode* node );
    printf ("Developing a new implementation of the name qualification support. \n");
    newBuildHiddenTypeAndDeclarationLists(node);
    printf ("DONE: new name qualification support built. \n");

    printf ("Calling SgNode::clearGlobalMangledNameMap() \n");
    SgNode::clearGlobalMangledNameMap();
#endif

    // DQ (5/15/2011): This causes template names to be computed as strings and and without name qualification
    // if we don't call the name qualification before here. Or we reset the template names after we do the
    // analysis to support the name qualification.
    // reset the names of template class declarations
    resetTemplateNames(node);

    // DQ (2/12/2012): This is a problem for test2004_35.C (debugging this issue).
    // printf ("Exiting after calling resetTemplateNames() \n");
    // ROSE_ASSERT(false);

    // DQ (3/17/2007): This should be empty
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // Output progress comments for these relatively expensive operations on the AST
    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing reset template names (done) */" << endl;

    // DQ (6/26/2007): Enum values used before they are defined in a class can have NULL declaration pointers.  This
    // fixup handles this case and traverses just the SgEnumVal objects.
    fixupEnumValues();

    // DQ (4/7/2010): This was commented out to modify Fortran code, but I think it should NOT modify Fortran code.
    // DQ (5/21/2008): This only make since for C and C++ (Error, this DOES apply to Fortran where the "parameter" attribute is used!)
    if (SageInterface::is_Fortran_language() == false && SageInterface::is_Java_language() == false)
    {
        // DQ (3/20/2005): Fixup AST so that GNU g++ compile-able code will be generated
        fixupInClassDataInitialization(node);
    }

    // DQ (3/24/2005): Fixup AST to generate code that works around GNU g++ bugs
    fixupforGnuBackendCompiler(node);

    // DQ (4/19/2005): fixup all definingDeclaration and NondefiningDeclaration pointers in SgDeclarationStatement IR nodes
    // fixupDeclarations(node);

    // DQ (5/20/2005): make the non-defining (forward) declarations added by EDG for static template
    // specializations added under the "--instantiation local" option match the defining declarations.
    fixupStorageAccessOfForwardTemplateDeclarations(node);

#if 0
    // DQ (6/27/2005): fixup the defining and non-defining declarations referenced at each SgDeclarationStatement
    fixupAstDefiningAndNondefiningDeclarations(node);
#endif

    // DQ (6/21/2005): This function now only marks the subtrees of all appropriate declarations as compiler generated.
    // DQ (5/27/2005): mark all template instantiations (which we generate as template specializations) as compiler generated.
    // This is required to make them pass the unparser and the phase where comments are attached.  Some fixup of filenames
    // and line numbers might also be required.
    fixupTemplateInstantiations(node);

    // DQ (8/19/2005): Mark any template specialization (C++ specializations are template instantiations
    // that are explicit in the source code).  Such template specializations are marked for output only
    // if they are present in the source file.  This detail could effect handling of header files later on.
    // Have this phase preceed the markTemplateInstantiationsForOutput() since all specializations should
    // be searched for uses of (references to) instantiated template functions and member functions.
    markTemplateSpecializationsForOutput(node);

    // DQ (6/21/2005): This function marks template declarations for output by the unparser (it is part of a
    // fixed point iteration over the AST to force find all templates that are required (EDG at the moment
    // outputs only though template functions that are required, but this function solves the more general
    // problem of instantiation of both function and member function templates (and static data, later)).
    markTemplateInstantiationsForOutput(node);

    // DQ (3/17/2007): This should be empty
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (3/16/2006): fixup any newly added declarations (see if we can eliminate the first place where this is called, above)
    // fixup all definingDeclaration and NondefiningDeclaration pointers in SgDeclarationStatement IR nodes
    // driscoll6 (6/10/11): this traversal sets p_firstNondefiningDeclaration for defining declarations, which
    // causes justifiable failures in AstConsistencyTests. Until this is resolved, skip this test for Python.
    if (SageInterface::is_Python_language()) {
        //cerr << "warning: python. Skipping fixupDeclarations() in astPostProcessing.C" << endl;
    } else {
        fixupDeclarations(node);
    }

    // DQ (3/17/2007): This should be empty
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (2/12/2006): Moved to trail marking templates (as a test)
    // DQ (6/27/2005): fixup the defining and non-defining declarations referenced at each SgDeclarationStatement
    // This is a more sophisticated fixup than that done by fixupDeclarations.
    fixupAstDefiningAndNondefiningDeclarations(node);

#if 0
    ROSE_ASSERT(saved_declaration != NULL);
    printf ("saved_declaration = %p saved_declaration->get_definingDeclaration() = %p saved_declaration->get_firstNondefiningDeclaration() = %p \n",
            saved_declaration,saved_declaration->get_definingDeclaration(),saved_declaration->get_firstNondefiningDeclaration());
    ROSE_ASSERT(saved_declaration->get_definingDeclaration() != saved_declaration->get_firstNondefiningDeclaration());
#endif

    // DQ (10/21/2007): Friend template functions were previously not properly marked which caused their generated template
    // symbols to be added to the wrong symbol tables.  This is a cause of numerous symbol table problems.
    fixupFriendTemplateDeclarations();

    // DQ (3/17/2007): This should be the last point at which the globalMangledNameMap is empty
    // The fixupAstSymbolTables will generate calls to function types that will be placed into
    // the globalMangledNameMap.
    ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (6/26/2005): The global function type symbol table should be rebuilt (since the names of templates
    // used in qualified names of types have been reset (in post processing).  Other local symbol tables should
    // be initalized and constructed for any empty scopes (for consistancy, we want all scopes to have a valid
    // symbol table pointer).
    fixupAstSymbolTables(node);

    // DQ (3/17/2007): At this point the globalMangledNameMap has been used in the symbol table construction. OK.
    // ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (8/20/2005): Handle backend vendor specific template handling options
    // (e.g. g++ options: -fno-implicit-templates and -fno-implicit-inline-templates)
    processTemplateHandlingOptions(node);

    // DQ (5/22/2005): relocate compiler generated forward template instantiation declarations to appear
    // after the template declarations and before first use.
    // relocateCompilerGeneratedTemplateInstantiationDeclarationsInAST(node);

    // DQ (8/27/2005): This disables output of some template instantiations that would result in
    // "ambiguous template specialization" in g++ (version 3.3.x, 3.4.x, and 4.x).  See test2005_150.C
    // for more detail.
    markOverloadedTemplateInstantiations(node);

    // DQ (9/5/2005): Need to mark all nodes in any subtree marked as a transformation
    markTransformationsForOutput(node);

    // DQ (3/5/2006): Mark functions that are provided for backend compatability as compiler generated by ROSE
#if 1
    markBackendSpecificFunctionsAsCompilerGenerated(node);
#else
    printf ("Warning: Skipped marking of backend specific functions ... \n");
#endif

    // DQ (5/24/2006): Added this test to figure out where Symbol parent pointers are being reset to NULL
    // TestParentPointersOfSymbols::test();

    // DQ (5/24/2006): reset the remaining parents in IR nodes missed by the AST based traversals
    // resetParentPointersInMemoryPool();
    resetParentPointersInMemoryPool(node);

    // DQ (3/17/2007): This should be empty
    // ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (5/29/2006): Fixup types in declarations that are not shared (e.g. where more than one non-defining declaration exists)
    resetTypesInAST();

    // DQ (3/17/2007): This should be empty
    // ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // DQ (3/10/2007): fixup name of any template classes that have been copied incorrectly into SgInitializedName
    // list in base class constructor preinitialization lists (see test2004_156.C for an example).
    resetContructorInitilizerLists();

    // DQ (10/27/2007): Setup any endOfConstruct Sg_File_Info objects (report on where they occur)
    fixupSourcePositionConstructs();

    // DQ (1/19/2008): This can be called at nearly any point in the ast fixup.
    markLhsValues(node);

#ifndef ROSE_USE_CLANG_FRONTEND
    // DQ (2/21/2010): This normalizes an EDG trick (well documented) that replaces "__PRETTY_FUNCTION__" variable
    // references with variable given the name of the function where the "__PRETTY_FUNCTION__" variable references
    // was found. This is only seen when compiling ROSE using ROSE and was a mysterious property of ROSE for a long
    // time until it was identified.  This fixup traversal changes the name back to "__PRETTY_FUNCTION__" to make
    // the code generated using ROSE when compiling ROSE source code the same as if GNU processed it (e.g. using CPP).
    if (SageInterface::is_Java_language() == false) {
        fixupPrettyFunctionVariables(node);
    }
#endif

#if 0
    // DQ (1/22/2008): Use this for the Fortran code to get more accurate source position information.

    // DQ (4/16/2007): comment out to test how function declaration prototypes are reset or set wrong.
    // DQ (11/1/2006): fixup source code position information for AST IR nodes.
    fixupSourcePositionInformation(node);
#endif

#if 0
    // DQ (11/10/2007): Moved computation of hidden list from astPostProcessing.C to unparseFile so that
    // it will be called AFTER any transformations and immediately before code generation where it is
    // really required.  This part of a fix for Liao's outliner, but should be useful for numerous
    // transformations.
    // DQ (8/6/2007): Only compute the hidden lists if working with C++ code!
    if (SageInterface::is_Cxx_language() == true)
    {
        // DQ (5/22/2007): Moved from SgProject::parse() function to here so that propagateHiddenListData() could be called afterward.
        // DQ (5/8/2007): Now build the hidden lists for types and declarations (Robert Preissl's work)
        Hidden_List_Computation::buildHiddenTypeAndDeclarationLists(node);

        // DQ (6/5/2007): We actually need this now since the hidden lists are not pushed to lower scopes where they are required.
        // DQ (5/22/2007): Added support for passing hidden list information about types, declarations and elaborated types to child scopes.
        propagateHiddenListData(node);
    }
#endif

    // DQ (11/24/2007): Support for Fortran resolution of array vs. function references.
    if (SageInterface::is_Fortran_language() == true)
    {
        // I think this is not used since I can always figure out if something is an
        // array reference or a function call.
        fixupFortranReferences(node);

        // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required.
        // This is the most reliable way to introduce the Fortran "contains" statement.
        // insertFortranContainsStatement(node);
    }

    // DQ (9/26/2008): fixup the handling of use declarations (SgUseStatement).
    // This also will fixup C++ using declarations.
    fixupFortranUseDeclarations(node);

#if 0
    ROSE_MemoryUsage memoryUsage1;
    printf ("Test 1: memory_usage = %f \n",memoryUsage1.getMemoryUsageMegabytes());
#endif

    // DQ (4/14/2010): Added support for symbol aliases for C++
    // This is the support for C++ "using declarations" which uses symbol aliases in the symbol table to provide
    // correct visability of symbols included from alternative scopes (e.g. namespaces).
    fixupAstSymbolTablesToSupportAliasedSymbols(node);

#if 0
    ROSE_MemoryUsage memoryUsage2;
    printf ("Test 2: memory_usage = %f \n",memoryUsage2.getMemoryUsageMegabytes());
#endif

    // DQ (6/24/2010): To support merge, we want to normalize the typedef lists for each type so that
    // the names of the types will evaluate to be the same (and merge appropriately).
    normalizeTypedefSequenceLists();

#if 0
    ROSE_MemoryUsage memoryUsage3;
    printf ("Test 3: memory_usage = %f \n",memoryUsage3.getMemoryUsageMegabytes());
#endif

    // DQ (3/7/2010): Identify the fragments of the AST that are disconnected.
    // Moved from astConsistancy tests (since it deletes nodes not connected to the AST).
    // TestForDisconnectedAST::test(node);

    // DQ (9/14/2011): Process the AST to remove constant folded values held in the expression trees.
    // This step defines a consistant AST more suitable for analysis since only the constant folded
    // values will be visited.  However, the default should be to save the original expression trees
    // and remove the constant folded values since this represents the original code.  This mechanism
    // will provide a default when it is more fully implemented.
    resetConstantFoldedValues(node);

    // Make sure that compiler-generated AST nodes are marked for Sg_File_Info::isCompilerGenerated().
    checkIsCompilerGeneratedFlag(node);

    // DQ (5/22/2005): Nearly all AST fixup should be done before this closing step
    // QY: check the isModified flag
    // CheckIsModifiedFlagSupport(node);
    checkIsModifiedFlag(node);

#if 0
    ROSE_MemoryUsage memoryUsage4;
    printf ("Test 4: memory_usage = %f \n",memoryUsage4.getMemoryUsageMegabytes());
#endif

    // ROSE_ASSERT(saved_declaration->get_definingDeclaration() != saved_declaration->get_firstNondefiningDeclaration());

    // DQ (3/17/2007): This should be empty
    // ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0);

    // This is used for both of the fillowing tests.
    SgSourceFile* sourceFile = isSgSourceFile(node);

#if 1
    // DQ (9/11/2009): Added support for numbering of statements required to support name qualification.
    if (sourceFile != NULL)
    {
        // DQ (9/11/2009): Added support for numbering of statements required to support name qualification.
        // sourceFile->buildStatementNumbering();
        SgGlobal* globalScope = sourceFile->get_globalScope();
        ROSE_ASSERT(globalScope != NULL);
        globalScope->buildStatementNumbering();
    }
    else
    {
        if (SgProject* project = isSgProject(node))
        {
            SgFilePtrList &files = project->get_fileList();
            for (SgFilePtrList::iterator fileI = files.begin(); fileI != files.end(); ++fileI)
            {
                if ( (sourceFile = isSgSourceFile(*fileI)) )
                {
                    SgGlobal* globalScope = sourceFile->get_globalScope();
                    ROSE_ASSERT(globalScope != NULL);
                    globalScope->buildStatementNumbering();
                }
            }
        }
    }
#endif

    // DQ (4/4/2010): check that the global scope has statements.
    // This was an error for Fortran and it appeared that everything
    // was working when it was not.  It appeared because of a strange
    // error between versions of the OFP support files.  So as a
    // way to avoid this in the future, we issue a warning for Fortran
    // code that has no statements in the global scope.  It can still
    // be a valid Fortran code (containing only comments).  but this
    // should help avoid our test codes appearing to work when they
    // don't (in the future). For C/C++ files there should always be
    // something in the global scope (because or ROSE defined functions),
    // so this test should not be a problem.
    if (sourceFile != NULL)
    {
        SgGlobal* globalScope = sourceFile->get_globalScope();
        ROSE_ASSERT(globalScope != NULL);
        if (globalScope->get_declarations().empty() == true)
        {
            printf ("WARNING: no statements in global scope for file = %s \n",sourceFile->getFileName().c_str());
        }
    }
    else
    {
        if (SgProject* project = isSgProject(node))
        {
            SgFilePtrList &files = project->get_fileList();
            for (SgFilePtrList::iterator fileI = files.begin(); fileI != files.end(); ++fileI)
            {
                if ( (sourceFile = isSgSourceFile(*fileI)) )
                {
                    SgGlobal* globalScope = sourceFile->get_globalScope();
                    ROSE_ASSERT(globalScope != NULL);
                    if (globalScope->get_declarations().empty() == true)
                    {
                        printf ("WARNING: no statements in global scope for file = %s \n",(*fileI)->getFileName().c_str());
                    }
                }
            }
        }
    }

    if ( SgProject::get_verbose() >= AST_POST_PROCESSING_VERBOSE_LEVEL )
        cout << "/* AST Postprocessing finished */" << endl;



    // DQ (5/3/2010): Added support for binary analysis specific post-processing.
    SgProject* project = isSgProject(node);
    if (project != NULL)
    {
#if 0
        // printf ("In postProcessingSupport(): project->get_exit_after_parser() = %s \n",project->get_exit_after_parser() ? "true" : "false");
        // printf ("In postProcessingSupport(): project->get_binary_only()       = %s \n",project->get_binary_only() ? "true" : "false");
        if (project->get_binary_only() == true)
        {
            printf ("Inside of postProcessingSupport(): Processing binary project \n");
            // ROSE_ASSERT(false);

            // addEdgesInAST();
        }
#endif
    }

}
예제 #2
0
int main( int argc, char *argv[] )
{
	if( argc < 2 ) {
		cout << "./amos: no input files                               " << endl;
		cout << "                                                     " << endl;
		cout << "Hi, this is Amos!                                    " << endl;
		cout << "It's my pleasure to serve you.                       " << endl;
		cout << "                                                     " << endl;
		cout << "Please type option '--help' to see guide             " << endl;
		cout << "                                                     " << endl;

		return 0;
	}

	cout << "*************************************************************" << endl;
	cout << "**                                                         **" << endl;
	cout << "**      Welcome to use OpenMP task validation system!      **" << endl;
	cout << "**                                                         **" << endl;
	cout << "**                                      editor: Amos Wang  **" << endl;
	cout << "*************************************************************\n" << endl;

	vector<string> argvList( argv, argv+argc );
	vector<string> argvList0( argv, argv+argc ); // keep original argv and argc

	command_processing( argvList );

	if( !parse_OmpTask( argvList ) ) {

		cout << "\nAmos says: I am sorry that I could not find any OpenMP task !" << endl << endl;
		return 0;
	}

	// for time counter
	long t_start;
	long t_end;
	double time_program = 0.0;

	t_start = usecs(); 
	// for time counter

	transform_Task2Loop( argvList );

	SgProject *project = frontend(argvList);
	ROSE_ASSERT( project != NULL );

#if 1
	VariantVector vv( V_SgForStatement );
	Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv);
	for( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) {
		SgForStatement* cur_loop = isSgForStatement(*iter);
		ROSE_ASSERT(cur_loop);
		SageInterface::normalizeForLoopInitDeclaration(cur_loop);
	}
#endif

	//initialize_analysis( project, false );
	initialize_analysis( project, false );

	//For each source file in the project
	SgFilePtrList &ptr_list = project->get_fileList();

	cout << "\n**** Amos' validation system running ****\n" << endl;

	for( SgFilePtrList::iterator iter = ptr_list.begin(); iter != ptr_list.end(); iter++ ) {

		cout << "temp source code: " << (*iter)->get_file_info()->get_filename() << endl << endl;
		SgFile *sageFile = (*iter);
		SgSourceFile *sfile = isSgSourceFile(sageFile);
		ROSE_ASSERT(sfile);
		SgGlobal *root = sfile->get_globalScope();
		SgDeclarationStatementPtrList& declList = root->get_declarations ();

		//cout << "Check point 2" << endl;
		//For each function body in the scope
		for( SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p ) 
		{
			SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
			if ( func == 0 )  continue;

			SgFunctionDefinition *defn = func->get_definition();
			if ( defn == 0 )  continue;

			//ignore functions in system headers, Can keep them to test robustness
			if ( defn->get_file_info()->get_filename() != sageFile->get_file_info()->get_filename() )
				continue;

			SgBasicBlock *body = defn->get_body();

			// For each loop
			Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree( defn, V_SgForStatement ); 

			if( loops.size() == 0 ) continue;

			// X. Replace operators with their equivalent counterparts defined 
			// in "inline" annotations
			AstInterfaceImpl faImpl_1( body );
			CPPAstInterface fa_body( &faImpl_1 );
			OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body) );

			// Pass annotations to arrayInterface and use them to collect 
			// alias info. function info etc.  
			ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
			ArrayInterface array_interface( *annot );
			array_interface.initialize( fa_body, AstNodePtrImpl(defn) );
			array_interface.observe( fa_body );

			// X. Loop normalization for all loops within body
			NormalizeForLoop(fa_body, AstNodePtrImpl(body));

			//cout << "Check point 3" << endl;
			for ( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) {

				SgNode* current_loop = *iter;
				SgInitializedName* invarname = getLoopInvariant( current_loop );

				if( invarname != NULL ) {

					if( invarname->get_name().getString().compare("__Amos_Wang__") == 0 ) {

						//cout << "It's __Amos_Wang__." << endl;
						//replace "for(__Amos_Wang__ = 0;__Amos_Wang__ <= 1 - 1;__Amos_Wang__ += 1)" 
						//to "#pragma omp task"
						std::string strtemp = current_loop->unparseToString();
						strtemp.replace( 0, 64, "#pragma omp task" );

						cout << "task position at: " << current_loop->get_file_info()->get_line()
							<< ", " << current_loop->get_file_info()->get_col() << endl;

						cout << "context: " << strtemp.c_str() << endl; 

						TaskValidation( current_loop );

						cout << "TaskValidation done...\n" << endl;
					}
					else continue;

				}

			}// end for loops

		}//end loop for each function body
		cout << "--------------------------------------------" << endl;

	}//end loop for each source file

	release_analysis();

	//generateDOT( *project );
	backend( project );

	//generate final file with correct directive
	amos_filter( argvList0 );

	// for time counter
	t_end = usecs();
	time_program = ((double)(t_end - t_start))/1000000;
	cout << "analysis time: " << time_program << " sec" << endl;
	//

	cout << endl << "***** Thank you for using Amos' compiler ! *****\n" << endl;

	return 0;
}
예제 #3
0
void POETAstInterface::unparse(POETCode_ext* n, std::ostream& out, int align)
{ 
 static SgUnparse_Info info;
 static Unparser* roseUnparser = 0;
 static POETCode* linebreak=ASTFactory::inst()->new_string("\n");
 static POETCode* comma=ASTFactory::inst()->new_string(",");
 static bool template_only=false;
 static POETCode* left_over = 0;
  SgNode * input = (SgNode*)n->get_content();
  POETCode* res = POETAstInterface::find_Ast2POET(input);
  if (res == n) {
      if (template_only && input->variantT() == V_SgFunctionDeclaration) 
         { left_over = LIST(n,left_over); }
      else {
        std::string res = input->unparseToCompleteString(); 
        out << res;
      }
  }
  else {
     if (roseUnparser == 0) {
        /* QY/2013: copied from the global unparseFile to use a different ostream and delegate*/
       bool UseAutoKeyword                = false;
       bool generateLineDirectives        = true;
       bool useOverloadedOperators        = false;
       bool num                           = false;
       bool _this                         = true;
       bool caststring                    = false;
       bool _debug                        = false;
       bool _class                        = false;
       bool _forced_transformation_format = false;
       bool _unparse_includes             = false; 
       Unparser_Opt roseOptions( UseAutoKeyword,
                                    generateLineDirectives,
                                    useOverloadedOperators,
                                    num,
                                    _this,
                                    caststring,
                                    _debug,
                                    _class,
                                    _forced_transformation_format,
                                    _unparse_includes );
       roseUnparser = new Unparser(&out, "", roseOptions);
     }
     switch (input->variantT()) {
     case V_SgSourceFile: 
      {
       SgSourceFile* f = isSgSourceFile(input);
       info.set_current_scope(f->get_globalScope());
       template_only = true;
       code_gen(out, n->get_children(), 0, 0, align); 
       template_only = false; 
       if (left_over != 0) {
           code_gen(out, left_over, 0, 0, align); 
           left_over = 0;
       }
       break;
      }
     case V_SgFunctionDeclaration:
      if (template_only) { left_over = LIST(n, left_over); break; }
     case V_SgTemplateInstantiationFunctionDecl:
      {
        SgFunctionDeclaration* d = isSgFunctionDeclaration(input);
        roseUnparser->u_exprStmt->unparseAttachedPreprocessingInfo(d,info,PreprocessingInfo::before);
        POETCode_ext_delegate repl(n, out);
        roseUnparser->repl = &repl;
        roseUnparser->u_exprStmt->unparseFuncDeclStmt(d, info);
        break;
      }
     case V_SgFunctionDefinition:
      {
        SgStatement* d = isSgStatement(input);
        POETCode_ext_delegate repl(n, out);
        roseUnparser->repl = &repl;
        roseUnparser->u_exprStmt->unparseStatement(d, info);
        assert(n->get_children() != n);
        out << "{"; code_gen(out, linebreak, 0, 0, align + 2); 
        code_gen(out, n->get_children(), 0, linebreak, align+2); 
        code_gen(out, linebreak, 0, 0, align); out << "}"; 
        break;
      }
     case V_SgPragmaDeclaration:
      {
         out << "#pragma ";
         POETTuple* c = dynamic_cast<POETTuple*>(n->get_children());
         assert(c != 0);
         code_gen(out, c->get_entry(0)); 
         roseUnparser->cur << " "; roseUnparser->cur.insert_newline(1,align);
         code_gen(out, c->get_entry(1), 0, 0, align); 
         break;
      }
     case V_SgForStatement:
      {
         out << "for (" ;
         POETTuple* c = dynamic_cast<POETTuple*>(n->get_children());
         assert(c != 0);
         code_gen(out, c->get_entry(0)); 
         code_gen(out, c->get_entry(1)); out << ";";
         code_gen(out, c->get_entry(2)); out << ")";
         break;
      }
     case V_SgExprStatement:
        code_gen(out, n->get_children(), 0, 0, align); 
        out << ";";
        break;
     case V_SgTemplateInstantiationMemberFunctionDecl:  break;
     default: 
std::cerr << "Unsupported unparsing for  : " << input->class_name() << input->unparseToString() << "\n";
//assert(0); 
     }
  }
}
예제 #4
0
int
main ( int argc,  char * argv[] )
{
  //init_poet();  // initialize poet

  if (argc <= 1) {
      PrintUsage(argv[0]);
      return -1;
  }

#ifdef USE_OMEGA
  std::stringstream buffer;
  buffer << argv[argc-1] << std::endl;
  DepStats.SetFileName(buffer.str());
#endif

  vector<string> argvList(argv, argv + argc);
  CmdOptions::GetInstance()->SetOptions(argvList);

  ArrayAnnotation* array_annot = ArrayAnnotation::get_inst();
  array_annot->register_annot();

  //OperatorSideEffectAnnotation* funcAnnot=OperatorSideEffectAnnotation::get_inst();
  //funcAnnot->register_annot();
  LoopTransformInterface::set_sideEffectInfo(array_annot);

  ArrayInterface anal(*array_annot);
  LoopTransformInterface::set_arrayInfo(&anal);

  ReadAnnotation::get_inst()->read();
  if (DebugAnnot()) {
   // funcAnnot->Dump();
    array_annot->Dump();
  }

  AssumeNoAlias aliasInfo;
  LoopTransformInterface::set_aliasInfo(&aliasInfo);

  LoopTransformInterface::cmdline_configure(argvList);

  SgProject *sageProject = new SgProject ( argvList);
  FixFileInfo(sageProject);

  // DQ (11/19/2013): Added AST consistency tests.
     AstTests::runAllTests(sageProject);

  int filenum = sageProject->numberOfFiles();
  for (int i = 0; i < filenum; ++i) {

  // DQ (11/19/2013): Added AST consistency tests.
     AstTests::runAllTests(sageProject);

    SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]);
    ROSE_ASSERT(sageFile != NULL);

    std::string fname = sageFile->get_file_info()->get_raw_filename();
    fname=fname.substr(fname.find_last_of('/')+1);

    AutoTuningInterface tuning(fname);

    LoopTransformInterface::set_tuningInterface(&tuning);
    SgGlobal *root = sageFile->get_globalScope();
    ROSE_ASSERT(root != NULL);

    SgDeclarationStatementPtrList declList = root->get_declarations ();

 // DQ (11/19/2013): Added AST consistency tests.
    AstTests::runAllTests(sageProject);

    for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
    {
      SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
      if (func == 0) continue;
      SgFunctionDefinition *defn = func->get_definition();
      if (defn == 0) continue;
      SgBasicBlock *stmts = defn->get_body();  
      AstInterfaceImpl scope(stmts);

   // DQ (11/19/2013): Added AST consistency tests.
      AstTests::runAllTests(sageProject);

   // DQ (11/19/2013): Added AST consistency tests.
      AstTests::runAllTests(sageProject);

      LoopTransformInterface::TransformTraverse(scope,AstNodePtrImpl(stmts));

#if 0
   // DQ (11/19/2013): Added AST consistency tests (this fails).
      AstTests::runAllTests(sageProject);
#endif
    }
    tuning.GenOutput();

#if 0
  // DQ (11/19/2013): Added AST consistency tests (this fails).
     AstTests::runAllTests(sageProject);
#endif
  }

//   if (CmdOptions::GetInstance()->HasOption("-fd")) {
//       simpleIndexFiniteDifferencing(sageProject);
//   }
//   if (CmdOptions::GetInstance()->HasOption("-pre")) {
//       partialRedundancyElimination(sageProject);
//   }

#if 0
  // DQ (11/19/2013): Added AST consistency tests (this fails).
     AstTests::runAllTests(sageProject);
#endif

     unparseProject(sageProject);
   //backend(sageProject);

#ifdef USE_OMEGA
     DepStats.SetDepChoice(0x1 | 0x2 | 0x4);
     DepStats.PrintResults();
#endif

  return 0;
}
예제 #5
0
int clang_main(int argc, char ** argv, SgSourceFile& sageFile) {
  // 0 - Analyse Cmd Line

    std::vector<std::string> inc_dirs_list;
    std::vector<std::string> define_list;
    std::vector<std::string> inc_list;
    std::string input_file;

    for (int i = 0; i < argc; i++) {
        std::string current_arg(argv[i]);
        if (current_arg.find("-I") == 0) {
            if (current_arg.length() > 2) {
                inc_dirs_list.push_back(current_arg.substr(2));
            }
            else {
                i++;
                if (i < argc)
                    inc_dirs_list.push_back(current_arg);
                else
                    break;
            }
        }
        else if (current_arg.find("-D") == 0) {
            if (current_arg.length() > 2) {
                define_list.push_back(current_arg.substr(2));
            }
            else {
                i++;
                if (i < argc)
                    define_list.push_back(current_arg);
                else
                    break;
            }
        }
        else if (current_arg.find("-c") == 0) {}
        else if (current_arg.find("-o") == 0) {
            if (current_arg.length() == 2) {
                i++;
                if (i >= argc) break;
            }
        }
        else {
            // TODO -include
#if DEBUG_ARGS
            std::cerr << "argv[" << i << "] = " << current_arg << " is neither define or include dir. Use it as input file."  << std::endl;
#endif
            input_file = current_arg;
        }
    }

    ClangToSageTranslator::Language language = ClangToSageTranslator::unknown;

    size_t last_period = input_file.find_last_of(".");
    std::string extention(input_file.substr(last_period + 1));

    if (extention == "c") {
        language = ClangToSageTranslator::C;
    }
    else if (extention == "C" || extention == "cxx" || extention == "cpp" || extention == "cc") {
        language = ClangToSageTranslator::CPLUSPLUS;
    }
    else if (extention == "objc") {
        language = ClangToSageTranslator::OBJC;
    }
    else if (extention == "cu") {
        language = ClangToSageTranslator::CUDA;
    }
    else if (extention == "ocl" || extention == "cl") {
        language = ClangToSageTranslator::OPENCL;
    }

    ROSE_ASSERT(language != ClangToSageTranslator::unknown);

    const char * cxx_config_include_dirs_array [] = CXX_INCLUDE_STRING;
    const char * c_config_include_dirs_array   [] = C_INCLUDE_STRING;

    std::vector<std::string> cxx_config_include_dirs (
                                                       cxx_config_include_dirs_array,
                                                       cxx_config_include_dirs_array + sizeof(cxx_config_include_dirs_array) / sizeof(const char*)
                                                     );
    std::vector<std::string> c_config_include_dirs   (
                                                       c_config_include_dirs_array,
                                                       c_config_include_dirs_array + sizeof(c_config_include_dirs_array) / sizeof(const char*)
                                                     );

    std::string rose_include_path;
    bool in_install_tree = roseInstallPrefix(rose_include_path);
    if (in_install_tree) {
        rose_include_path += "/include-staging/";
    }
    else {
        rose_include_path = std::string(ROSE_AUTOMAKE_TOP_BUILDDIR) + "/include-staging/";
    }

    std::vector<std::string>::iterator it;
    for (it = c_config_include_dirs.begin(); it != c_config_include_dirs.end(); it++)
        if (it->length() > 0 && (*it)[0] != '/')
            *it = rose_include_path + *it;
    for (it = cxx_config_include_dirs.begin(); it != cxx_config_include_dirs.end(); it++)
        if (it->length() > 0 && (*it)[0] != '/')
            *it = rose_include_path + *it;

    inc_dirs_list.push_back(rose_include_path + "clang/");


    // FIXME add ROSE path to gcc headers...
    switch (language) {
        case ClangToSageTranslator::C:
            inc_dirs_list.insert(inc_dirs_list.begin(), c_config_include_dirs.begin(), c_config_include_dirs.end());
            inc_list.push_back("clang-builtin-c.h");
            break;
        case ClangToSageTranslator::CPLUSPLUS:
            inc_dirs_list.insert(inc_dirs_list.begin(), cxx_config_include_dirs.begin(), cxx_config_include_dirs.end());
            inc_list.push_back("clang-builtin-cpp.hpp");
            break;
        case ClangToSageTranslator::CUDA:
            inc_dirs_list.insert(inc_dirs_list.begin(), cxx_config_include_dirs.begin(), cxx_config_include_dirs.end());
            inc_list.push_back("clang-builtin-cuda.hpp");
            break;
        case ClangToSageTranslator::OPENCL:
//          inc_dirs_list.insert(inc_dirs_list.begin(), c_config_include_dirs.begin(), c_config_include_dirs.end());
            // FIXME get the path right
            inc_list.push_back("clang-builtin-opencl.h");
            break;
        case ClangToSageTranslator::OBJC:
        default:
            ROSE_ASSERT(false);
    }

    // FIXME should be handle by Clang ?
    define_list.push_back("__I__=_Complex_I");

    unsigned cnt = define_list.size() + inc_dirs_list.size() + inc_list.size();
    char ** args = new char*[cnt];
    std::vector<std::string>::iterator it_str;
    unsigned i = 0;
    for (it_str = define_list.begin(); it_str != define_list.end(); it_str++) {
        args[i] = new char[it_str->size() + 3];
        args[i][0] = '-';
        args[i][1] = 'D';
        strcpy(&(args[i][2]), it_str->c_str());
#if DEBUG_ARGS
        std::cerr << "args[" << i << "] = " << args[i] << std::endl;
#endif
        i++;
    }
    for (it_str = inc_dirs_list.begin(); it_str != inc_dirs_list.end(); it_str++) {
        args[i] = new char[it_str->size() + 3];
        args[i][0] = '-';
        args[i][1] = 'I';
        strcpy(&(args[i][2]), it_str->c_str());
#if DEBUG_ARGS
        std::cerr << "args[" << i << "] = " << args[i] << std::endl;
#endif
        i++;
    }
    for (it_str = inc_list.begin(); it_str != inc_list.end(); it_str++) {
        args[i] = new char[it_str->size() + 9];
        args[i][0] = '-'; args[i][1] = 'i'; args[i][2] = 'n'; args[i][3] = 'c';
        args[i][4] = 'l'; args[i][5] = 'u'; args[i][6] = 'd'; args[i][7] = 'e';
        strcpy(&(args[i][8]), it_str->c_str());
#if DEBUG_ARGS
        std::cerr << "args[" << i << "] = " << args[i] << std::endl;
#endif
        i++;
    }


  // 2 - Create a compiler instance

    clang::CompilerInstance * compiler_instance = new clang::CompilerInstance();

    clang::TextDiagnosticPrinter * diag_printer = new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
    compiler_instance->createDiagnostics(argc, argv, diag_printer, true, false);

    clang::CompilerInvocation * invocation = new clang::CompilerInvocation();
    clang::CompilerInvocation::CreateFromArgs(*invocation, args, &(args[cnt]), compiler_instance->getDiagnostics());
    compiler_instance->setInvocation(invocation);

    clang::LangOptions & lang_opts = compiler_instance->getLangOpts();

    switch (language) {
        case ClangToSageTranslator::C:
//          compiler_instance->getInvocation().setLangDefaults(lang_opts, clang::IK_C, );
            break;
        case ClangToSageTranslator::CPLUSPLUS:
            lang_opts.CPlusPlus = 1;
//          compiler_instance->getInvocation().setLangDefaults(lang_opts, clang::IK_CXX, );
            break;
        case ClangToSageTranslator::CUDA:
            lang_opts.CUDA = 1;
//          lang_opts.CPlusPlus = 1;
//          compiler_instance->getInvocation().setLangDefaults(lang_opts, clang::IK_CUDA,   clang::LangStandard::lang_cuda);
            break;
        case ClangToSageTranslator::OPENCL:
            lang_opts.OpenCL = 1;
//          compiler_instance->getInvocation().setLangDefaults(lang_opts, clang::IK_OpenCL, clang::LangStandard::lang_opencl);
            break;
        case ClangToSageTranslator::OBJC:
            ROSE_ASSERT(!"Objective-C is not supported by ROSE Compiler.");
//          compiler_instance->getInvocation().setLangDefaults(lang_opts, clang::IK_, );
        default:
            ROSE_ASSERT(false);
    }

    clang::TargetOptions target_options;
    target_options.Triple = llvm::sys::getHostTriple();
    clang::TargetInfo * target_info = clang::TargetInfo::CreateTargetInfo(compiler_instance->getDiagnostics(), target_options);
    compiler_instance->setTarget(target_info);

    compiler_instance->createFileManager();
    compiler_instance->createSourceManager(compiler_instance->getFileManager());

    const clang::FileEntry * input_file_entry = compiler_instance->getFileManager().getFile(input_file);
    compiler_instance->getSourceManager().createMainFileID(input_file_entry);

    if (!compiler_instance->hasPreprocessor()) compiler_instance->createPreprocessor();

    if (!compiler_instance->hasASTContext()) compiler_instance->createASTContext();

    ClangToSageTranslator translator(compiler_instance, language);
    compiler_instance->setASTConsumer(&translator);   

    if (!compiler_instance->hasSema()) compiler_instance->createSema(clang::TU_Complete, NULL);

    ROSE_ASSERT (compiler_instance->hasDiagnostics());
    ROSE_ASSERT (compiler_instance->hasTarget());
    ROSE_ASSERT (compiler_instance->hasFileManager());
    ROSE_ASSERT (compiler_instance->hasSourceManager());
    ROSE_ASSERT (compiler_instance->hasPreprocessor());
    ROSE_ASSERT (compiler_instance->hasASTContext());
    ROSE_ASSERT (compiler_instance->hasSema());

  // 3 - Translate

    compiler_instance->getDiagnosticClient().BeginSourceFile(compiler_instance->getLangOpts(), &(compiler_instance->getPreprocessor()));
    clang::ParseAST(compiler_instance->getPreprocessor(), &translator, compiler_instance->getASTContext());
    compiler_instance->getDiagnosticClient().EndSourceFile();

    SgGlobal * global_scope = translator.getGlobalScope();

  // 4 - Attach to the file

    if (sageFile.get_globalScope() != NULL) SageInterface::deleteAST(sageFile.get_globalScope());

    sageFile.set_globalScope(global_scope);

    global_scope->set_parent(&sageFile);

    std::string file_name(input_file);

    Sg_File_Info * start_fi = new Sg_File_Info(file_name, 0, 0);
    Sg_File_Info * end_fi   = new Sg_File_Info(file_name, 0, 0);

    global_scope->set_startOfConstruct(start_fi);

    global_scope->set_endOfConstruct(end_fi);

  // 5 - Finish the AST (fixup phase)

    finishSageAST(translator);

    return 1;
}
예제 #6
0
POETCode* POETAstInterface::Ast2POET(const Ast& n)
{
  static SgTemplateInstantiationFunctionDecl* tmp=0;
  SgNode* input = (SgNode*) n;
  if (input == 0) return EMPTY;
  POETCode* res = POETAstInterface::find_Ast2POET(input);
  if (res != 0) return res;

  {
  SgProject* sageProject=isSgProject(input); 
  if (sageProject != 0) {
    int filenum = sageProject->numberOfFiles(); 
    for (int i = 0; i < filenum; ++i) { 
      SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); 
      SgGlobal *root = sageFile->get_globalScope(); 
      SgDeclarationStatementPtrList declList = root->get_declarations ();
      POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp);
      curfile = new POETCode_ext(sageFile, curfile);
      POETAstInterface::set_Ast2POET(sageFile, curfile);
      res=LIST(curfile, res);
    }
    POETAstInterface::set_Ast2POET(sageProject,res); 
    return res;
  } }
  { 
  SgBasicBlock* block = isSgBasicBlock(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_statements(), res, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
  { 
  SgExprListExp* block = isSgExprListExp(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_expressions(), 0, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
 {
  SgForStatement *f = isSgForStatement(input);
  if (f != 0) {
      POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp);
      POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment())));
      res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body())));  
      POETAstInterface::set_Ast2POET(input, res); 
      return res;
  }
  }
  {
    SgVarRefExp * v = isSgVarRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgIntVal * v = isSgIntVal(input);
    if (v != 0) {
       res = ICONST(v->get_value());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
   SgInitializedName* var = isSgInitializedName(input);
   if (var != 0) {
     POETCode* name = STRING(var->get_name().str()); 
     POETCode* init = Ast2POET(var->get_initializer());
     res = new POETCode_ext(var, PAIR(name,init));
     POETAstInterface::set_Ast2POET(input, res); 
     return res;
   }
  }

/*
  {
  std::string fname;
  AstInterface::AstList params;
  AstNodeType returnType;
  AstNodePtr body;
  if (AstInterface :: IsFunctionDefinition( input, &fname, &params, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) {
if (body != AST_NULL)
 std::cerr << "body not empty:" << fname << "\n";
      POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), 
                 STRING(AstInterface::GetTypeName(returnType)), 
                 Ast2POET(body.get_ptr()));
      res = new POETCode_ext(input, c);
      POETAstInterface::set_Ast2POET(input,res);
      return res;
  } }   
*/

  AstInterface::AstList c = AstInterface::GetChildrenList(input);
  switch (input->variantT()) {
    case V_SgCastExp:
    case V_SgAssignInitializer:
      res = Ast2POET(c[0]); 
      POETAstInterface::set_Ast2POET(input, res); return res; 
    case V_SgDotExp:
     {
      POETCode* v1 = Ast2POET(c[1]);
      if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") 
           return Ast2POET(c[0]);
      res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res;
     }
    case V_SgLessThanOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgSubtractOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAddOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgMultiplyOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgDivideOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAssignOp:
      res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgFunctionCallExp:
      res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
  } 
  POETCode * c2 = 0; 
  if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input);
   switch (c.size()) {
   case 0: break;
   case 1: c2 = Ast2POET(c[0]); break;
   case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break;
   case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break;
   case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break;
   default: 
     //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n";
     c2 = EMPTY;
   }
  if (tmp == input) tmp = 0;
  res = new POETCode_ext(input, c2); 
  POETAstInterface::set_Ast2POET(input,res);
  return res;
}
예제 #7
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  //  autopar_command_processing(argvList);
  argvList = commandline_processing (argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

  // register midend signal handling function
  if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL)
  {
    std::cout
      << "[WARN] "
      << "Configured to keep going after catching a "
      << "signal in AutoPar"
      << std::endl;
    Rose::KeepGoing::setMidendErrorCode (project, 100);
    goto label_end;
  }   

  // create a block to avoid jump crosses initialization of candidateFuncDefs etc.
  {                             
    std::vector<SgFunctionDefinition* > candidateFuncDefs; 
    findCandidateFunctionDefinitions (project, candidateFuncDefs);
    normalizeLoops (candidateFuncDefs);

    //Prepare liveness analysis etc.
    //Too much output for analysis debugging info.
    //initialize_analysis (project,enable_debug);   
    initialize_analysis (project, false);   

    // This is a bit redundant with findCandidateFunctionDefinitions ()
    // But we do need the per file control to decide if omp.h is needed for each file
    //
    // For each source file in the project
    SgFilePtrList & ptr_list = project->get_fileList();
    for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
        iter++)
    {
      SgFile* sageFile = (*iter);
      SgSourceFile * sfile = isSgSourceFile(sageFile);
      ROSE_ASSERT(sfile);
      SgGlobal *root = sfile->get_globalScope();

      Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); 
      bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

      //For each function body in the scope
      //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
      for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) 
      {

        //      cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl;

        SgFunctionDefinition *defn = isSgFunctionDefinition(*p);
        ROSE_ASSERT (defn != NULL);

        SgFunctionDeclaration *func = defn->get_declaration();
        ROSE_ASSERT (func != NULL);

        //ignore functions in system headers, Can keep them to test robustness
        if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
        {
          continue;
        }

        SgBasicBlock *body = defn->get_body();  
        // For each loop 
        Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); 
        if (loops.size()==0) 
        {
          if (enable_debug)
            cout<<"\t skipped since no for loops are found in this function"<<endl;
          continue;
        }

#if 0 // Moved to be executed before running liveness analysis.
        // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
        // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
            iter!= loops.end(); iter++ )
        {
          SgForStatement* cur_loop = isSgForStatement(*iter);
          ROSE_ASSERT(cur_loop);
          SageInterface::normalizeForLoopInitDeclaration(cur_loop);
        }
#endif
        // X. Replace operators with their equivalent counterparts defined 
        // in "inline" annotations
        AstInterfaceImpl faImpl_1(body);
        CPPAstInterface fa_body(&faImpl_1);
        OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body));

        // Pass annotations to arrayInterface and use them to collect 
        // alias info. function info etc.  
        ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
        ArrayInterface array_interface(*annot);
        array_interface.initialize(fa_body, AstNodePtrImpl(defn));
        array_interface.observe(fa_body);

        //FR(06/07/2011): aliasinfo was not set which caused segfault
        LoopTransformInterface::set_aliasInfo(&array_interface);

        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); 
            iter!= loops.end(); iter++ ) 
        {
          SgNode* current_loop = *iter;

          if (enable_debug)
          {
            SgForStatement * fl = isSgForStatement(current_loop);
            cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl;
          }
          //X. Parallelize loop one by one
          // getLoopInvariant() will actually check if the loop has canonical forms 
          // which can be handled by dependence analysis
          SgInitializedName* invarname = getLoopInvariant(current_loop);
          if (invarname != NULL)
          {
            bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot);
            if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file.
              hasOpenMP = true;  
          }
          else // cannot grab loop index from a non-conforming loop, skip parallelization
          {
            if (enable_debug)
              cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl;
            // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be.  
            //hasOpenMP = false;
          }
        }// end for loops
      } // end for-loop for declarations

      // insert omp.h if needed
      if (hasOpenMP && !enable_diff)
      {
        SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root);
        if (enable_patch)
          generatePatchFile(sfile); 
      }
      // compare user-defined and compiler-generated OmpAttributes
      if (enable_diff)
        diffUserDefinedAndCompilerGeneratedOpenMP(sfile); 
    } //end for-loop of files

#if 1
    // undo loop normalization
    std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin();
    for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) 
    {
      SgForStatement* for_loop = (*iter).first; 
      unnormalizeForLoopInitDeclaration (for_loop);
    }
#endif
    // Qing's loop normalization is not robust enough to pass all tests
    //AstTests::runAllTests(project);


    // clean up resources for analyses
    release_analysis();
  }

label_end: 
  // Report errors
  if (keep_going)
  {
    std::vector<std::string> orig_rose_cmdline(argv, argv+argc);
    Rose::KeepGoing::generate_reports (project, orig_rose_cmdline);
  }

  //project->unparse();
  return backend (project);
}
예제 #8
0
int main(int argc, char** argv) {

  std::string binaryFilename = (argc >= 1 ? argv[argc-1]   : "" );
  std::vector<std::string> newArgv(argv,argv+argc);
  newArgv.push_back("-rose:output");
  newArgv.push_back(binaryFilename+"-binarySemantics.C");

  SgProject* proj = frontend(newArgv);
  
  ROSE_ASSERT (proj);
  SgSourceFile* newFile = isSgSourceFile(proj->get_fileList().front());
  ROSE_ASSERT(newFile != NULL);
  SgGlobal* g = newFile->get_globalScope();
  ROSE_ASSERT (g);

  //I am doing some experimental work to enable functions in the C representation
  //Set this flag to true in order to enable that work
  bool enable_functions = true;
  //Jeremiah did some work to enable a simplification and normalization of the 
  //C representation. Enable this work by setting this flag to true.
  bool enable_normalizations = false;

  vector<SgNode*> asmFiles = NodeQuery::querySubTree(proj, V_SgAsmGenericFile);
  ROSE_ASSERT (asmFiles.size() == 1);



  if( enable_functions == false)
  {
    //Representation of C normalizations withotu functions
    SgFunctionDeclaration* decl = buildDefiningFunctionDeclaration("run", SgTypeVoid::createType(), buildFunctionParameterList(), g);
    appendStatement(decl, g);
    SgBasicBlock* body = decl->get_definition()->get_body();
    //  ROSE_ASSERT(isSgAsmFile(asmFiles[0]));
    //  X86CTranslationPolicy policy(newFile, isSgAsmFile(asmFiles[0]));
    X86CTranslationPolicy policy(newFile, isSgAsmGenericFile(asmFiles[0]));
    ROSE_ASSERT( isSgAsmGenericFile(asmFiles[0]) != NULL);

    policy.switchBody = buildBasicBlock();
    removeDeadStores(policy.switchBody,policy);

    SgSwitchStatement* sw = buildSwitchStatement(buildVarRefExp(policy.ipSym), policy.switchBody);
    ROSE_ASSERT(isSgBasicBlock(sw->get_body()));

    SgWhileStmt* whileStmt = buildWhileStmt(buildBoolValExp(true), sw);

    appendStatement(whileStmt, body);
    policy.whileBody = sw;

    X86InstructionSemantics<X86CTranslationPolicy, WordWithExpression> t(policy);
    //AS FIXME: This query gets noting in the form in the repository. Doing this hack since we only 
    //have one binary file anyways.
    //vector<SgNode*> instructions = NodeQuery::querySubTree(asmFiles[0], V_SgAsmX86Instruction);
    vector<SgNode*> instructions = NodeQuery::querySubTree(proj, V_SgAsmX86Instruction);

    std::cout << "Instruction\n";
    for (size_t i = 0; i < instructions.size(); ++i) {
      SgAsmX86Instruction* insn = isSgAsmX86Instruction(instructions[i]);
      ROSE_ASSERT (insn);
      try {
          t.processInstruction(insn);
      } catch (const X86InstructionSemantics<X86CTranslationPolicy, WordWithExpression>::Exception &e) {
          std::cout <<e.mesg <<": " <<unparseInstructionWithAddress(e.insn) <<"\n";
      }
    }


    if ( enable_normalizations == true )
    {
      //Enable normalizations of C representation
      //This is done heuristically where some steps
      //are repeated. It is not clear which order is 
      //the best
      {
        plugInAllConstVarDefs(policy.switchBody,policy) ;
        simplifyAllExpressions(policy.switchBody);
        removeIfConstants(policy.switchBody);
        removeDeadStores(policy.switchBody,policy);
        removeUnusedVariables(policy.switchBody);
      }
      {
        plugInAllConstVarDefs(policy.switchBody,policy) ;
        simplifyAllExpressions(policy.switchBody);
        removeIfConstants(policy.switchBody);
        removeDeadStores(policy.switchBody,policy);
      }
      removeUnusedVariables(policy.switchBody);
    }

  
  }else{ //Experimental changes to introduce functions into the C representation


    //When trying to add function I get that symbols are not defined

    //Iterate over the functions separately
    vector<SgNode*> asmFunctions = NodeQuery::querySubTree(proj, V_SgAsmFunction);

    for(size_t j = 0; j < asmFunctions.size(); j++ )
    {
      SgAsmFunction* binFunc = isSgAsmFunction( asmFunctions[j] );

      // Some functions (probably just one) are generated to hold basic blocks that could not
      // be assigned to a particular function. This happens when the Disassembler is overzealous
      // and the Partitioner cannot statically determine where the block belongs.  The name of
      // one such function is "***uncategorized blocks***".  [matzke 2010-06-29]
      if ((binFunc->get_reason() & SgAsmFunction::FUNC_LEFTOVERS))
        continue;

      //Some functions may be unnamed so we need to generate a name for those
      std::string funcName;
      if (binFunc->get_name().size()==0) {
	char addr_str[64];
	sprintf(addr_str, "0x%"PRIx64, binFunc->get_statementList()[0]->get_address());
	funcName = std::string("my_") + addr_str;;
      } else {
	funcName = "my" + binFunc->get_name();
      }

      //Functions can have illegal characters in their name. Need to replace those characters
      for ( int i = 0 ; i < funcName.size(); i++ )
      {
	char& currentCharacter = funcName.at(i);
	if ( currentCharacter == '.' )
	  currentCharacter = '_';
      }


      SgFunctionDeclaration* decl = buildDefiningFunctionDeclaration(funcName, SgTypeVoid::createType(), buildFunctionParameterList(), g);

      appendStatement(decl, g);
      SgBasicBlock* body = decl->get_definition()->get_body();
      X86CTranslationPolicy policy(newFile, isSgAsmGenericFile(asmFiles[0]));
      ROSE_ASSERT( isSgAsmGenericFile(asmFiles[0]) != NULL);
      policy.switchBody = buildBasicBlock();
      SgSwitchStatement* sw = buildSwitchStatement(buildVarRefExp(policy.ipSym), policy.switchBody);
      SgWhileStmt* whileStmt = buildWhileStmt(buildBoolValExp(true), sw);
      appendStatement(whileStmt, body);
      policy.whileBody = sw;
      X86InstructionSemantics<X86CTranslationPolicy, WordWithExpression> t(policy);
      vector<SgNode*> instructions = NodeQuery::querySubTree(binFunc, V_SgAsmX86Instruction);

      for (size_t i = 0; i < instructions.size(); ++i) {
        SgAsmX86Instruction* insn = isSgAsmX86Instruction(instructions[i]);
	if( insn->get_kind() == x86_nop )
	  continue;
        ROSE_ASSERT (insn);
        try {
            t.processInstruction(insn);
        } catch (const X86InstructionSemantics<X86CTranslationPolicy, WordWithExpression>::Exception &e) {
            std::cout <<e.mesg <<": " <<unparseInstructionWithAddress(e.insn) <<"\n";
        }
      }

    }

    //addDirectJumpsToSwitchCases(policy);


  }

  proj->get_fileList().erase(proj->get_fileList().end() - 1); // Remove binary file before calling backend

//  AstTests::runAllTests(proj);

  //Compile the resulting project

  return backend(proj);
}
예제 #9
0
파일: options.C 프로젝트: 8l/rose
void
TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName )
   {
  // This function searches for variables of type ScopeBasedTransformationOptimization.  Variables
  // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the
  // application to the preprocessor. If called from a project or file object it traverses down to
  // the global scope of the file and searches only the global scope, if called from and other
  // location within the AST it searches the current scope and then traverses the parent nodes to
  // find all enclosing scopes until in reaches the global scope.  At each scope it searches for
  // variables of type ScopeBasedTransformationOptimization.

  // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n");

     ROSE_ASSERT (astNode != NULL);
     ROSE_ASSERT (identifingTypeName.c_str() != NULL);

#if 0
     printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n",
          astNode->sage_class_name(),generatedList.size());
     SgLocatedNode* locatedNode = isSgLocatedNode(astNode);
     if (locatedNode != NULL)
        {
          printf ("          locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename());
          printf ("          locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line());
        }
#endif

     switch (astNode->variant())
        {
          case ProjectTag:
             {
               SgProject* project = isSgProject(astNode);
               ROSE_ASSERT (project != NULL);

           //! Loop through all the files in the project and call the mainTransform function for each file
               int i = 0;
               for (i=0; i < project->numberOfFiles(); i++)
                  {
                    SgFile* file = &(project->get_file(i));

                 // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n");
                    getTransformationOptions ( file, generatedList, identifingTypeName );
                  }
               break;
             }

          case SourceFileTag:
             {
               SgSourceFile* file = isSgSourceFile(astNode);
               ROSE_ASSERT (file != NULL);
               SgGlobal* globalScope = file->get_globalScope();
               ROSE_ASSERT (globalScope != NULL);
               ROSE_ASSERT (isSgGlobal(globalScope) != NULL);
               getTransformationOptions ( globalScope, generatedList, identifingTypeName );
               break;
             }

       // Global Scope
          case GLOBAL_STMT:
             {
               SgGlobal* globalScope = isSgGlobal(astNode);
               ROSE_ASSERT (globalScope != NULL);

               SgSymbolTable* symbolTable = globalScope->get_symbol_table();
               ROSE_ASSERT (symbolTable != NULL);
               getTransformationOptions ( symbolTable, generatedList, identifingTypeName );

            // printf ("Processed global scope, exiting .. \n");
            // ROSE_ABORT();
               break;
             }

          case SymbolTableTag:
             {
            // List the variable in each scope
            // printf ("List all the variables in this symbol table! \n");
               SgSymbolTable* symbolTable = isSgSymbolTable(astNode);
               ROSE_ASSERT (symbolTable != NULL);

               bool foundTransformationOptimizationSpecifier = false;

            // printf ("Now print out the information in the symbol table for this scope: \n");
            // symbolTable->print();

#if 0
            // I don't know when a SymbolTable is given a name!
               printf ("SymbolTable has a name = %s \n",
                    (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name");
               if (!symbolTable->get_no_name())
                    printf ("SymbolTable name = %s \n",symbolTable->get_name().str());
                 else
                    ROSE_ASSERT (symbolTable->get_name().str() == NULL);
#endif

               if (symbolTable->get_table() != NULL)
                  {
                    SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin();
                    int counter = 0;
                    while (i != symbolTable->get_table()->end())
                       {
                         ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL );

                      // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n",
                      //      counter,(*i).first.str(),(*i).second->sage_class_name());

                         SgSymbol* symbol = isSgSymbol((*i).second);
                         ROSE_ASSERT ( symbol != NULL );
                         SgType* type = symbol->get_type();
                         ROSE_ASSERT ( type != NULL );

                         SgNamedType* namedType = isSgNamedType(type);
                         string typeName;
                         if (namedType != NULL)
                            {
                              SgName n = namedType->get_name();
                              typeName = namedType->get_name().str();
                           // char* nameString = namedType->get_name().str();
                           // printf ("Type is: (named type) = %s \n",nameString);
                              ROSE_ASSERT (identifingTypeName.c_str() != NULL);
                           // ROSE_ASSERT (typeName != NULL);
                           // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str());
                           // if ( (typeName != NULL) && ( typeName == identifingTypeName) )
                              if ( typeName == identifingTypeName )
                                 {
                                // Now look at the parameter list to the constructor and save the
                                // values into the list.

                                // printf ("Now save the constructor arguments! \n");

                                   SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol);

                                   if ( variableSymbol != NULL )
                                      {
                                        SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration();
                                        ROSE_ASSERT (initializedNameDeclaration != NULL);

                                        SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration();
                                        ROSE_ASSERT (declarationStatement != NULL);

                                        SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement);
                                        ROSE_ASSERT (variableDeclaration != NULL);

                                        getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList);

                                        foundTransformationOptimizationSpecifier = true;

                                     // printf ("Exiting after saving the constructor arguments! \n");
                                     // ROSE_ABORT();
                                      }
                                     else
                                      {
#if 0
                                        printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n",
                                             symbol->sage_class_name());
#endif
                                      }
                                 }
                                else
                                 {
#if 0
                                   printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n",
                                        symbol->sage_class_name());
#endif
#if 0
                                // I don't think this should ever be NULL (but it is sometimes)
                                   if (typeName != NULL)
                                        printf ("typeName == NULL \n");
#endif
                                 }
                            }
                           else
                            {
                              typeName = (char *)type->sage_class_name();
                            }

                      // printf ("In while loop at the base: counter = %d \n",counter);
                         i++;
                         counter++;
                       }
                  }
                 else
                  {
                 // printf ("Pointer to symbol table is NULL \n");
                  }

            // printf ("foundTransformationOptimizationSpecifier = %s \n",foundTransformationOptimizationSpecifier ? "true" : "false");

            // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent
            // member function in the interface)!
               break;
             }

          case BASIC_BLOCK_STMT:
             {
            // List the variable in each scope
            // printf ("List all the variables in this scope! \n");
               SgBasicBlock* basicBlock = isSgBasicBlock(astNode);
               ROSE_ASSERT (basicBlock != NULL);

               SgSymbolTable* symbolTable = basicBlock->get_symbol_table();
               ROSE_ASSERT (symbolTable != NULL);
               getTransformationOptions ( symbolTable, generatedList, identifingTypeName );

            // Next go (fall through this case) to the default case so that we traverse the parent
            // of the SgBasicBlock.
            // break;
             }

          default:
            // Most cases will be the default (this is by design)
            // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name());

            // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope)
               SgStatement* statement = isSgStatement(astNode);
               if (statement != NULL)
                  {
                    SgNode* parentNode = statement->get_parent();
                    ROSE_ASSERT (parentNode != NULL);
//                  printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name());
                    SgStatement* parentStatement = isSgStatement(parentNode);
                    if (parentStatement == NULL)
                       {
                         printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name());
                         printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename());
                         printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line());
                       }
                    ROSE_ASSERT (parentStatement != NULL);

                 // Call this function recursively (directly rather than through the query mechanism)
                    getTransformationOptions ( parentStatement, generatedList, identifingTypeName );
                  }
                 else
                  {
                 // printf ("astNode is not a SgStatement! \n");
                  }

               break;
        }

#if 0
     printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n",
          astNode->sage_class_name(),generatedList.size());
#endif

  // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n");
   }
예제 #10
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  autopar_command_processing(argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

#if 1 // This has to happen before analyses are called.
       // For each loop 
       VariantVector vv (V_SgForStatement); 
        Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); 

      // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
       // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
         for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
                     iter!= loops.end(); iter++ )
         {
           SgForStatement* cur_loop = isSgForStatement(*iter);
           ROSE_ASSERT(cur_loop);
           SageInterface::normalizeForLoopInitDeclaration(cur_loop);
         }

#endif
  //Prepare liveness analysis etc.
  initialize_analysis (project,false);   
  // For each source file in the project
    SgFilePtrList & ptr_list = project->get_fileList();
    for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
        iter++)
   {
     SgFile* sageFile = (*iter);
     SgSourceFile * sfile = isSgSourceFile(sageFile);
     ROSE_ASSERT(sfile);
     SgGlobal *root = sfile->get_globalScope();
     SgDeclarationStatementPtrList& declList = root->get_declarations ();
     bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

    //For each function body in the scope
     for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
     {
        SgFunctionDeclaration *func = isSgFunctionDeclaration(*p);
        if (func == 0)  continue;
        SgFunctionDefinition *defn = func->get_definition();
        if (defn == 0)  continue;
         //ignore functions in system headers, Can keep them to test robustness
        if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
          continue;
        SgBasicBlock *body = defn->get_body();  
       // For each loop 
        Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); 
        if (loops.size()==0) continue;

#if 0 // Moved to be executed before running liveness analysis.
      // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
       // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
         for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
                     iter!= loops.end(); iter++ )
         {
           SgForStatement* cur_loop = isSgForStatement(*iter);
           ROSE_ASSERT(cur_loop);
           SageInterface::normalizeForLoopInitDeclaration(cur_loop);
         }
#endif
        // X. Replace operators with their equivalent counterparts defined 
        // in "inline" annotations
        AstInterfaceImpl faImpl_1(body);
        CPPAstInterface fa_body(&faImpl_1);
        OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body));
         
	 // Pass annotations to arrayInterface and use them to collect 
         // alias info. function info etc.  
         ArrayAnnotation* annot = ArrayAnnotation::get_inst(); 
         ArrayInterface array_interface(*annot);
         array_interface.initialize(fa_body, AstNodePtrImpl(defn));
         array_interface.observe(fa_body);
	
	//FR(06/07/2011): aliasinfo was not set which caused segfault
	LoopTransformInterface::set_aliasInfo(&array_interface);
       
        // X. Loop normalization for all loops within body
        NormalizeForLoop(fa_body, AstNodePtrImpl(body));

	for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); 
	    iter!= loops.end(); iter++ ) 
	{
	  SgNode* current_loop = *iter;
	  //X. Parallelize loop one by one
          // getLoopInvariant() will actually check if the loop has canonical forms 
          // which can be handled by dependence analysis
          SgInitializedName* invarname = getLoopInvariant(current_loop);
          if (invarname != NULL)
          {
             hasOpenMP = ParallelizeOutermostLoop(current_loop, &array_interface, annot);
          }
           else // cannot grab loop index from a non-conforming loop, skip parallelization
           {
            if (enable_debug)
              cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl;
             hasOpenMP = false;
           }
	}// end for loops
      } // end for-loop for declarations
     // insert omp.h if needed
     if (hasOpenMP && !enable_diff)
     {
       SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root);
       if (enable_patch)
         generatePatchFile(sfile); 
     }
     // compare user-defined and compiler-generated OmpAttributes
     if (enable_diff)
       diffUserDefinedAndCompilerGeneratedOpenMP(sfile); 
   } //end for-loop of files

  // Qing's loop normalization is not robust enough to pass all tests
  //AstTests::runAllTests(project);
  
  release_analysis();
  //project->unparse();
  return backend (project);
}
예제 #11
0
int
main( int argc, char* argv[] )
   {
  // Initialize and check compatibility. See rose::initialize
     ROSE_INITIALIZE;

     SgProject* project = frontend(argc,argv);
     AstTests::runAllTests(project);

#if 0
  // Output the graph so that we can see the whole AST graph, for debugging.
     generateAstGraph(project, 4000);
#endif
#if 1
     printf ("Generate the dot output of the SAGE III AST \n");
     generateDOT ( *project );
     printf ("DONE: Generate the dot output of the SAGE III AST \n");
#endif

  // There are lots of way to write this, this is one simple approach; get all the function calls.
     std::vector<SgNode*> functionCalls = NodeQuery::querySubTree (project,V_SgFunctionCallExp);

  // Find the SgFunctionSymbol for snprintf so that we can reset references to "sprintf" to "snprintf" instead.
  // SgGlobal* globalScope = (*project)[0]->get_globalScope();
     SgSourceFile* sourceFile = isSgSourceFile(project->get_fileList()[0]);
     ROSE_ASSERT(sourceFile != NULL);
     SgGlobal* globalScope = sourceFile->get_globalScope();
     SgFunctionSymbol* snprintf_functionSymbol = globalScope->lookup_function_symbol("snprintf");
     ROSE_ASSERT(snprintf_functionSymbol != NULL);

  // Iterate over the function calls to find the calls to "sprintf"
     for (unsigned long i = 0; i < functionCalls.size(); i++)
        {
          SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(functionCalls[i]);
          ROSE_ASSERT(functionCallExp != NULL);

          SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function());
          if (functionRefExp != NULL)
             {
               SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
               if (functionSymbol != NULL)
                  {
                    SgName functionName = functionSymbol->get_name();
                 // printf ("Function being called: %s \n",functionName.str());
                    if (functionName == "sprintf")
                       {
                      // Now we have something to do!
                         functionRefExp->set_symbol(snprintf_functionSymbol);

                      // Now add the "n" argument
                         SgExprListExp* functionArguments = functionCallExp->get_args();
                         SgExpressionPtrList & functionArgumentList = functionArguments->get_expressions();

                      // "sprintf" shuld have exactly 2 arguments (I guess the "..." don't count)
                         printf ("functionArgumentList.size() = %zu \n",functionArgumentList.size());
                      // ROSE_ASSERT(functionArgumentList.size() == 2);
                         SgExpressionPtrList::iterator i = functionArgumentList.begin();

                      // printf ("(*i) = %p = %s = %s \n",*i,(*i)->class_name().c_str(),SageInterface::get_name(*i).c_str());
                         SgVarRefExp* variableRefExp = isSgVarRefExp(*i);
                         ROSE_ASSERT(variableRefExp != NULL);

                      // printf ("variableRefExp->get_type() = %p = %s = %s \n",variableRefExp->get_type(),variableRefExp->get_type()->class_name().c_str(),SageInterface::get_name(variableRefExp->get_type()).c_str());

                         SgType* bufferType = variableRefExp->get_type();
                         SgExpression* bufferLengthExpression = NULL;
                         switch(bufferType->variantT())
                            {
                              case V_SgArrayType:
                                 {
                                   SgArrayType* arrayType = isSgArrayType(bufferType);
                                   bufferLengthExpression = arrayType->get_index();
                                   break;
                                 }

                              case V_SgPointerType:
                                 {
                                // SgPointerType* pointerType = isSgPointerType(bufferType);
                                   SgInitializedName* variableDeclaration = variableRefExp->get_symbol()->get_declaration();
                                   ROSE_ASSERT(variableDeclaration != NULL);
                                   SgExpression* initializer = variableDeclaration->get_initializer();
                                   if (initializer != NULL)
                                      {
                                        SgAssignInitializer* assignmentInitializer = isSgAssignInitializer(initializer);
                                        ROSE_ASSERT(assignmentInitializer != NULL);

                                     // This is the rhs of the initialization of the pointer (likely a malloc through a cast).
                                     // This assumes: buffer = (char*) malloc(bufferLengthExpression);
                                        SgExpression* initializationExpression = assignmentInitializer->get_operand();
                                        ROSE_ASSERT(initializationExpression != NULL);
                                        SgCastExp* castExp = isSgCastExp(initializationExpression);
                                        ROSE_ASSERT(castExp != NULL);
                                        SgFunctionCallExp* functionCall = isSgFunctionCallExp(castExp->get_operand());
                                        ROSE_ASSERT(functionCall != NULL);
                                        SgExprListExp* functionArguments = isSgExprListExp(functionCall->get_args());
                                        bufferLengthExpression = functionArguments->get_expressions()[0];
                                        ROSE_ASSERT(bufferLengthExpression != NULL);
                                      }
                                     else
                                      {
                                        printf ("Initializer not found, so no value for n in snprintf can be computed currently \n");
                                      }
                                   break;
                                 }

                              default:
                                 {
                                   printf ("Error: default reached in evaluation of buffer type = %p = %s \n",bufferType,bufferType->class_name().c_str());
                                   ROSE_ASSERT(false);
                                 }
                            }

                         ROSE_ASSERT(bufferLengthExpression != NULL);

                      // printf ("bufferLengthExpression = %p = %s = %s \n",bufferLengthExpression,bufferLengthExpression->class_name().c_str(),SageInterface::get_name(bufferLengthExpression).c_str());

                      // Jump over the first argument, the "n" is defined to be the 2nd argument (the rest are shifted one position).
                         i++;

                      // Build a deep copy of the expression used to define the static buffer (could be any complex expression).
                         SgTreeCopy copy_help;
                         SgExpression* bufferLengthExpression_copy = isSgExpression(bufferLengthExpression->copy(copy_help));

                      // Insert the "n" for the parameter list to work with "snprintf" instead of "sprintf"
                         functionArgumentList.insert(i,bufferLengthExpression_copy);
                       }
                  }
             }
        }

     return backend(project);
   }