SgStatement*
returnFirstOrLastStatementFromCurrentFile ( 
     SgStatement* target,
     const SgStatementPtrList & statementList,
     bool findFirstStatement )
   {
  // printf ("Inside of returnFirstOrLastStatement \n");
  // Find the first statement from the current file being processed
     SgStatement* statement = NULL;
     if (findFirstStatement)
        {
          SgStatementPtrList::const_iterator statementIterator = statementList.begin();
          while (statementIterator != statementList.end())
             {
               statement = *statementIterator;
               ROSE_ASSERT (statement != NULL);
               Sg_File_Info* fileInfo = statement->get_file_info();
               ROSE_ASSERT (fileInfo != NULL);
               string filename = fileInfo->get_filename();
               if (filename == ROSE::getFileNameByTraversalBackToFileNode(target))
                  {
                 // printf ("Found the first statement in this file = %s \n",filename.c_str());
                 // printf ("First statement = %s \n",statement->unparseToCompleteString().c_str());
                    break;
                  }
               statementIterator++;
             }
        }
       else
        {
          SgStatementPtrList::const_reverse_iterator statementIterator = statementList.rbegin();
          while (statementIterator != statementList.rend())
             {
               statement = *statementIterator;
               ROSE_ASSERT (statement != NULL);
               Sg_File_Info* fileInfo = statement->get_file_info();
               ROSE_ASSERT (fileInfo != NULL);
               string filename = fileInfo->get_filename();
               if (filename == ROSE::getFileNameByTraversalBackToFileNode(target))
                  {
                 // printf ("Found the last statement in this file = %s \n",filename.c_str());
                 // printf ("First statement = %s \n",statement->unparseToCompleteString().c_str());
                    break;
                  }
               statementIterator++;
             }
        }

     ROSE_ASSERT (statement != NULL);
     return statement;
   }
Beispiel #2
0
 // obtain read or write variables processed by all nested loops, if any
 void getVariablesProcessedByInnerLoops (SgScopeStatement* current_loop_body, bool isRead, std::set<SgInitializedName*>& var_set)
 {
   // AST query to find all loops
   // add all read/write variables into the var_set
   VariantVector vv;
   vv.push_back(V_SgForStatement);  
   vv.push_back(V_SgFortranDo);  
   Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(current_loop_body, vv); 
   for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++)
   {
     SgStatement* loop = isSgStatement(*i);
     if (debug)
       cout<< "Found nested loop at line:"<< loop->get_file_info()->get_line()<<endl;
     std::set<SgInitializedName*> src_var_set ;
     if (isRead)
       src_var_set = LoopLoadVariables[loop];
     else
       src_var_set = LoopStoreVariables[loop];
     std::set<SgInitializedName*>::iterator j; 
     if (debug)
       cout<< "\t Insert processed variable:"<<endl;
     for (j= src_var_set.begin(); j!= src_var_set.end(); j++)
     {
        var_set.insert(*j);
       if (debug)
         cout<< "\t \t "<<(*j)->get_name()<<endl;
     }
   }
 }
/**
 *  handling error occured due to failed assertion
 * this error handler only works during parser phase since it uses
 * Token_t to know the line number

 * TODO: we need to make this function more general
 **/
void 
fortran_error_handler(int signum)
{
  // get the current filename 
  std::string sFilename = getCurrentFilename();
  if (sFilename.size()==0) {
     fprintf(stderr, "ERROR while parsing the source code\n");
  } else {
    
    SgScopeStatement* scope = astScopeStack.front();
    SgStatement* lastStatement = scope;
    SgStatementPtrList statementList = scope->generateStatementList();
    if (statementList.empty() == false)
       {
         lastStatement = statementList.back();
       }
    int lineNumberOfLastStatement = (astScopeStack.empty() == false) ? lastStatement->get_file_info()->get_line() : 0;
    // get the latest token parsed
    if (lineNumberOfLastStatement > 0)
      std::cerr <<"FATAL ERROR in file "<<sFilename<<":"<<lineNumberOfLastStatement<<std::endl;
    else
     std::cerr <<"FATAL ERROR while parsing "<<sFilename<<std::endl;
  }
  fflush(NULL); // flush all stdio
  fortran_error_handler_end();
  exit(-1);
}
PrefixInheritedAttribute
PrefixSuffixGenerationTraversal::evaluateInheritedAttribute (
     SgNode* astNode,
     PrefixInheritedAttribute inputInheritedAttribute )
   {
#if 0
     printf ("!!! In evaluateInheritedAttribute: astNode = %s \n",astNode->sage_class_name());
#endif

     if ( isSgScopeStatement(astNode) != NULL)
        {
//        printf ("Found a new scope! currentScope.size() = %zu \n",currentScope.size());
          stackOfScopes.push(currentScope);

       // empty the current scope stack
          while (currentScope.empty() == false)
               currentScope.pop_front();
        }

     SgStatement* currentStatement = isSgStatement(astNode);
     if ( currentStatement != NULL )
        {
       // printf ("Found a statement! \n");
       // string declarationFilename   = ROSE::getFileName(currentStatement);
          string declarationFilename   = currentStatement->get_file_info()->get_filename();
          string targetFilename        = ROSE::getFileNameByTraversalBackToFileNode(currentStatement);

       // printf ("targetFilename = %s declarationFilename = %s counter = %d (*i)->sage_class_name() = %s \n",
       //      targetFilename.c_str(),declarationFilename.c_str(),counter,(*i)->sage_class_name());

          if ( generateIncludeDirectives == false || declarationFilename == targetFilename )
             {
//             printf ("Found a declaration statement! currentScope.size() = %zu \n",currentScope.size());
               currentScope.push_front(currentStatement);
             }
        }

//   printf ("Leaving evaluateInheritedAttribute() \n");

     return inputInheritedAttribute;
   }
void generateStencilCode(StencilEvaluationTraversal & traversal, bool generateLowlevelCode)
   {
  // Read the stencil and generate the inner most loop AST for the stencil.

  // Note that generateLowlevelCode controls the generation of low level C code using a
  // base pointer to raw memory and linearized indexing off of that pointer.  The
  // alternative is to use the operator[] member function in the RectMDArray class.

  // Example of code that we want to generate:
  // for (j=0; j < source.size(0); j++)
  //    {
  //      int axis_x_size = source.size(0);
  //      for (i=0; i < source.size(0); i++)
  //         {
  //           destination[j*axis_x_size+i] = source[j*axis_x_size+i];
  //         }
  //    }

  // This function genertes the loop nest only:
  //    SgForStatement* buildLoopNest(int stencilDimension, SgBasicBlock* & innerLoopBody)

  // This function generates the statement in the inner most loop body:
  //    SgExprStatement* assembleStencilSubTreeArray(vector<SgExpression*> & stencilSubTreeArray)

  // This function generates the AST representing the stencil points:
  //    SgExpression* buildStencilPoint (StencilOffsetFSM* stencilOffsetFSM, double stencilCoeficient, int stencilDimension, SgVariableSymbol* destinationVariableSymbol, SgVariableSymbol* sourceVariableSymbol)

  // The generated code should be in terms of the operator[]() functions on the 
  // RectMDArray objects.  Likely we have to support a wider range of generated code later.
  //    const RectMDArray<TDest>& a_LOfPhi,
  //    const RectMDArray<TSrc>& a_phi,

  // std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList;
     std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList = traversal.get_stencilOperatorFunctionCallList();
     for (size_t i = 0; i < stencilOperatorFunctionCallList.size(); i++)
        {
          SgFunctionCallExp* functionCallExp = stencilOperatorFunctionCallList[i];
          ROSE_ASSERT(functionCallExp != NULL);

          printf ("processing functionCallExp = %p \n",functionCallExp);

          SgStatement* associatedStatement = TransformationSupport::getStatement(functionCallExp);
          ROSE_ASSERT(associatedStatement != NULL);

          string filename = associatedStatement->get_file_info()->get_filename();
          int lineNumber  = associatedStatement->get_file_info()->get_line();

          printf ("Generating code for stencil operator used at file = %s at line = %d \n",filename.c_str(),lineNumber);

          SgExprListExp* argumentList = functionCallExp->get_args();
          ROSE_ASSERT(argumentList != NULL);

       // There should be four elements to a stencil operator.
          ROSE_ASSERT(argumentList->get_expressions().size() == 4);

       // Stencil
          SgExpression* stencilExpression = argumentList->get_expressions()[0];
          SgVarRefExp* stencilVarRefExp = isSgVarRefExp(stencilExpression);
          ROSE_ASSERT(stencilVarRefExp != NULL);

       // RectMDArray (destination)
          SgExpression* destinationArrayReferenceExpression = argumentList->get_expressions()[1];
          SgVarRefExp* destinationArrayVarRefExp = isSgVarRefExp(destinationArrayReferenceExpression);
          ROSE_ASSERT(destinationArrayVarRefExp != NULL);

       // RectMDArray (source)
          SgExpression* sourceArrayReferenceExpression = argumentList->get_expressions()[2];
          SgVarRefExp* sourceArrayVarRefExp = isSgVarRefExp(sourceArrayReferenceExpression);
          ROSE_ASSERT(sourceArrayVarRefExp != NULL);

       // Box
          SgExpression* boxReferenceExpression = argumentList->get_expressions()[3];
          SgVarRefExp* boxVarRefExp = isSgVarRefExp(boxReferenceExpression);
          ROSE_ASSERT(boxVarRefExp != NULL);

          printf ("DONE: processing inputs to stencil operator \n");

          ROSE_ASSERT(stencilVarRefExp->get_symbol() != NULL);
          SgInitializedName* stencilInitializedName = stencilVarRefExp->get_symbol()->get_declaration();
          ROSE_ASSERT(stencilInitializedName != NULL);

          string stencilName = stencilInitializedName->get_name();

          printf ("stencilName = %s \n",stencilName.c_str());

          std::map<std::string,StencilFSM*> & stencilMap = traversal.get_stencilMap();
          
          ROSE_ASSERT(stencilMap.find(stencilName) != stencilMap.end());

          StencilFSM* stencilFSM = stencilMap[stencilName];
          ROSE_ASSERT(stencilFSM != NULL);

       // DQ (2/8/2015): Moved out of loop.
          int stencilDimension = stencilFSM->stencilDimension();
          ROSE_ASSERT(stencilDimension > 0);

       // These are computed values.
          printf ("Stencil dimension = %d \n",stencilDimension);
          printf ("Stencil width     = %d \n",stencilFSM->stencilWidth());

          std::vector<std::pair<StencilOffsetFSM,double> > & stencilPointList = stencilFSM->stencilPointList;

       // This is the scope where the stencil operator is evaluated.
          SgScopeStatement* outerScope = associatedStatement->get_scope();
          ROSE_ASSERT(outerScope != NULL);

          SgVariableSymbol* indexVariableSymbol_X     = NULL;
          SgVariableSymbol* indexVariableSymbol_Y     = NULL;
          SgVariableSymbol* indexVariableSymbol_Z     = NULL;
          SgVariableSymbol* arraySizeVariableSymbol_X = NULL;
          SgVariableSymbol* arraySizeVariableSymbol_Y = NULL;

          SgVariableSymbol* destinationVariableSymbol = destinationArrayVarRefExp->get_symbol();
          ROSE_ASSERT(destinationVariableSymbol != NULL);
          SgVariableSymbol* sourceVariableSymbol = sourceArrayVarRefExp->get_symbol();
          ROSE_ASSERT(sourceVariableSymbol != NULL);
          SgVariableSymbol* boxVariableSymbol = boxVarRefExp->get_symbol();
          ROSE_ASSERT(boxVariableSymbol != NULL);

       // This can be important in handling of comments and CPP directives.
          bool autoMovePreprocessingInfo = true;

          SgStatement* lastStatement = associatedStatement;
          if (generateLowlevelCode == true)
             {
#if 1
               SgVariableDeclaration* sourceDataPointerVariableDeclaration = buildDataPointer("sourceDataPointer",sourceVariableSymbol,outerScope);
#else
            // Optionally build a pointer variable so that we can optionally support a C style indexing for the DTEC DSL blocks.
               SgExpression* sourcePointerExp = buildMemberFunctionCall(sourceVariableSymbol,"getPointer",NULL,false);
               ROSE_ASSERT(sourcePointerExp != NULL);
               SgAssignInitializer* assignInitializer = SageBuilder::buildAssignInitializer_nfi(sourcePointerExp);
               ROSE_ASSERT(assignInitializer != NULL);

            // Build the variable declaration for the pointer to the data.
               string sourcePointerName = "sourceDataPointer";
               SgVariableDeclaration* sourceDataPointerVariableDeclaration  = SageBuilder::buildVariableDeclaration_nfi(sourcePointerName,SageBuilder::buildPointerType(SageBuilder::buildDoubleType()),assignInitializer,outerScope);
               ROSE_ASSERT(sourceDataPointerVariableDeclaration != NULL);
#endif

            // SageInterface::insertStatementAfter(associatedStatement,forStatementScope,autoMovePreprocessingInfo);
               SageInterface::insertStatementAfter(associatedStatement,sourceDataPointerVariableDeclaration,autoMovePreprocessingInfo);

               SgVariableDeclaration* destinationDataPointerVariableDeclaration = buildDataPointer("destinationDataPointer",destinationVariableSymbol,outerScope);
               SageInterface::insertStatementAfter(sourceDataPointerVariableDeclaration,destinationDataPointerVariableDeclaration,autoMovePreprocessingInfo);

            // Reset the variable symbols we will use in the buildStencilPoint() function.
               sourceVariableSymbol      = SageInterface::getFirstVarSym(sourceDataPointerVariableDeclaration);
               destinationVariableSymbol = SageInterface::getFirstVarSym(destinationDataPointerVariableDeclaration);

               lastStatement = destinationDataPointerVariableDeclaration;
             }

          SgBasicBlock* innerLoopBody = NULL;
       // SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,sourceVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y);
          SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,boxVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y);
          ROSE_ASSERT(innerLoopBody != NULL);

          ROSE_ASSERT(lastStatement != NULL);
          SageInterface::insertStatementAfter(lastStatement,loopNest,autoMovePreprocessingInfo);

       // Mark this as compiler generated so that it will not be unparsed.
          associatedStatement->get_file_info()->setCompilerGenerated();

       // Form an array of AST subtrees to represent the different points in the stencil.
       // vector<SgFunctionCallExp*> stencilSubTreeArray;
          vector<SgExpression*> stencilSubTreeArray;
          for (size_t j = 0; j < stencilPointList.size(); j++)
             {
#if 0
               printf ("Forming stencil point subtree for offsetValues[0] = %3d [1] = %3d [2] = %3d \n",stencilPointList[j].first.offsetValues[0],stencilPointList[j].first.offsetValues[1],stencilPointList[j].first.offsetValues[2]);
#endif
               StencilOffsetFSM* stencilOffsetFSM = &(stencilPointList[j].first);
               double stencilCoeficient           = stencilPointList[j].second;

            // SgFunctionCallExp* stencilSubTree = buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilFSM->stencilDimension());
               SgExpression* stencilSubTree = 
                    buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilDimension,sourceVariableSymbol,
                         indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode);

               ROSE_ASSERT(stencilSubTree != NULL);

               stencilSubTreeArray.push_back(stencilSubTree);
             }

       // Construct the lhs value for the stencil inner loop statement.
          StencilOffsetFSM* stencilOffsetFSM_lhs = new StencilOffsetFSM(0,0,0);
          double stencilCoeficient_lhs = 1.00;
          SgExpression* stencil_lhs = buildStencilPoint(stencilOffsetFSM_lhs,stencilCoeficient_lhs,stencilDimension,destinationVariableSymbol,
                                           indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode);
          ROSE_ASSERT(stencil_lhs != NULL);

       // Assemble the stencilSubTreeArray into a single expression.
          SgExprStatement* stencilStatement = assembleStencilSubTreeArray(stencil_lhs,stencilSubTreeArray,stencilDimension,destinationVariableSymbol);
          SageInterface::appendStatement(stencilStatement,innerLoopBody);
        }
   }
Beispiel #6
0
void MintCudaMidend::lowerMinttoCuda(SgSourceFile* file)
{
  //Searches mint pragmas, and performs necessary transformation
  //We also check the mint pragmas syntactically 
  //At this point, we only care parallel regions and for loops
  //But do not process forloops at this point (note that this is bottom-up)
  //We process forloops when we see a parallel region pragma because they are always
  //inside of a parallel region.
  //TODO: Sometimes a forloop is merged with a parallel region. Need to handle these.

  ROSE_ASSERT(file != NULL);

  //replaces all the occurrences of mint parallel with omp parallel 
  replaceMintParallelWithOmpParallel(file);
  replaceMintForWithOmpFor(file);

  //adds the private and first private into private clause explicitly 
  patchUpPrivateVariables(file);  //uses ROSE's
  patchUpFirstprivateVariables(file); //uses ROSE's

  //insert openmp specific headers
  //insertRTLHeaders(file);

  //check if mint pragma declarations are correct
  mintPragmasFrontendProcessing(file);

  //the map has the mapping from the host variables to device variables
  //where we copy the data
  
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgStatement* node = isSgStatement(*nodeListIterator);
      ROSE_ASSERT(node != NULL);
      switch (node->variantT())
	{
        case V_SgOmpParallelStatement:
          {
	    //first we handle data transfer pragmas
	    MintHostSymToDevInitMap_t hostToDevVars;
	    processDataTransferPragmas(node, hostToDevVars);
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    cout << "  Processing Mint Parallel Statement" << endl << endl;
#endif
	    MintCudaMidend::transOmpParallel(node, hostToDevVars);
            break;
          }
        case V_SgOmpTaskStatement:
          {
            //transOmpTask(node);
            break;
          }
        case V_SgOmpForStatement:
          {
	    //cout << "INFO-mint: Omp For Statement (skipped processing it)" << endl;
	    //LoweringToCuda::transOmpFor(node);
	    //OmpSupport::transOmpFor(node);
            break;
          }
        case V_SgOmpBarrierStatement:
          {
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    cout << "  Processing Omp Barrier Statement" << endl;
#endif
            transOmpBarrierToCudaBarrier(node);
            break;
          }
        case V_SgOmpFlushStatement:
          {
	    cout << "  INFO:Mint: Processing Omp Flush Statement" << endl;
	    transOmpFlushToCudaBarrier(node);
            break;
          }
        case V_SgOmpThreadprivateStatement:
          {
            //transOmpThreadprivate(node);
            break;
          }
	case V_SgOmpTaskwaitStatement:
          {
            //transOmpTaskwait(node);
            break;
          }
        case V_SgOmpSingleStatement:
          {
	    //TODO: we need to check if the loop body becomes a cuda kernel or not. 
	    MintCudaMidend::transOmpSingle(node);
            break;
          }
	case V_SgOmpMasterStatement:
          {
	    //TODO: we need to check if the loop body becomes a cuda kernel or not. 
	    MintCudaMidend::transOmpMaster(node);
            break;
          }
	case V_SgOmpAtomicStatement:
          {
            //transOmpAtomic(node);
            break;
          }
	case V_SgOmpOrderedStatement:
          {
            //transOmpOrdered(node);
            break;
          }
	case V_SgOmpCriticalStatement:
          {
            //transOmpCritical(node);
            break;
          }
        default:
          {
            //This is any other statement in the source code which is not omp pragma
            //cout<< node->unparseToString()<<" at line:"<< (node->get_file_info())->get_line()<<endl;
            // do nothing here    
          }
	}// switch
    } 
#if 0
  //3. Special handling for files with main() 
  // rename main() to user_main()
  SgFunctionDeclaration * mainFunc = findMain(cur_file);
  if (mainFunc) 
    {
      renameMainToUserMain(mainFunc);
    }
#endif

}
Beispiel #7
0
void MintCudaMidend::processLoopsInParallelRegion(SgNode* parallelRegionNode, 
						 MintHostSymToDevInitMap_t hostToDevVars,
						 ASTtools::VarSymSet_t& deviceSyms, 
						 MintSymSizesMap_t& trfSizes,
						 std::set<SgInitializedName*>& readOnlyVars,
						 const SgVariableSymbol* dev_struct)
{
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(parallelRegionNode, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgStatement* node = isSgStatement(*nodeListIterator);
   
      ROSE_ASSERT(node != NULL);
      switch (node->variantT())
        {
        case V_SgOmpForStatement:
          {
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
            cout << "  Processing Omp For Statement" << endl << endl;
#endif
	    //DataTransferSizes::findTransferSizes(node, trfSizes);
	
	    bool isBoundaryCond = LoweringToCuda::isBoundaryConditionLoop(node);
	    
	    SgFunctionDeclaration* kernel;
	
	    MintForClauses_t clauseList; 

	    //kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, readOnlyVars,clauseList, dev_struct) ;  	    
	    kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, clauseList, dev_struct) ;  	    

	    //swap anyways // x swapping is buggy, need to fix that before allowing x as well
	    if(clauseList.chunksize.x == 1 && ( clauseList.chunksize.z != 1 || clauseList.chunksize.y != 1 ))
	      {
		//if(MintOptions::GetInstance()->isSwapOpt())
		CudaOptimizer::swapLoopAndIf(kernel, clauseList);
	      }
	    if (!isBoundaryCond && MintOptions::GetInstance()->optimize())
	      //if (MintOptions::GetInstance()->optimize())
	      {
		cout << "\n\n  INFO:Mint: Optimization is ON. Optimizing ...\n\n" ;

		CudaOptimizer::optimize(kernel, clauseList);
	      } 
	    //  MintTools::printAllStatements(isSgNode(kernel));
	    //MintArrayInterface::linearizeArrays(kernel);
	    break;
          }
	default:
	  {
	    //cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    //cout << "  Currently we only handle for loops" << endl << endl;
	    
	    //do nothing
	    //currently we only handle for loops
	    break;
	  }
	}
    }
  
  
  for (ASTtools::VarSymSet_t::const_iterator i = deviceSyms.begin (); i!= deviceSyms.end (); ++i)
    {     
      SgVariableSymbol* sym= const_cast<SgVariableSymbol*> (*i);

      SgInitializedName* name = sym->get_declaration();
      SgType* type = name->get_type();
     
      if(isSgArrayType(type) || isSgPointerType(type)){
	
	//Check if is of the fields of the struct
	if(hostToDevVars.find(sym) == hostToDevVars.end())
	  {
	    string name_str = name->get_name().str();
	    
	    cerr << "  ERR:Mint: Ooops! Did you forget to insert a copy pragma for the variable ("<< name_str << ") ?"<< endl;
	    cerr << "  ERR:Mint: Please insert the copy pragma and compile again "<< endl;
	    cerr << "  INFO:Mint: Note that copy pragmas should appear right before and after a parallel region" << endl;
	    ROSE_ABORT();
	  }
      }
      }
}
Beispiel #8
0
void
visitorTraversal::visit(SgNode* n)
   {
     SgFile* file = isSgFile(n);
     if (file != NULL)
        {
          filename = file->get_sourceFileNameWithPath();
        }

  // On each statement node and output it's position.
     SgStatement* statement = isSgStatement(n);

     bool outputStatement = (statement != NULL) ? true : false;

  // Check for the statement to exist in the input source file
     outputStatement = outputStatement && (statement->get_file_info()->get_filenameString() == filename);

  // Skip SgGlobal IR nodes
     outputStatement = outputStatement && (isSgGlobal(statement) == NULL);

     if (outputStatement == true)
        {
          AttachedPreprocessingInfoType* comments = statement->getAttachedPreprocessingInfo();

          if (comments != NULL)
             {
            // printf ("Found attached comments (to IR node at %p of type: %s): \n",statement,statement->class_name().c_str());
            // int counter = 0;
               AttachedPreprocessingInfoType::iterator i;
               for (i = comments->begin(); i != comments->end(); i++)
                  {
#if 0
                    printf ("          Attached Comment #%d in file %s (relativePosition=%s): classification %s :\n%s\n",
                         counter++,(*i)->get_file_info()->get_filenameString().c_str(),
                         ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after",
                         PreprocessingInfo::directiveTypeName((*i)->getTypeOfDirective()).c_str(),
                         (*i)->getString().c_str());
#endif

                 // Mark comments and CPP directives a few different colors.
                    int startingLineNumber   = (*i)->get_file_info()->get_line();
                    int startingColumnNumber = (*i)->get_file_info()->get_col();

                 // Subtract 1 from number of lines to avoid over counting the current line.
                    int endingLineNumber = startingLineNumber + ((*i)->getNumberOfLines() - 1);
                    int endingColumnNumber = (*i)->getColumnNumberOfEndOfString();

                    string color = directiveTypeColor((*i)->getTypeOfDirective());
#if 0
                    printf ("%d,%d,%s,%d,%d\n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber);
#endif
                    dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl;
                  }
             }
            else
             {
            // printf ("No attached comments (at %p of type: %s): \n",statement,statement->sage_class_name());
             }

          ROSE_ASSERT(statement->get_startOfConstruct() != NULL);
          int startingLineNumber   = statement->get_startOfConstruct()->get_line();
          int startingColumnNumber = statement->get_startOfConstruct()->get_col();
          if (statement->get_endOfConstruct() == NULL)
             {
               printf ("Error: statement->get_endOfConstruct() == NULL (statement = %p = %s) \n",statement,statement->class_name().c_str());
             }
          ROSE_ASSERT(statement->get_endOfConstruct() != NULL);
          int endingLineNumber     = statement->get_endOfConstruct()->get_line();
          int endingColumnNumber   = statement->get_endOfConstruct()->get_col();

       // Catch errors (likely compiler generate IR node or NULL file)
          if (endingLineNumber == 0)
             {
               endingLineNumber   = startingLineNumber;
               endingColumnNumber = startingColumnNumber;
             }
#if 0
       // Mark all statements blue
          string color = "blue";
          if (isSgScopeStatement(statement) != NULL)
             color = "red";
#else
          string color = nodeColor(statement);
#endif
#if 0
          printf ("%d,%d,%s,%d,%d  %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,statement->class_name().c_str(),statement);
#endif
          dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl;

        }


  // On each statement node and output it's position.
     SgExpression* expression = isSgExpression(n);

     bool outputExpression = (expression != NULL) ? true : false;

  // Check for the statement to exist in the input source file
     outputExpression = outputExpression && (expression->get_file_info()->get_filenameString() == filename);

     if (outputExpression == true)
        {
       // Currently we don't attach comments to expressions (as I recall).
          AttachedPreprocessingInfoType* comments = expression->getAttachedPreprocessingInfo();
          ROSE_ASSERT(comments == NULL);

          ROSE_ASSERT(expression->get_startOfConstruct() != NULL);
          int startingLineNumber   = expression->get_startOfConstruct()->get_line();
          int startingColumnNumber = expression->get_startOfConstruct()->get_col();

       // For expressions I would like to be a bit more tollerant of a few mistakes.
          if (expression->get_endOfConstruct() == NULL)
             {
               printf ("Error: expression->get_endOfConstruct() == NULL (expression = %p = %s) \n",expression,expression->class_name().c_str());
             }
       // ROSE_ASSERT(expression->get_endOfConstruct() != NULL);
          int endingLineNumber     = startingLineNumber;
          int endingColumnNumber   = startingColumnNumber;
          if (expression->get_endOfConstruct() != NULL)
             {
               endingLineNumber     = expression->get_endOfConstruct()->get_line();
               endingColumnNumber   = expression->get_endOfConstruct()->get_col();
             }

       // Catch errors (likely compiler generate IR node or NULL file)
          if (endingLineNumber == 0)
             {
               endingLineNumber   = startingLineNumber;
               endingColumnNumber = startingColumnNumber;
             }

          string color = nodeColor(expression);
#if 0
          printf ("%d,%d,%s,%d,%d  %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,expression->class_name().c_str(),expression);
#endif
          dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl;

        }

  // On each statement node and output it's position.
     SgInitializedName* initializedName = isSgInitializedName(n);

     bool outputInitializedName = (initializedName != NULL) ? true : false;

  // Check for the statement to exist in the input source file
     outputInitializedName = outputInitializedName && (initializedName->get_file_info()->get_filenameString() == filename);

     if (outputInitializedName == true)
        {
       // Currently we don't attach comments to SgInitializedName IR nodes (as I recall).
       // AttachedPreprocessingInfoType* comments = initializedName->getAttachedPreprocessingInfo();
       // ROSE_ASSERT(comments == NULL);

          ROSE_ASSERT(initializedName->get_startOfConstruct() != NULL);
          int startingLineNumber   = initializedName->get_startOfConstruct()->get_line();
          int startingColumnNumber = initializedName->get_startOfConstruct()->get_col();
#if 0
       // For SgInitializedName I would like to be a bit more tollerant of a few mistakes.
          if (initializedName->get_endOfConstruct() == NULL)
             {
               printf ("Note: initializedName->get_endOfConstruct() == NULL is OK (initializedName = %p = %s) \n",initializedName,initializedName->class_name().c_str());
             }
       // ROSE_ASSERT(initializedName->get_endOfConstruct() != NULL);
#endif
          int endingLineNumber     = startingLineNumber;
          int endingColumnNumber   = startingColumnNumber;
          if (initializedName->get_endOfConstruct() != NULL)
             {
               endingLineNumber     = initializedName->get_endOfConstruct()->get_line();
               endingColumnNumber   = initializedName->get_endOfConstruct()->get_col();
             }

       // Catch errors (likely compiler generate IR node or NULL file)
          if (endingLineNumber == 0)
             {
               endingLineNumber   = startingLineNumber;
               endingColumnNumber = startingColumnNumber;
             }

          string color = nodeColor(initializedName);
#if 0
       // This is redundant I/O for debugging.
          printf ("%d,%d,%s,%d,%d  %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,initializedName->class_name().c_str(),initializedName);
#endif
          dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl;

        }
   }
Beispiel #9
0
void 
visitorTraversal::visit(SgNode* n)
   {
     SgStatement* statement = isSgStatement(n);
     if (statement != NULL)
        {
          string filename = statement->get_file_info()->get_filename();

	  // CH (2/1/2010): Get the real filename (not a symlink)
	  if(boost::filesystem::exists(filename))
	     filename = realpath(filename.c_str(), NULL);

       // Skip the case of compiler generated Sg_File_Info objects.
          //if (previousFilename != filename && filename != "compilerGenerated")
          if (previousFilenames.count(filename) == 0 && filename != "compilerGenerated")
             {
#if 0
            // DQ (1/30/2010): Skip the display of output (too much for testing).
               printf ("\n\nfilename = %s statement = %s \n",filename.c_str(),n->class_name().c_str());
#endif

               FileNameClassification classification;
#if 1
            // string sourceDir = "/home/dquinlan/ROSE/roseCompileTree-g++4.2.2/developersScratchSpace/Dan/fileLocation_tests";

            // This causes the path edit distance to be: 4
               //string sourceDir = "/home/dquinlan/ROSE/svn-rose";
				//string sourceDir = "/home/hou1/rose";
				string sourceDir = "/";
				map<string, string> libs;
				libs["/home/hou1/opt/rose"] = "MyRose";
				libs["/home/hou1/opt/boost"] = "MyBoost";
            // This causes the path edit distance to be: 0
               //string sourceDir = "/home/dquinlan/ROSE";

               classification = classifyFileName(filename,sourceDir,libs);
#else
               string home = "/home/dquinlan/";
               string sourceDir = home + "ROSE/svn-rose/";
               classification = classifyFileName("/usr/include/stdio.h",sourceDir);
#endif

               FileNameLocation fileTypeClassification = classification.getLocation();
               FileNameLibrary  libraryClassification  = classification.getLibrary();
               //int pathEditDistance = classification.getDistanceFromSourceDirectory();

#if 1
	       if (fileTypeClassification == FILENAME_LOCATION_UNKNOWN)
	       {
		   cerr << "filename: " << filename << " is classified as UNKNOWN!!!" << endl;
		   ROSE_ASSERT(false);
		   //exit(0);
	       }
	       else
	       {
		   cout << "filename: " << filename << " " << getName(fileTypeClassification) 
		      << " " << libraryClassification << endl; 
	       }
#endif

#if 0
            // DQ (1/30/2010): Skip the display of output (too much for testing).
	       printf ("\n\nfilename: %s\n", filename.c_str());
               printf ("fileTypeClassification = %d \n",fileTypeClassification);
               display(fileTypeClassification,"Display fileTypeClassification");
               printf ("libraryClassification  = %s \n",libraryClassification.c_str());
               //display(libraryClassification,"Display libraryClassification");
               printf ("pathEditDistance       = %d \n",pathEditDistance);
#endif

#if 1
            // DQ (1/30/2010): Skip the display of output (too much for testing).

            // Some of our tests explicitly build a link and this tests that it is correctly identified as a link.
            // printf ("isLink(StringUtility::stripPathFromFileName(filename)) = %s \n",isLink(StringUtility::stripPathFromFileName(filename)) ? "true" : "false");

            // ROSE_ASSERT(isLink(filename) == false);
	       //bool lk = isLink(filename);
               //printf ("isLink(filename) = %s \n",lk ? "true" : "false");

            // DQ (1/30/2010): Added this test.
            // ROSE_ASSERT(islinkOrPartOfLinkedDirectory(filename) == false);
             //  printf ("islinkOrPartOfLinkedDirectory(filename) = %s \n",islinkOrPartOfLinkedDirectory(filename) ? "true" : "false");
#endif
	       previousFilenames.insert(filename);
             }

          //previousFilename = filename;
        }
   }
DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute 
DetectMacroExpansionsToBeUnparsedAsAstTransformations::evaluateSynthesizedAttribute ( 
   SgNode* n, 
   DetectMacroExpansionsToBeUnparsedAsAstTransformationsInheritedAttribute inheritedAttribute, 
   SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute returnAttribute(n);

#if 0
     printf ("In (Detect Transformations in Macro Expansions) evaluateSynthesizedAttribute(): n = %s n->get_containsTransformation() = %s \n",n->class_name().c_str(),n->get_containsTransformation() ? "true" : "false");
#endif

  // DQ (11/8/2015): This has to be moved to after the tokenStreamSequenceMap has been setup since we need that to determine if 
  // IR nodes have a token mapping or not (subparts of macros expansions will not and we need this infor to recognize parts of 
  // the AST that are associated with macro expansions.
  // DQ (11/8/2015): If this has been marked as containing a transformation then check if there is token info for each of the children.
  // If there is not token info for each of the children then this currentStatement (e.g. n) must be marked as a transformation.
  // This case happens when a transformation is done to a child of a statement that is part of a macro.  In this case the parent will
  // have token information which is the macro call, but since there is a transformation, we have to unparse the fully expanded form 
  // of the macro (from the AST), so the whole subtree must be unparsed.  NOTE: this case might be more complex if multiple statements
  // are associated with a macro (so that there is not a single root of the subtree.  I need to build an example of this to better 
  // understand if there is a problem and if so just what would be the best solution.  It will b at least an iterative refinement of
  // this specific problem.  See tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_135.C for an example
  // of this problem.
     if (n->get_containsTransformation() == true)
        {
#if 0
          printf ("Found case of statement marked as containing a transforamtion \n");
#endif
          SgStatement* currentStatement = isSgStatement(n);
#if 0
          if (currentStatement != NULL)
             {
            // printf ("currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str());
               printf ("currentStatement = %s \n",currentStatement->class_name().c_str());
               printf ("   --- currentStatement->isTransformation()    = %s \n",currentStatement->isTransformation() ? "true" : "false");
             }
#endif
       // We have to test for a macro exapansion (will only work on statement level grainularity where parent statement has child statements).
          bool all_children_have_token_info = true;
          for (size_t i = 0; i < synthesizedAttributeList.size(); i++)
             {
               SgStatement* statement = isSgStatement(synthesizedAttributeList[i].node);
               if (statement != NULL)
                  {
#if 0
                 // printf ("(child) statement = %p = %s \n",statement,statement->class_name().c_str());
                    printf ("(child) statement = %s \n",statement->class_name().c_str());
                    printf ("   --- statement->isTransformation()           = %s \n",statement->isTransformation() ? "true" : "false");
                    printf ("   --- statement->get_containsTransformation() = %s \n",statement->get_containsTransformation() ? "true" : "false");
#endif
                 // DQ (11/8/2015): We might need to also check the surrounding white space as well (except that I think this is set later).
                    if (tokenStreamSequenceMap.find(statement) != tokenStreamSequenceMap.end())
                       {
                      // If we have a token mapping then we don't have to do anything.
                         TokenStreamSequenceToNodeMapping* mapping = tokenStreamSequenceMap[statement];
                         ROSE_ASSERT(mapping != NULL);
                       }
                      else
                       {
#if 0
                      // printf ("Parent statement = %p = %s No token stream information found for child statement = %p = %s \n",
                      //      currentStatement,currentStatement->class_name().c_str(),statement,statement->class_name().c_str());
                         printf ("Parent statement = %s No token stream information found for child statement = %s \n",
                              currentStatement->class_name().c_str(),statement->class_name().c_str());
                         printf ("   --- at line: %d \n",statement->get_file_info()->get_line());

                      // When this is a function declaration, try to understand more about it.
                         SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(statement);
                         if (functionDeclaration != NULL)
                            {
                              printf ("   --- functionDeclaration name = %s \n",functionDeclaration->get_name().str());
                            }
#endif
                         all_children_have_token_info = false;
                       }
                  }
             }

          if (currentStatement != NULL && all_children_have_token_info == false)
             {
#if 0
            // printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str());
               printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %s \n",currentStatement->class_name().c_str());
#endif

            // DQ (11/9/2015): Added support for specific scopes where we don't want them the be 
            // unparsed from the token stream when children of them are transformed.
            // DQ (11/8/2015): I think that this should not apply to a SgBasicBlock (for example see 
            // tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_94.C).
            // The reason is that a block is not the same sort for compound statement as a SgForStatement.
            // if (isSgBasicBlock(currentStatement) == NULL)
               bool current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences = 
                    ( (isSgGlobal(currentStatement) != NULL)          || 
                      (isSgBasicBlock(currentStatement) != NULL)      ||
                   // (isSgEnumDefinition(currentStatement) != NULL)  ||
                      (isSgClassDefinition(currentStatement) != NULL) );

               if (current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences == false)
                  {
                 // Mark as a transformation instead of containing a transformation.
                    currentStatement->setTransformation();

                 // We also need to mark this too!
                    currentStatement->setOutputInCodeGeneration();

                 // And reset this to NOT contain a transformation.
                    currentStatement->set_containsTransformation(false);
#if 0
                    printf ("Exiting as a test! \n");
                    ROSE_ASSERT(false);
#endif
                  }
                 else
                  {
#if 0
                 // printf ("This currentStatement = %p = %s is allowed to have a child without a token sequence mapping \n",currentStatement,currentStatement->class_name().c_str());
                    printf ("This currentStatement = %s is allowed to have a child without a token sequence mapping \n",currentStatement->class_name().c_str());
#endif
                  }
             }
#if 0
       // Debugging code.
          if (isSgForStatement(n) != NULL)
             {
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
             }
#endif
        }

     return returnAttribute;
   }
Beispiel #11
0
Datei: options.C Projekt: 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");
   }
IntermediateRepresentationNodeGraph::IntermediateRepresentationNodeGraph(ofstream & inputFile, SgProject* project, const std::vector<VariantT> & inputNodeKindList)
   : file(inputFile), 
     nodeKindList(inputNodeKindList)
   {
     for (size_t i = 0; i < nodeKindList.size(); i++)
        {
          printf ("Adding nodeKindList[%" PRIuPTR "] = %d = %s to nodeKindSet \n",i,Cxx_GrammarTerminalNames[nodeKindList[i]].variant,Cxx_GrammarTerminalNames[nodeKindList[i]].name.c_str());
          include_nodeKindSet.insert(nodeKindList[i]);
        }

  // Build a list of functions within the AST
  // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);
  // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgDeclarationStatement);
     Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgStatement);

  // include_nodeSet.insert(functionDeclarationList.begin(),functionDeclarationList.end());

     int maxNumberOfNodes = 5000;
     int numberOfNodes = (int)functionDeclarationList.size();
     printf ("Number of IR nodes in IntermediateRepresentationNodeGraph = %d \n",numberOfNodes);

#if 1
     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
          SgStatement*            statement           = isSgStatement(*i);
          SgDeclarationStatement* declaration         = isSgDeclarationStatement(*i);
          SgFunctionDeclaration*  functionDeclaration = isSgFunctionDeclaration(*i);

          SgTemplateInstantiationFunctionDecl*  templateInstantiationFunctionDeclaration = isSgTemplateInstantiationFunctionDecl(*i);

       // if (declaration != NULL && declaration->get_file_info()->isCompilerGenerated() == false)
          if (statement != NULL && statement->get_file_info()->isCompilerGenerated() == false)
             {
               include_nodeSet.insert(statement);
             }

          if (templateInstantiationFunctionDeclaration != NULL)
             {
               include_nodeSet.insert(statement);
             }
           
#if 0
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          if (functionDeclaration != NULL)
             {
            // DQ (3/5/2006): Only output the non-compiler generated IR nodes
               if ( (*i)->get_file_info()->isCompilerGenerated() == false)
                  {
                 // output the function number and the name of the function
                    printf ("Function #%2d name is %s at line %d \n",counter++,functionDeclaration->get_name().str(),functionDeclaration->get_file_info()->get_line());
                  }
                 else
                  {
                 // Output something about the compiler-generated builtin functions
                    printf ("Compiler-generated (builtin) function #%2d name is %s \n",counter++,functionDeclaration->get_name().str());
                  }
             }
            else
             {
               SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
               ROSE_ASSERT(declaration != NULL);
               printf ("--- declaration #%2d is: %p = %s \n",counter++,declaration,declaration->class_name().c_str());
             }
#endif
        }
#endif

     if (numberOfNodes <= maxNumberOfNodes)
        {
       // Ouput nodes.
          for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++)
             {
               SgNode* node = *i;
               file << "\"" << StringUtility::numberToString(node) << "\"[" << "label=\"" << node->class_name() << "\\n" << StringUtility::numberToString(node) << "\"];" << endl;
             }

       // Output edges
          for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++)
             {
               SgNode* node = *i;

               std::vector<std::pair<SgNode*,std::string> > listOfIRnodes = node->returnDataMemberPointers();
               std::vector<std::pair<SgNode*,std::string> >::iterator j = listOfIRnodes.begin();
               while (j != listOfIRnodes.end())
                  {
                    if (include_nodeSet.find(j->first) != include_nodeSet.end())
                       {
                         file << "\"" << StringUtility::numberToString(node) << "\" -> \"" << StringUtility::numberToString(j->first) << "\"[label=\"" << j->second << "\"];" << endl;
                       }

                    j++;
                  }
             }
        }
       else
        {
          printf ("WARNING: IntermediateRepresentationNodeGraph is too large to generate: numberOfNodes = %d (max size = %d) \n",numberOfNodes,maxNumberOfNodes);
        }
   }