コード例 #1
0
int main( int argc, char * argv[] )
   {
  // If we want this translator to take specific options (beyond those defined 
  // by ROSE) then insert command line processing for new options here.

  // To better support the stencil specification that might benifit from constant 
  // folding, I have turned this ON is hte frontend.  By default it is OFF so that
  // we can preserve source code as much as possible (original expression trees).
  // The Stencil DSL can be made to work in eithr setting, but this make sure that
  // dimension dependent processing of the stencil coeficients will be evaluated 
  // to constants.  I will turn this off (and thus use a less blunt axe) when the new
  // constant expression evaluation in ROSE is fixed to support more general types
  // than integer expresion (should be done by JP later today).
  // bool frontendConstantFolding = true;
     bool frontendConstantFolding = false;

  // Generate the ROSE AST.
     SgProject* project = frontend(argc,argv,frontendConstantFolding);
     ROSE_ASSERT(project != NULL);

#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
     generateDOT(*project,"_before_transformation");
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 12000;
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before");
#endif

  // Build the inherited attribute
     Detection_InheritedAttribute inheritedAttribute;

  // Define the traversal
     DetectionTraversal shiftCalculus_DetectionTraversal;

#if 0
     printf ("Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
     Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverse(project,inheritedAttribute);
#if 0
     printf ("Stencil Operator was transformed: %s \n",result.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result.get_stencilOperatorTransformed() == false);

#if 0
     printf ("DONE: Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Build the inherited attribute
     StencilEvaluation_InheritedAttribute inheritedAttribute_stencilEval;

  // Define the traversal
     StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal(shiftCalculus_DetectionTraversal);

#if 0
     printf ("Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
     StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverse(project,inheritedAttribute_stencilEval);
#if 0
     printf ("Stencil Evaluation was transformed: %s \n",result_stencilEval.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result_stencilEval.get_stencilOperatorTransformed() == false);

#if 0
     printf ("DONE: Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

     shiftCalculus_StencilEvaluationTraversal.displayStencil("After evaluation of stencil");

#if 1
     printf ("Call generateStencilCode to generate example code \n");
#endif

  // Generate code from stencil data structure.
     bool generateLowlevelCode = true;
     generateStencilCode(shiftCalculus_StencilEvaluationTraversal,generateLowlevelCode);

#if 1
     printf ("DONE: Call generateStencilCode to generate example code \n");
#endif

  // AST consistency tests (optional for users, but this enforces more of our tests)
     AstTests::runAllTests(project);

#if DEBUG_USING_DOT_GRAPHS
     printf ("Write out the DOT file after the transformation \n");
  // generateDOTforMultipleFile(*project,"after_transformation");
     generateDOT(*project,"_after_transformation");
     printf ("DONE: Write out the DOT file after the transformation \n");
#endif
#if DEBUG_USING_DOT_GRAPHS && 0
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
  // const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 10000;
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_after");
#endif

  // Regenerate the source code but skip the call the to the vendor compiler.
     return backend(project);
   }
コード例 #2
0
int main (int argc, char* argv[])
   {
  // Main Function for default example ROSE Preprocessor
  // This is an example of a preprocessor that can be built with ROSE

  // Build the project object (AST) which we will fill up with multiple files and use as a
  // handle for all processing of the AST(s) associated with one or more source files.
     SgProject* sageProject = frontend(argc,argv);

  // DQ (7/20/2004): Added internal consistancy tests on AST
     AstTests::runAllTests(sageProject);

  // This is not needed here
  // FixSgProject(sageProject);

     bool changed = true;
     int  count   = 0;

  /* Inline one call at a time until all have been inlined.  Loops on recursive code. */
     while (changed)
        {
          changed = false;
          calls_to_inline.clear();
          FindCallsVisitor().traverseInputFiles(sageProject, preorder);

          for (std::vector<SgFunctionCallExp*>::iterator i = calls_to_inline.begin(); i != calls_to_inline.end(); ++i)
             {
            // cout << (*i)->unparseToString() << endl;
            // generateAstGraph(sageProject, 400000);
               if (doInline(*i))
                  {
                    changed = true;
                 // AstTests::runAllTests(sageProject);
                    break;
                  }
             }
          ++count;
#if 0
          sageProject.unparse();
#endif
       // To prevent infinite loops
          if (count == 10)
             {
               break;
             }
        }

#if 1

  // Rename each variable declaration
     renameVariables(sageProject);

#if 1
  // Fold up blocks
     flattenBlocks(sageProject);

  // Clean up inliner-generated code
     cleanupInlinedCode(sageProject);
#endif

  // Change members to public
     changeAllMembersToPublic(sageProject);

  // AstPDFGeneration().generateInputFiles(sageProject);
  // AstDOTGeneration().generateInputFiles(sageProject);
#endif

     AstTests::runAllTests(sageProject);

#if 0
  // Output an optional graph of the AST (just the tree, when active)
     printf ("Generating a dot file... (ROSE Release Note: turn off output of dot files before committing code) \n");
     generateDOT (*sageProject );
     // generateAstGraph(project, 2000);
#endif

#if 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 8000;
     generateAstGraph(sageProject,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif


     return backend(sageProject);
   }
コード例 #3
0
//! This removes the original expression tree from value expressions where it has been constant folded by EDG.
void resetConstantFoldedValues( SgNode* node )
   {
  // This is the initial default, it will be changed later to be an optional behavior.
  // Note that all unparsing will use the original expression tree and is verified to generate
  // correct for all of the regression tests in C and C++.  The original expression trees are
  // saved in ROSE as part of supporting source to source work.  One could conclude that the
  // original expression tree should always of never used as part of analysis, but not both
  // the constant folded value AND the original expression tree.

  // This is a temporary option, if false then we pass all tests and are consistent with historical configurations 
  // of the ROSE AST, but it is inconsistent so we want to fix that (because it causes control flow problems).
#if 1
  // DQ (11/5/2012): Original value
     bool makeASTConstantFoldingExpressionConsistant = true;
#else
  // DQ (11/5/2012): An experimental value while I play with the original expression trees.
     bool makeASTConstantFoldingExpressionConsistant = false;
#endif

#if 1
  // This should be turned on except for internal testing.
     ROSE_ASSERT(makeASTConstantFoldingExpressionConsistant == true);
#else
     printf ("WARNING: INTERNAL TESTING MODE: In resetConstantFoldedValues() \n");
     ROSE_ASSERT(makeASTConstantFoldingExpressionConsistant == false);
#endif

  // This will become an input option in the near future.  Once they can be supported through all of the test codes.
  // The default is to use the original expression trees and replace the saved constant folded values in the AST.
  // Note that having both can lead to some confusion (e.g. in the control flow graph and analysis, so we select one
  // (no constant folded values) and make it an option to have the other (using constant folded values)).  Note also
  // This this is EDG's definition of constant folding which is fairly aggressive.
     bool makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = true;

  // Constant folding is optional and can be specified as an optional parameter to "frontend()" function.
  // If set it sets a flag in the SgProject IR node.
     SgProject* project = isSgProject(node);
     if (project != NULL)
        {
       // Read the optional setting for constant folding in the frontend (only applied to C/C++ when using EDG).
          makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = (project->get_frontendConstantFolding() == false);
        }
  // ROSE_ASSERT(project != NULL);
  // printf ("project->get_frontendConstantFolding() = %s \n",(project->get_frontendConstantFolding() == true) ? "true" : "false");

#if 0
  // SgProject* project = isSgProject(node);
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 8000;
     ROSE_ASSERT(project != NULL);
     if (project != NULL)
        {
          printf ("OUTPUT A GRAPH BEFORE CONSTANT FOLDING \n");
          generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before_constantfolding");
        }
#endif

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

     if (makeASTConstantFoldingExpressionConsistant == true)
        {
       // printf ("In resetConstantFoldedValues(): makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = %s \n",makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees ? "true" : "false");

          if (makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees == true)
             {
            // We want this to be the default for ROSE, since it matches what is output by the unparser and thus what 
            // is required to pass all of the tests codes.

            // DQ (9/17/2011): This case fails dozens of test codes!
            // However, this case fails lot of tests codes due to the verification of all OriginalExpressionTree pointer 
            // to be NULL and the name qualification tests (which fail as a result of the transformations to eliminate the 
            // constant folded expressions and instead use the original expression trees).

            // printf ("WARNING: Testing current default to replace constant folded value with the original expression tree (future default setting for ROSE). \n");

            // This replaces the constant folded value with the saved original expression tree (default).
            // This fails for test2011_113.C since we don't handle expressions in array types that contain 
            // original expression trees. The reason is that original expression tree is not used to replace
            // the constant folded value and then (because of recent changes to the AST traversal) the variables
            // in the array types index expression is not processed for name qualification.  
            // We need to either: 
            //    1) uniformly define the how constants are replaced (everywhere) with their original expressions, or
            //    2) fix the name qualification to look into the original expression trees explicitly.
            // or both.
            // Note: If we fix #1 then we will not have to worry about #2, also I think that #1 defines a consistent 
            // AST, where as #2 pushes the name qualification to simple work on the non-consistent AST.
               removeConstantFoldedValue(node);
             }
            else
             {
            // DQ (9/17/2011): This case fails only 2 test codes. Where the constant folded expression is unparsed but 
            // does not generate the correct code.  This may be a separate issue to investigate after we get the original 
            // expression trees to be used (and the constant folding overridden; the other face below).

            // DQ (9/18/2011): Leave this warning message in place for now (we will likely remove it later).
               printf ("WARNING: Current default is to reset constant folding by removing the original expression tree. \n");

            // This removes the original expression tree leaving the constant folded values (optional; not the default).
            // This fails for test2006_112.C (fails to compile unparsed code because the original expression is correct 
            // code (if unparsed) while the constant folded expression is not correct code (if unparsed).  In this case
            // the constant folded values are mostly useful for purposes of analysis.
               removeOriginalExpressionTrees(node);
             }

       // DQ (11/5/2012): I think this should be here rather than outside of this (put it back the way it was).
       // verifyOriginalExpressionTreesSetToNull(node);

       // DQ (4/26/2013): Moved here to permit makeASTConstantFoldingExpressionConsistant == false for debugging.
       // DQ (11/5/2012): Moved to inside of conditional (put this back the way it was).
       // verifyOriginalExpressionTreesSetToNull(node);
        }
       else
        {
       // DQ (4/26/2013): Added warning to support debugging of default argument handling in function call arguments.
          printf ("WARNING: makeASTConstantFoldingExpressionConsistant == false (temporary state for debugging mixed AST with constants and their original expression trees). \n");
        }

  // DQ (4/26/2013): Commented out (see comment above).
  // DQ (11/5/2012): Moved to inside of conditional (put this back the way it was).
     verifyOriginalExpressionTreesSetToNull(node);
   }
コード例 #4
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);
   }