Esempio n. 1
0
  //Replace the unparsing of expanded macro calls with the actual macro call wherever possible
  void unparseMacroCalls(SgNode* searchTree)
  {
    //Traverse AST to find all macro calls and the nodes they are attached to
    findPreprocInfo findPre;
    findPre.traverse(searchTree, preorder);

    std::vector< std::pair<SgNode*, PreprocessingInfo*> >& wherePreprocIsAttached = findPre.wherePreprocIsAttached;

    //Replace expanded macro calls with actual macro call from pre-cpp wherever possible
    for( std::vector< std::pair<SgNode*, PreprocessingInfo*> >::iterator iItr = wherePreprocIsAttached.begin(); 
        iItr != wherePreprocIsAttached.end(); ++iItr)
    {
      SgStatement*       currentNode = isSgStatement( (*iItr).first );
      PreprocessingInfo* curPreproc  = (*iItr).second;

      ROSE_ASSERT(currentNode != NULL);

      std::vector<SgNode*> matchingSubTree;

      if ( matchMacroToSubtrees(currentNode->get_scope(), curPreproc, matchingSubTree) )
      {
        for(unsigned int i = 0; i < matchingSubTree.size(); i++)
        {
          SgLocatedNode* macroNode = isSgLocatedNode(matchingSubTree[i]);
          ROSE_ASSERT(macroNode != NULL);
          std::string replacementString = ( i ==0 ? curPreproc->getString() : "" );

          if( isSgExpression(macroNode) == NULL )
          {
#ifndef USE_ROSE
#ifndef ROSE_SKIP_COMPILATION_OF_WAVE
         // If we are using ROSE to compile ROSE source code then the Wave support is not present.
            PreprocessingInfo::rose_macro_call* macroCall = curPreproc->get_macro_call();

            if(macroCall->expanded_macro.size() > 0 && boost::wave::token_id(macroCall->expanded_macro.back()) != boost::wave::T_COLON)
              replacementString +=";";
#endif
#endif
          }

          std::cout << "Doing line replacement " << macroNode->unparseToString() << " with " << replacementString << std::endl;

#if 0
          std::string pos;
          curPreproc->display(pos);
          std::cout << macroNode->class_name() << " "<<  pos << std::endl;
#endif

          macroNode->addToAttachedPreprocessingInfo(new PreprocessingInfo(PreprocessingInfo::LineReplacement,
                replacementString,macroNode->get_file_info()->get_filenameString(),1,1,1,PreprocessingInfo::before));
        }

        
      };

       

    }
    
  };
/**
 *  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);
}
Esempio n. 3
0
/**
 * Convert for_stmt to a upc_forall statement if it has an affinity exp
 * in the global map.
 */
SgStatement* translate_to_upc(SgForStatement* for_stmt) {
    /* return value is either SgUpcForAllStmt or SgForStmt */
    SgStatement* retval;

    /* translate if the for_stmt was upc_forall stmt */
    aff_map_t::iterator affinity_exp_it = aff_exp_map.find(for_stmt);
    if (affinity_exp_it != aff_exp_map.end()) {

        /* build a new upc_forall statement */
        retval = SageBuilder::buildUpcForAllStatement_nfi(
                for_stmt->get_for_init_stmt(), /* initialize stmt */
                for_stmt->get_test(),          /* condition */
                for_stmt->get_increment(),     /* increment */
                affinity_exp_it->second,       /* affinity */
                for_stmt->get_loop_body()      /* loop body */
                );

        /* set file info */
        Sg_File_Info* old_file_info = for_stmt->get_file_info();
        retval->set_file_info( old_file_info );

    } else {
        /* for_stmt was never a upc_forall stmt */
        retval = for_stmt;
    }

    return retval;
}
Esempio n. 4
0
void visitorTraversal::visit(SgNode* n)
   {
  // There are three types ir IR nodes that can be queried for scope:
  //   - SgStatement, and 
  //   - SgInitializedName
     SgStatement* statement = isSgStatement(n);
     if (statement != NULL)
        {
          SgScopeStatement* scope = statement->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgStatement       = %12p = %30s has scope = %12p = %s (total number = %d) \n",
               statement,statement->class_name().c_str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }

     SgInitializedName* initializedName = isSgInitializedName(n);
     if (initializedName != NULL)
        {
          SgScopeStatement* scope = initializedName->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgInitializedName = %12p = %30s has scope = %12p = %s (total number = %d)\n",
               initializedName,initializedName->get_name().str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }
   }
Esempio n. 5
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;
     }
   }
 }
Esempio n. 6
0
//note that we keep mint for pragma as well 
//#pragma mint for
//#pragma omp for
void MintCudaMidend::replaceMintForWithOmpFor(SgSourceFile* file)
{
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgPragmaDeclaration);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgPragmaDeclaration* node = isSgPragmaDeclaration(*nodeListIterator);
      ROSE_ASSERT(node != NULL);

      //checks if the syntax is correct and the parallel region is followed by 
      //a basic block
      if(MintPragmas::isForLoopPragma(node))
	{
	  SgStatement* loop = getNextStatement(node);
	  ROSE_ASSERT(loop);
	  
	  if(isSgForStatement(loop))
	    {
	      removeStatement(loop);

	      SgOmpForStatement* omp_stmt = new SgOmpForStatement(NULL, loop);
	      setOneSourcePositionForTransformation(omp_stmt);
	      loop->set_parent(omp_stmt);

	      insertStatementAfter(node, omp_stmt);

	    }
	}
    }
}
Esempio n. 7
0
/*
 *  The function
 *      findScope()
 *  takes as a parameter a SgNode* which is a SgStatement*. It returns a SgNodePtrVector of all
 *  preceding scopes the SgStatement is in.
 *
 */
SgNodePtrVector
findScopes (SgNode * astNode)
{
  ROSE_ASSERT (isSgStatement (astNode));

  SgNodePtrVector returnVector;
  SgScopeStatement *currentScope;

  if (isSgScopeStatement (astNode))
    {
      currentScope = isSgScopeStatement (astNode);
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (astNode);
    }
  else
    {
      SgStatement *sageStatement = isSgStatement (astNode);
      ROSE_ASSERT (sageStatement != NULL);
      currentScope = sageStatement->get_scope ();
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (currentScope);
    }

  while (currentScope->variantT () != V_SgGlobal)
    {
      currentScope = currentScope->get_scope ();
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (currentScope);
    }

  //Must also include the Global Scopes of the other files in the project
  if (currentScope->variantT () == V_SgGlobal)
    {
      SgFile *sageFile = isSgFile ((currentScope)->get_parent ());
      ROSE_ASSERT (sageFile != NULL);
      SgProject *sageProject = isSgProject (sageFile->get_parent ());
      ROSE_ASSERT (sageProject != NULL);

      //Get a list of all files in the current project
      const SgFilePtrList& sageFilePtrList = sageProject->get_fileList ();

      //Iterate over the list of files to find all Global Scopes
      SgNodePtrVector globalScopes;
      for (unsigned int i = 0; i < sageFilePtrList.size (); i += 1)
	{
	  const SgSourceFile *sageFile = isSgSourceFile (sageFilePtrList[i]);
	  ROSE_ASSERT (sageFile != NULL);
	  SgGlobal *sageGlobal = sageFile->get_globalScope();
	  ROSE_ASSERT (sageGlobal != NULL);

	  returnVector.push_back (sageGlobal);
	}
    }


  return returnVector;
};
Esempio n. 8
0
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;
   }
Esempio n. 9
0
SgStatement *findSafeInsertPoint(SgNode *node) {
    SgStatement *insertPoint = SageInterface::getEnclosingStatement(node);
    SgStatement *es = isSgExprStatement(insertPoint);
    SgStatement *esParent = es ? isSgStatement(es->get_parent()) : 0;
    if (es && (isSgSwitchStatement(esParent) || isSgIfStmt(esParent))) {
      // Make sure insertion point is outside of the condition of an if-stmt
      // or the selector of a switch-stmt.
      insertPoint = esParent; 
    } else {
      if (esParent) {
        assert(isSgBasicBlock(esParent));
      }
    }
    return insertPoint;
}
Esempio n. 10
0
FrontierDetectionForTokenStreamMapping_InheritedAttribute
FrontierDetectionForTokenStreamMapping::evaluateInheritedAttribute(SgNode* n, FrontierDetectionForTokenStreamMapping_InheritedAttribute inheritedAttribute)
   {
     static int random_counter = 0;

#if 1
  // Ignore IR nodes that are front-end specific (declarations of builtin functions, etc.).
     if (n->get_file_info()->isFrontendSpecific() == false)
        {
          printf ("In FrontierDetectionForTokenStreamMapping::evaluateInheritedAttribute(): n = %p = %s \n",n,n->class_name().c_str());

       // Count the IR nodes traversed so that we can make a subset transformations.
          random_counter++;
        }
#endif

     FrontierDetectionForTokenStreamMapping_InheritedAttribute returnAttribute;

     SgStatement* statement = isSgStatement(n);
  // if (statement != NULL && random_counter > 30 && random_counter < 40)
     if (statement != NULL)
        {
          string name    = "token_frontier";
          string options = "color=\"blue\"";

          if (random_counter > 30 && random_counter < 40)
             {
               printf ("In FrontierDetectionForTokenStreamMapping::evaluateInheritedAttribute(): Mark this statement as a transformation: random_counter = %d statement = %p = %s \n",random_counter,statement,statement->class_name().c_str());

               options = "color=\"red\"";

               returnAttribute.containsFrontier = true;
             }

       // AstAttribute::AttributeNodeInfo* attribute = new FrontierDetectionForTokenStreamMappingAttribute ( (SgNode*) n, name, options);
          AstAttribute* attribute = new FrontierDetectionForTokenStreamMappingAttribute ( (SgNode*) n, name, options);

          statement->setAttribute(name,attribute);
        }

  // return FrontierDetectionForTokenStreamMapping_InheritedAttribute();
     return returnAttribute;
   }
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;
   }
SgIfStmt *
RoseStatementsAndExpressionsBuilder::buildIfStatementWithEmptyElse (
    SgExpression * ifGuard, SgScopeStatement * thenBlock)
{
  using namespace SageBuilder;
  using namespace SageInterface;

  SgStatement * ifGuardStatement = buildExprStatement (ifGuard);

  SgIfStmt * ifStatement = new SgIfStmt (ifGuardStatement, thenBlock, NULL);
  ifStatement->setCaseInsensitive (true);
  ifStatement->set_use_then_keyword (true);
  ifStatement->set_has_end_statement (true);

  setOneSourcePositionForTransformation (ifStatement);

  ifGuardStatement->set_parent (ifStatement);
  thenBlock->set_parent (ifStatement);

  return ifStatement;
}
void getIfConds(SgIfStmt* fixIf, SgScopeStatement* parentScope) {
	SgStatement* conditional = fixIf->get_conditional();
	if (isSgExprStatement(conditional)) {
		SgExpression* expr = isSgExprStatement(conditional)->get_expression();
		std::pair<SgVariableDeclaration*, SgExpression*> pr = SageInterface::createTempVariableForExpression(expr,isSgScopeStatement(fixIf),true);		
		SgInitializedNamePtrList lptr = pr.first->get_variables();
		//std::cout << "lprt size: " << lptr.size() << std::endl;
		ROSE_ASSERT(lptr.size() <= 1);
		SgVarRefExp* varRef = SageBuilder::buildVarRefExp(pr.first);
		SgIntVal* iv = SageBuilder::buildIntVal(0);
		SgNotEqualOp* nop = SageBuilder::buildNotEqualOp(isSgExpression(varRef),isSgExpression(iv)); 
		SgExprStatement* ses = SageBuilder::buildExprStatement(isSgExpression(nop));	
		SageInterface::replaceStatement(conditional,ses);
	
	//SageInterface::moveVariableDeclaration(pr.first, parentScope);
//	SageInterface::appendStatement(pr.first, parentScope);	
	SageInterface::insertStatementBefore(fixIf,pr.first);
	
	std::cout << "conditional type: " << conditional->class_name() << std::endl;
	}
	return;
}	
Esempio n. 14
0
std::map<SgNode*,PreviousAndNextNodeData*>
computePreviousAndNextNodes(SgGlobal* globalScope, std::vector<FrontierNode*> frontierNodes)
   {
  // This is an alternative way to compute the previous/next node map using the token/AST unparsing frontier list directly.

     std::map<SgNode*,PreviousAndNextNodeData*> previousAndNextNodeMap;

     SgStatement* previousNode         = globalScope;
     SgStatement* previousPreviousNode = globalScope;
     for (size_t j = 0; j < frontierNodes.size(); j++)
        {
       // SgStatement* statement = topAttribute.frontierNodes[j];
       // ROSE_ASSERT(statement != NULL);
          FrontierNode* frontierNode = frontierNodes[j];
          ROSE_ASSERT(frontierNode != NULL);
          SgStatement* statement = frontierNode->node;
          ROSE_ASSERT(statement != NULL);
#if 0
          printf (" (%p = %s) ",statement,statement->class_name().c_str());
#endif
          PreviousAndNextNodeData* previousAndNextNodeData = new PreviousAndNextNodeData(previousPreviousNode,statement);
#if 0
          printf ("Building previousAndNextNodeData = %p previousPreviousNode = %p = %s previousNode = %p = %s statement = %p = %s \n",
               previousAndNextNodeData,previousPreviousNode,previousPreviousNode->class_name().c_str(),
               previousNode,previousNode->class_name().c_str(),statement,statement->class_name().c_str());
#endif
       // Insert a element into the map for the current IR node being traversed.
          if (previousNode != NULL)
             {
#if 0
               printf ("Insert previousAndNextNodeData = %p into previousAndNextNodeMap \n",previousAndNextNodeData);
#endif
               previousAndNextNodeMap.insert(std::pair<SgNode*,PreviousAndNextNodeData*>(previousNode,previousAndNextNodeData));
             }
            else
             {
               printf ("WARNING: previousNode == NULL: j = %" PRIuPTR " can't insert entry into previousAndNextNodeMap: statement = %p = %s \n",j,statement,statement->class_name().c_str());
             }

          previousPreviousNode = previousNode;
          previousNode = statement;
        }

  // Handle the last frontier IR node
     if (frontierNodes.empty() == false)
        {
          PreviousAndNextNodeData* previousAndNextNodeData = new PreviousAndNextNodeData(previousPreviousNode,globalScope);

       // Insert a element into the map for the current IR node being traversed.
          previousAndNextNodeMap.insert(std::pair<SgNode*,PreviousAndNextNodeData*>(previousNode,previousAndNextNodeData));
        }

     return previousAndNextNodeMap;
   }
Esempio n. 15
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;

        }
   }
Esempio n. 16
0
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);
        }
   }
in_list
objectsAllocated(SgStatement *statement, StopCond stopCond)
   {

     in_list objs;
     SgStatement *parent;
     do
        {
#if 0
          in_list::iterator startOfCurrent = objs.end();
#endif
          parent = isSgStatement(statement->get_parent());
          //cout << "parent = " << parent << endl;
          ROSE_ASSERT(parent);
          in_list blockObjs = blockObjectsAllocated(parent, statement);
          objs.insert(objs.end(), blockObjs.begin(), blockObjs.end());
#if 0
          switch (parent->variantT())
             {
               case V_SgBasicBlock:
                     {
                       SgBasicBlock *b = isSgBasicBlock(parent);
                       ROSE_ASSERT(b);
                       SgStatementPtrList &stmts = b->get_statements();
                       for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                          {
                            if (*i == statement) break;
                            addStmtVarsIfAny(objs, startOfCurrent, *i);
                          }
                     }
                  break;
               case V_SgForStatement:
                     {
                       SgForStatement *fs = isSgForStatement(parent);
                       SgStatementPtrList &stmts = fs->get_init_stmt();
                       bool done = false;
                       if (!omitInit)
                          {
                            for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                               {
                                 if (*i == statement)
                                    {
                                      done = true;
                                      break;
                                    }
                                 addStmtVarsIfAny(objs, startOfCurrent, *i);
                               }
                          }
                       if (!done)
                          {
                            if (fs->get_test() != statement)
                               {
                                 addStmtVarsIfAny(objs, startOfCurrent, fs->get_test());
                               }
                          }
                     }
                  break;
               default:
                  break;
             }
#endif
          statement = parent;
        } while (!stopCond(parent));
     return objs;
   }
void
FunctionCallNormalization::visit( SgNode *astNode )
   {
     SgStatement *stm = isSgStatement( astNode );

     // visiting all statements which may contain function calls;
     // Note 1: we do not look at the body of loops, or sequences of statements, but only
     // at statements which may contain directly function calls; all other statements will have their component parts visited in turn
     if ( isSgEnumDeclaration( astNode ) || isSgVariableDeclaration( astNode ) || isSgVariableDefinition( astNode ) ||
                               isSgExprStatement( astNode ) || isSgForStatement( astNode ) || isSgReturnStmt( astNode ) ||
                               isSgSwitchStatement( astNode ) )
        {
       // maintain the mappings from function calls to expressions (variables or dereferenced variables)
          map<SgFunctionCallExp *, SgExpression *> fct2Var;

       // list of Declaration structures, one structure per function call
          DeclarationPtrList declarations;
          bool variablesDefined = false;
             
       // list of function calls, in correnspondence with the inForTest list below
          list<SgNode*> functionCallExpList;
          list<bool> inForTest;

          SgForStatement *forStm = isSgForStatement( stm );
          SgSwitchStatement *swStm = isSgSwitchStatement( stm );
          list<SgNode*> temp1, temp2;

       // for-loops and Switch statements have conditions ( and increment ) expressed as expressions
       // and not as standalone statements; this will change in future Sage versions
       // TODO: when for-loops and switch statements have conditions expressed via SgStatements
       // these cases won't be treated separately; however, do-while will have condition expressed via expression
       // so that will be the only exceptional case to be treated separately
          if (forStm != NULL)
             {
            // create a list of function calls in the condition and increment expression
            // the order is important, the condition is evaluated after the increment expression
            // temp1 = FEOQueryForNodes( forStm->get_increment_expr_root(), V_SgFunctionCallExp );
            // temp2 = FEOQueryForNodes( forStm->get_test_expr_root(), V_SgFunctionCallExp );
               temp1 = FEOQueryForNodes( forStm->get_increment(), V_SgFunctionCallExp );
               temp2 = FEOQueryForNodes( forStm->get_test_expr(), V_SgFunctionCallExp );
               functionCallExpList = temp1;
               functionCallExpList.splice( functionCallExpList.end(), temp2 );
             }
            else
             {
               if (swStm != NULL)
                  {
                 // create a list of function calls in the condition in the order of function evaluation
                 // DQ (11/23/2005): Fixed SgSwitchStmt to have SgStatement for conditional.
                 // list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector_root(), V_SgFunctionCallExp );
                    list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector(), V_SgFunctionCallExp );
                    functionCallExpList = temp1;
                  }
                 else
                  {
                 // create a list of function calls in the statement in the order of function evaluation
                    functionCallExpList = FEOQueryForNodes( stm, V_SgFunctionCallExp );
                  }
             }

         // all function calls get replaced: this is because they can occur in expressions (e.g. for-loops)
         // which makes it difficult to build control flow graphs
         if ( functionCallExpList.size() > 0 )
           {
             cout << "--------------------------------------\nStatement ";
             cout << stm->unparseToString() << "\n";;
             
             // traverse the list of function calls in the current statement, generate a structure  Declaration for each call
             // put these structures in a list to be inserted in the code later
             for ( list<SgNode *>::iterator i = functionCallExpList.begin(); i != functionCallExpList.end(); i++ )
               {
                 variablesDefined = true;

                 // get function call exp
                 SgFunctionCallExp *exp = isSgFunctionCallExp( *i );
                 ROSE_ASSERT ( exp );
                 
                 // get type of expression, generate unique variable name
                 SgType *expType = exp->get_type();
                 ROSE_ASSERT ( expType );
                 Sg_File_Info *location = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 ROSE_ASSERT ( location );
                 ostringstream os;
                 os << "__tempVar__" << location;
                 SgName name = os.str().c_str();

                 // replace previous variable bindings in the AST
                 SgExprListExp *paramsList = exp->get_args();
                 SgExpression *function = exp->get_function();
                 ROSE_ASSERT ( paramsList && function );
                 replaceFunctionCallsInExpression( paramsList, fct2Var );
                 replaceFunctionCallsInExpression( function, fct2Var );

                 // duplicate function call expression, for the initialization declaration and the assignment
                 SgTreeCopy treeCopy;
                 SgFunctionCallExp *newExpInit = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpInit );
                 SgFunctionCallExp *newExpAssign = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpAssign );

                 // variables
                 Sg_File_Info *initLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *nonInitLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *assignLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 Declaration *newDecl = new Declaration();
                 SgStatement *nonInitVarDeclaration, *initVarDeclaration, *assignStmt;
                 SgExpression *varRefExp;
                 SgVariableSymbol *varSymbol;
                 SgAssignOp *assignOp;
                 SgInitializedName *initName;

                 bool pointerTypeNeeded = false;

                 // mark whether to replace inside or outside of ForStatement due to the
                 // function call being inside the test or the increment for a for-loop statement
                 // the 'inForTest' list is in 1:1  ordered correpondence with the 'declarations' list
                 if ( forStm )
                   {
        // SgExpressionRoot
                  //   *testExp = isSgForStatement( astNode )->get_test_expr_root(),
                  //   *incrExp = isSgForStatement( astNode )->get_increment_expr_root();
                     SgExpression
                       *testExp = isSgForStatement( astNode )->get_test_expr(),
                       *incrExp = isSgForStatement( astNode )->get_increment();
                     SgNode *up = exp;
                     while ( up && up != testExp && up != incrExp )
                       up = up->get_parent();
                     ROSE_ASSERT ( up );

                     // function call is in the condition of the for-loop
                     if ( up == testExp )
                       inForTest.push_back( true );
                     // function call is in the increment expression
                     else
                       {
                         inForTest.push_back( false );

                         // for increment expressions we need to be able to reassign the return value
                         // of the function; if the ret value is a reference, we need to generate a
                         // pointer of that type (to be able to reassign it later)
                         if ( isSgReferenceType( expType ) )
                           pointerTypeNeeded = true;
                       }
                   }

                 // for do-while statements:  we need to generate declaration of type pointer to be able to have
                 // non-assigned references when looping and assign them at the end of the body of the loop
                 if ( isSgDoWhileStmt( stm->get_parent() ) && isSgReferenceType( expType ) )
                   pointerTypeNeeded = true;

                 // we have a function call returning a reference and we can't initialize the variable
                 // at the point of declaration; we need to define the variable as a pointer
                 if ( pointerTypeNeeded )
                   {
                     // create 'address of' term for function expression, so we can assign it to the pointer
                     SgAddressOfOp *addressOp = new SgAddressOfOp( assignLoc, newExpAssign, expType );

                     // create noninitialized declaration
                     SgType *base = isSgReferenceType( expType )->get_base_type();
                     ROSE_ASSERT( base );
                     SgPointerType *ptrType = SgPointerType::createType( isSgReferenceType( expType )->get_base_type() );
                     ROSE_ASSERT ( ptrType );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, ptrType );

                     // create assignment (symbol, varRefExp, assignment)
                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );

                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );

                     SgPointerDerefExp *ptrDeref= new SgPointerDerefExp( assignLoc, varRefExp, expType );
                     ROSE_ASSERT ( isSgExpression( varRefExp ) && ptrDeref );
                     assignOp = new SgAssignOp( assignLoc, varRefExp, addressOp, ptrType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt &&  nonInitVarDeclaration );
           
                     // we don't need initialized declarations in this case
                     initVarDeclaration = NULL;

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, ptrDeref ) );
                   }
                 else
                   {
                     // create (non- &)initialized declarations, initialized name & symbol
                     SgAssignInitializer *declInit = new SgAssignInitializer( initLoc, newExpInit, expType );
                     ROSE_ASSERT ( declInit );
                     initVarDeclaration = new SgVariableDeclaration ( initLoc, name, expType, declInit );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, expType );
                     ROSE_ASSERT ( initVarDeclaration && nonInitVarDeclaration );

                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );
                     newExpInit->set_parent( initName );
                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );

                     // create variable ref exp
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );
                     ROSE_ASSERT ( isSgVarRefExp( varRefExp ) );

                     // create the assignment
                     assignOp = new SgAssignOp( assignLoc, varRefExp, newExpAssign, expType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt );

                     initVarDeclaration->set_parent( stm->get_parent() );
                     isSgVariableDeclaration( initVarDeclaration )->set_definingDeclaration( isSgDeclarationStatement( initVarDeclaration ) );

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, varRefExp ) );
                   }

                 // save the 'declaration' structure, with all 3 statements and the variable name
                 newDecl->nonInitVarDeclaration = nonInitVarDeclaration;
                 newDecl->initVarDeclaration = initVarDeclaration;
                 newDecl->assignment = assignStmt;
                 newDecl->name = name;
                 nonInitVarDeclaration->set_parent( stm->get_parent() );
                 isSgVariableDeclaration( nonInitVarDeclaration )->set_definingDeclaration( isSgVariableDeclaration( nonInitVarDeclaration ) );
                 assignStmt->set_parent( stm->get_parent() );
                 declarations.push_back( newDecl );
               } // end for
           } // end if  fct calls in crt stmt > 1

         SgScopeStatement *scope = stm->get_scope();
         ROSE_ASSERT ( scope );
         
         // insert function bindings to variables; each 'declaration' structure in the list
         // corresponds to one function call
         for ( DeclarationPtrList::iterator i = declarations.begin(); i != declarations.end(); i++ )
           {
             Declaration *d = *i;
             ROSE_ASSERT ( d && d->assignment && d->nonInitVarDeclaration );

             // if the current statement is a for-loop, we insert Declarations before & in the loop body, depending on the case
             if ( forStm )
               {
                 SgStatement *parentScope = isSgStatement( stm->get_scope() );
                 SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfFor(forStm);
                 ROSE_ASSERT ( !inForTest.empty() && body && parentScope );
                 // SgStatementPtrList &list = body->get_statements();

                 // if function call is in loop condition, we add initialized variable before the loop and at its end
                 // hoist initialized variable declarations outside the loop
                 if ( inForTest.front() )
                   {
                     ROSE_ASSERT ( d->initVarDeclaration );
                     parentScope->insert_statement( stm, d->initVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
                 // function call is in loop post increment so add noninitialized variable decls above the loop
                 else
                   {
                     parentScope->insert_statement( stm, d->nonInitVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }

                 // in a for-loop, always insert assignments at the end of the loop
                 body->get_statements().push_back( d->assignment );
                 d->assignment->set_parent( body );

                 // remove marker
                 inForTest.pop_front();
               }
             else
               {
                 // look at the type of the enclosing scope
                 switch ( scope->variantT() )
                   {

                     // while stmts have to repeat the function calls at the end of the loop;
                     // note there is no "break" statement, since we want to also add initialized
                     // declarations before the while-loop
                   case V_SgWhileStmt:
                     {
                       // assignments need to be inserted at the end of each while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfWhile(isSgWhileStmt( scope ) );
                       ROSE_ASSERT ( body );
                       d->assignment->set_parent( body );
                       body->get_statements().push_back( d->assignment );
                     }

                     // SgForInitStatement has scope SgForStatement, move declarations before the for loop;
                     // same thing if the enclosing scope is an If, or Switch statement
                   case V_SgForStatement:
                   case V_SgIfStmt:
                   case V_SgSwitchStatement:
                     {
                       // adding bindings (initialized variable declarations only, not assignments)
                       // outside the statement, in the parent scope
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->initVarDeclaration, true );\

                       // setting the scope of the initializedName
                       SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );
                     }
                     break;

                     // do-while needs noninitialized declarations before the loop, with assignments inside the loop
                   case V_SgDoWhileStmt:
                     {
                       // adding noninitialized variable declarations before the body of the loop
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->nonInitVarDeclaration, true );

                       // initialized name scope setting
                       SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );

                       // adding assignemts at the end of the do-while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfDoWhile( isSgDoWhileStmt(scope) );
                       ROSE_ASSERT ( body );
                       body->get_statements().push_back( d->assignment );
                       d->assignment->set_parent(body);
                     }
                     break;

                     // for all other scopes, add bindings ( initialized declarations ) before the statement, in the same scope
                   default:
                     scope->insert_statement( stm, d->initVarDeclaration, true );

                     // initialized name scope setting
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( scope->get_scope() );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
               }
           }
         
         // once we have inserted all variable declarations, we need to replace top-level calls in the original statement
         if ( variablesDefined )
           {
             cout << "\tReplacing in the expression " << stm->unparseToString() << "\n";

             // for ForStatements, replace expressions in condition and increment expressions,
             // not in the body, since those get replace later
             if ( forStm )
               {
         // SgExpressionRoot *testExp = forStm->get_test_expr_root(), *incrExp = forStm->get_increment_expr_root();
            SgExpression *testExp = forStm->get_test_expr(), *incrExp = forStm->get_increment();
            replaceFunctionCallsInExpression( incrExp, fct2Var );
            replaceFunctionCallsInExpression( testExp, fct2Var );
               }
             else
               if ( swStm )
             {
            // DQ (11/23/2005): Fixed SgSwitch to permit use of declaration for conditional
            // replaceFunctionCallsInExpression( swStm->get_item_selector_root(), fct2Var );
               replaceFunctionCallsInExpression( swStm->get_item_selector(), fct2Var );
             }
               else
             replaceFunctionCallsInExpression( stm, fct2Var );
           }
       } // end if isSgStatement block
   }
Esempio n. 19
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;
        }
   }
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                    if (className == "sigaction")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;
                              std::string macroString = "#undef sa_handler\n";
                              std::string filenameString = "macro_call_fixupSelfReferentialMacrosInAST";
                              int line_no = 1;
                              int col_no  = 1;
                              int nol     = 1;
                              PreprocessingInfo::RelativePositionType relPos = PreprocessingInfo::before;

                              PreprocessingInfo* macro = new PreprocessingInfo(directiveType,macroString,filenameString,line_no,col_no,nol,relPos);

                           // printf ("Attaching CPP directive %s to IR node %p as attributes. \n",PreprocessingInfo::directiveTypeName(macro->getTypeOfDirective()).c_str(),associatedStatement);
                              associatedStatement->addToAttachedPreprocessingInfo(macro);
#if 0
                              printf ("Exiting as a test! \n");
                              ROSE_ASSERT(false);
#endif
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

   }
void BasicProgmemTransform::insertPreprocessingInfo(const std::string &data) {
	SgGlobal *global = SageInterface::getFirstGlobalScope(project);
	SgStatement *firstDecl = SageInterface::getFirstStatement(global);
	PreprocessingInfo* result = new PreprocessingInfo(PreprocessingInfo::CpreprocessorIncludeDeclaration, data, "Transformation generated",0, 0, 0, PreprocessingInfo::before);
	firstDecl->addToAttachedPreprocessingInfo(result, PreprocessingInfo::after);
}
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;
   }
Esempio n. 23
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

}
Esempio n. 24
0
void MPI_Code_Generator::lower_xomp (SgSourceFile* file)
{
  ROSE_ASSERT(file != NULL);

  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);
    //debug the order of the statements
    //    cout<<"Debug lower_omp(). stmt:"<<node<<" "<<node->class_name() <<" "<< node->get_file_info()->get_line()<<endl;

    switch (node->variantT())
    {
#if 0
      case V_SgOmpParallelStatement:
        {
          // check if this parallel region is under "omp target"
          SgNode* parent = node->get_parent();
          ROSE_ASSERT (parent != NULL);
          if (isSgBasicBlock(parent)) // skip the padding block in between.
            parent= parent->get_parent();
          if (isSgOmpTargetStatement(parent))
            transOmpTargetParallel(node);
          else  
            transOmpParallel(node);
          break;
        }
      case V_SgOmpForStatement:
      case V_SgOmpDoStatement:
        {
          // check if the loop is part of the combined "omp parallel for" under the "omp target" directive
          // TODO: more robust handling of this logic, not just fixed AST form
          bool is_target_loop = false;
          SgNode* parent = node->get_parent();
          ROSE_ASSERT (parent != NULL);
          // skip a possible BB between omp parallel and omp for, especially when the omp parallel has multiple omp for loops 
          if (isSgBasicBlock(parent))
            parent = parent->get_parent();
          SgNode* grand_parent = parent->get_parent();
          ROSE_ASSERT (grand_parent != NULL);

          if (isSgOmpParallelStatement (parent) && isSgOmpTargetStatement(grand_parent) ) 
            is_target_loop = true;

          if (is_target_loop)
          {
            //            transOmpTargetLoop (node);
            // use round-robin scheduler for larger iteration space and better performance
            transOmpTargetLoop_RoundRobin(node);
          }
          else  
          { 
            transOmpLoop(node);
          }
          break;
        }
#endif
    // transform combined "omp target parallel for", represented as separated three directives: omp target, omp parallel, and omp for     
    case V_SgOmpForStatement:
    {
      SgOmpTargetStatement * omp_target; 
      SgOmpParallelStatement*  omp_parallel;
      if (isCombinedTargetParallelFor (isSgOmpForStatement(node),&omp_target, &omp_parallel )) 
      {
        transOmpTargetParallelLoop (isSgOmpForStatement(node));
      }
      break;
    }
    case V_SgOmpTargetStatement:
        {
          SgOmpTargetStatement* t_stmt = isSgOmpTargetStatement(node);
          ROSE_ASSERT (t_stmt != NULL);
          SgStatement* body_stmt = t_stmt->get_body();
          SgBasicBlock * body_block = isSgBasicBlock (body_stmt);
//          transOmpTarget(node);
          if (isMPIAllBegin (t_stmt))
          {
            // move all body statements to be after omp target
            if (body_block != NULL)
            {
              stripOffBasicBlock (body_block, t_stmt);
            }
            else
            {
              //TODO: ideally, the body_stmt should be normalized to be a BB even it is only a single statement
              removeStatement (body_stmt);
              insertStatementAfter (t_stmt, body_stmt, false);
            }
            // remove the pragma stmt after the translation
            removeStatement (t_stmt);
          }
          else if (isMPIMasterBegin (t_stmt))
          {
            transMPIDeviceMaster (t_stmt);
          }
          else
          {
            // other target directive with followed omp parallel for will be handled when parallel for is translated
            // cerr<<"Error. Unhandled target directive:" <<t_stmt->unparseToString()<<endl;
            //ROSE_ASSERT (false);
          }
          break;
        }
     default:
        {
          // do nothing here    
        }
    }// switch

  } // end for 

}
Esempio n. 25
0
ClastToSage::ClastToSage(SgScopeStatement* scopScope,
			 clast_stmt* root,
			 scoplib_scop_p scoplibScop,
			 PolyRoseOptions& options)
{
  //SgScopeStatement* scope = isSgScopeStatement((SgNode*) scoplibScop->usr);
  _polyoptions = options;
  SgScopeStatement* scope = scopScope;
  ROSE_ASSERT(scope);
  m_scopRoot = NULL;
  /// OLD:
  m_scope = scope;
  m_scoplib_scop = scoplibScop;
  m_verbose = _polyoptions.isVerbose();

  // 0- Retrive meta information stored as an annotation of the
  // SageAST root.
  SgStatement* scopRoot = isSgStatement((SgNode*)(scoplibScop->usr));
  ScopRootAnnotation* annot =
    (ScopRootAnnotation*)(scopRoot->getAttribute("ScopRoot"));
  ROSE_ASSERT(annot);
  _fakeSymbolMap = annot->fakeSymbolMap;

  // 1- Collect all iterators in the clast. They are of the from 'cXX'
  // where XX is an integer.
  _scoplibIterators = collectAllIterators(root);

  // 2- Map clast iterator to new variables that does not conflict
  // with existing names, and register the symbols in the symbol
  // table.
  _sageIterators = createNewIterators(_scoplibIterators, scope);

  // 3- Create the basic block containing the transformed scop.
  SgBasicBlock* bb = buildBasicBlock(root);
  // 4- Update the variable scope with the new bb, and insert the
  // declaration statement in the AST.
  std::map<const char*, SgVariableDeclaration*>::iterator iter;
  Rose_STL_Container<SgNode*> varRefs =
    NodeQuery::querySubTree(bb,V_SgVarRefExp);
  for(iter = _sageIterators.begin(); iter != _sageIterators.end(); ++iter)
    {
      // Deal with the symbol tables.
      SgInitializedNamePtrList& l = iter->second->get_variables();
      for (SgInitializedNamePtrList::iterator i = l.begin(); i != l.end(); i++)
	{
	  (*i)->set_scope(bb);
	  SgVariableSymbol* sym = new SgVariableSymbol(*i);
          bb->insert_symbol((*i)->get_name(), sym);
	  // Ugly hack: replace the old symbol with the new entry in
	  // the symbol table.
	  for (Rose_STL_Container<SgNode *>::iterator j = varRefs.begin();
	       j != varRefs.end(); j++)
	    {
	      SgVarRefExp *vRef = isSgVarRefExp((*j));
	      if (vRef->get_symbol()->get_name() == (*i)->get_name())
		vRef->set_symbol(sym);
	    }

	}
      // Insert the declaration statement in the BB.
      bb->prepend_statement(iter->second);
    }

  // Post-process for pragma insertion.
  if (options.getGeneratePragmas())
    insertPragmas(bb);

  m_scopRoot = bb;
}
Esempio n. 26
0
InheritedAttribute
visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute)
   {
    Sg_File_Info* s = n->get_startOfConstruct();
    Sg_File_Info* e = n->get_endOfConstruct();
    Sg_File_Info* f = n->get_file_info();
    for(int x=0; x < inheritedAttribute.depth; ++x) {
        printf(" ");
    }
    if(s != NULL && e != NULL && !isSgLabelStatement(n)) { 
        printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(),  verbose ? n->unparseToString().c_str() : "" );
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
        SgExprStatement * exprStmt = isSgExprStatement(n);
        if(exprStmt != NULL) {
            printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name());           
            SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression());
            if(fcall != NULL) {
               SgExpression * funcExpr = fcall->get_function();
               if(funcExpr != NULL) {
                    printf(" [function expr: %s]", funcExpr->class_name().c_str());
               }
               SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration();
               if(fdecl != NULL) {
                    printf(" [called function: %s]", fdecl->get_name().str());
               }
            }
        }
        if(isSgFunctionDeclaration(n)) {
            printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str());
        }
        SgStatement * sgStmt = isSgStatement(n);
        if(sgStmt != NULL) {
            printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope());
        }
        //SgLabelStatement * lblStmt = isSgLabelStatement(n);
        //if(lblStmt != NULL) {
        //    SgStatement * lblStmt2 = lblStmt->get_statement();
        //}
    } else if (f != NULL) {
		SgInitializedName * iname = isSgInitializedName(n);
		if(iname != NULL) {
            SgType* inameType = iname->get_type();
			printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str());
			SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent());
			if(ds != NULL) {
				if(ds->get_declarationModifier().get_storageModifier().isStatic()) {
					printf(" static");
				}
			}
			
			SgArrayType * art = isSgArrayType(iname->get_type());
			if(art != NULL) {
				printf(" %d", art->get_rank());
			}
			
			printf("]");
            if(isSgAsmDwarfConstruct(n)) {
                printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
            }
            } else {
        	printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : "");
		}
    } else {
        printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : "");
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
    }
    printf(" succ# %lu", n->get_numberOfTraversalSuccessors());
	printf("\n");
     return InheritedAttribute(inheritedAttribute.depth+1);
   }
Esempio n. 27
0
// schroder3 (2016-07-12): Returns the mangled stable/portable scope of the given statement.
//  FIXME: There are some places (see comment below) in the rose mangling which add the address
//  of the AST node to the mangled name. Due to this, this function currently does not return
//  a stable/portable mangled scope in all cases.
string getScopeAsMangledStableString(SgLocatedNode* stmt) {
  SgNode* parent = stmt;
  // Go up in the AST and look for the closest scope of the given statement:
  while((parent = parent->get_parent())) {
    SgStatement* declScope = 0;
    // Look for a FunctionParameterList or a ScopeStatement:
    if(SgFunctionParameterList* functionParams = isSgFunctionParameterList(parent)) {
      // Special case: Function parameter: The scope is
      //  the corresponding function definition/declaration:
      //  Function declaration is enough, because we only need the function
      //  name and types to create the mangled scope.
      declScope = isSgFunctionDeclaration(functionParams->get_parent());
      ROSE_ASSERT(declScope);
    }
    else if(SgScopeStatement* scope = isSgScopeStatement(parent)) {
      declScope = scope;
    }

    if(declScope) {
      // Found the scope of the given statement.

      // In theory it should work by using
      //   return mangleQualifiersToString(declScope);
      //  but there are the following problems in functions that get called by mangleQualifiersToString(...):
      //   1) SgFunctionDeclaration::get_mangled_name() mangles every function with the name "main" (even
      //      those that are not in the global scope) as
      //       main_<address of the AST node>
      //      .
      //   2) SgTemplateArgument::get_mangled_name(...) adds the address of a AST node to the mangled
      //      name if the template argument is a type and it's parent is a SgTemplateInstantiationDecl.
      //  Especially because of the address we can not use this as a portable scope representation.
      //
      // Workaround for 1): Replace the name of every function definition/declaration that has the name "main" and that
      //  is a direct or indirect scope parent of declScope by a temporary name that is different from "main".
      //  Then use mangleQualifiersToString(...) to mangle the scope. Finally, replace occurrences of the
      //  temporary name in the mangled-scope by "main".
      //
      // Workaround for 2): Currently none.

      // Workaround for 1):
      string tempName = string("(]"); // Something that does not appear in a function or operator name.
      SgName tempSgName = SgName(tempName);
      SgName mainSgName = SgName("main");
      vector<SgFunctionDeclaration*> main_func_decls;
      SgStatement* scopeParent = declScope;
      // Collect all functions that have "main" as their name and replace their name
      //  by the temporary name:
      while((scopeParent = scopeParent->get_scope()) && !isSgGlobal(scopeParent)) {
        SgFunctionDefinition* funcDef = isSgFunctionDefinition(scopeParent);
        if(SgFunctionDeclaration* funcDecl = funcDef ? funcDef->get_declaration() :0) {
          if(funcDecl->get_name() == tempSgName) {
            // There is a function whose name contains tempName. The mangled scope
            //  will probably be wrong:
            throw SPRAY::Exception("Found function whose name contains the reserved text \"" + tempName + "\". "
                                   "Mangling of scope is not possible.");
          }
          else if(funcDecl->get_name() == mainSgName) {
            main_func_decls.push_back(funcDecl);
            funcDecl->set_name(tempSgName);
          }
        }
      }

      // Create the mangled-scope:
      string mangled_scope;
      if(SgFunctionDeclaration* fundDecl = isSgFunctionDeclaration(declScope)) {
        // Special case: A function decl node is not a scope statement:
        mangled_scope = fundDecl->get_mangled_name();
      }
      else if(SgScopeStatement* scope = isSgScopeStatement(declScope)) {
        mangled_scope = mangleQualifiersToString(scope);
      }
      else {
        ROSE_ASSERT(false);
      }

      // Replace occurrences of the temporary name in the mangled-scope
      //  by "main" and restore the previous name ("main") of the functions:
      for(vector<SgFunctionDeclaration*>::const_iterator i = main_func_decls.begin();
          i != main_func_decls.end(); ++i
      ) {
          (*i)->set_name(mainSgName);
          size_t start = mangled_scope.find(tempName);
          // TODO: Functions and local classes (and more?) are mangled as L0R, L1R, ... and not with their
          //  scope. Because of that, there is no corresponding temporary name in
          //  the mangled-scope sometimes:
          if(start != string::npos) {
            mangled_scope.replace(start, tempName.length(), string("main"));
          }
      }
      if(mangled_scope.find(tempName) != string::npos) {
        // There is a function whose name contains tempName. Because we abort above if there is such a function
        //  this should not happen.
        ROSE_ASSERT(false);
      }
      return mangled_scope;
    }
  }
  return string("");
}
SgNode*
SourceLocationInheritedAttribute::
getCurrentStatementInScope( SgScopeStatement* targetScope ) const
   {
     ROSE_ASSERT (targetScope != NULL);

#if 1
     printf ("At top of SourceLocationInheritedAttribute::getCurrentStatementInScope(): targetScope = %p targetScope->sage_class_name() = %s \n",
          targetScope,targetScope->sage_class_name());
#endif

     int scopeDepth = -1;
     unsigned int i;

  // Search the scopeList for the target scope. We no longer use the index of the 
  // scope to compute the index into the statement list. This would be complicated 
  // since the lists are different sizes debending on the details of the traversal 
  // of the AST (what is a child vs. what is a new sort of Sage node).
     for (i = 0; i < scopeList.size(); i++)
        {
          ROSE_ASSERT (scopeList[i] != NULL);
          if (scopeList[i] == targetScope)
               scopeDepth = i;
        }

#if 1
  // error checking (redundent with assert below, but provides better user interface) 
  // printf ("scopeDepth = %d \n",scopeDepth);
     if (scopeDepth < 0)
        {
       // Report an error since no scope was found
          printf ("ERROR: target scope was not found targetScope = %p targetScope->unparseToString() = %s \n",
               targetScope,targetScope->unparseToString().c_str());
          ROSE_ABORT();
        }
#endif

     ROSE_ASSERT (scopeDepth >= 0);

  // Now get the depth of the associated target statement
  // int targetStatementDepth = scopeDepth+1;
  // increment depends upon number of functions (could be more than one with local class definitions).
  // int targetStatementDepth = scopeDepth+1;

#if 1
     printf ("In SourceLocationInheritedAttribute::getCurrentStatementInScope(): scopeDepth = %d  scopeList.size()     = %zu \n",scopeDepth,scopeList.size());
     printf ("In SourceLocationInheritedAttribute::getCurrentStatementInScope(): scopeDepth = %d  statementList.size() = %zu \n",scopeDepth,statementList.size());
     printf ("##### Find the associated current statement in the target scope: \n");
#endif

  // If this is not a query about the deepest scope then we can find the current statement 
  // in scopeList by looking at the next scope.  Else we have to look at the last statement in the 
  // statement list (to find the current statement in the deepest (currently local) scope).
     SgStatement* targetStatement = NULL;
     if (scopeDepth < (int)(scopeList.size()-1))
        {
          printf ("     use the NEXT statement in the scope list \n");
#if 0
          targetStatement = scopeList[scopeDepth+1];
#else
       // We need to find the target statement in the targe scope, this might not be in the
       // list of scopes since only some scopes are saved to avoid redundent accumulation of 
       // multiple nodes that can represent only a single scope (e.g. functions).  The scope
       // that we store are not always the ones that represent the first node representing 
       // that scope (e.g. functions). But the targetStaement must be initialized to the 
       // statement that appears in the target scope (because the insertion mechanism requires 
       // this).
          int indexOfTargetStatement = -1;
          for (i = 0; i < statementList.size(); i++)
             {
               ROSE_ASSERT (statementList[i] != NULL);
               if (statementList[i] == targetScope)
                    indexOfTargetStatement = i+1;
             }
          ROSE_ASSERT (indexOfTargetStatement >= 0);
          ROSE_ASSERT (indexOfTargetStatement < (int)statementList.size());
          targetStatement = statementList[indexOfTargetStatement];
#endif
        }
       else
        {
          printf ("     use the LAST statement in the statement list \n");
          targetStatement = *(statementList.rbegin());
        }

     ROSE_ASSERT (targetStatement != NULL);

#if 0
     if (isSgScopeStatement( *(statementList.rbegin()) ) != NULL)
          targetStatementDepth = scopeDepth;
       else
          targetStatementDepth = scopeDepth+1;
#endif

#if 1
     printf ("targetScope     = %p targetScope->sage_class_name()     = %s \n",
          targetScope,targetScope->sage_class_name());
     printf ("targetScope = %p targetScope->unparseToString() = %s \n",
          targetScope,targetScope->unparseToString().c_str());
     printf ("targetStatement = %p targetStatement->sage_class_name() = %s \n",
          targetStatement,targetStatement->sage_class_name());
     printf ("targetStatement = %p targetStatement->unparseToString() = %s \n",
          targetStatement,targetStatement->unparseToString().c_str());
#endif

#if ROSE_INTERNAL_DEBUG
  // Error checking: search for targetStatement within the targetScope
     bool found = false;
     if (targetScope->containsOnlyDeclarations() == true)
        {
          printf ("Looking in a scope containing only declarations ... \n");
          SgDeclarationStatementPtrList & declarationList = targetScope->getDeclarationList();
          ROSE_ASSERT (declarationList.size() > 0);
          SgDeclarationStatementPtrList::iterator j;
          for (j = declarationList.begin(); j != declarationList.end(); j++)
             {
               ROSE_ASSERT ((*j) != NULL);
#if 0
               printf ("Testing against declaration: (*j) = %p (*j)->unparseToString() = %s \n",
                    (*j),(*j)->unparseToString().c_str());
#endif
               if ( (*j) == targetStatement )
                    found = true;
             }
        }
       else
        {
          printf ("Looking in a scope containing any statement nodes ... \n");
          SgStatementPtrList & statementList = targetScope->getStatementList();
          ROSE_ASSERT (statementList.size() > 0);
          SgStatementPtrList::iterator j;
          for (j = statementList.begin(); j != statementList.end(); j++)
             {
               ROSE_ASSERT ((*j) != NULL);
#if 0
               printf ("Testing against statement: (*j) = %p (*j)->unparseToString() = %s \n",
                    (*j),(*j)->unparseToString().c_str());
#endif
               if ( (*j) == targetStatement )
                    found = true;
             }
        }

     if (found == false)
          display("At base of SourceLocationInheritedAttribute::getCurrentStatementInScope()");

     ROSE_ASSERT (found == true);
#endif

#if 0
     printf ("Exiting at base of SourceLocationInheritedAttribute::getCurrentStatementInScope() \n");
     ROSE_ABORT();
#endif

     ROSE_ASSERT (targetStatement != NULL);

     return targetStatement;
   }
Esempio n. 29
0
File: traceCPU.C Progetto: 8l/rose
int main (int argc, char *argv[])
{
   /* indicate whether include files need to be added */
   bool loopTransformApplied = false ;

   /* more bools at top of file... */
   bool withPAPI = false ;
   bool showStats = false ;
   bool enablePostProcessing = false ;

   /***********************************************/
   /* Process command line options                */
   /***********************************************/

   Rose_STL_Container<string> cmdLineArgs =
     CommandlineProcessing::generateArgListFromArgcArgv(argc,argv) ;

   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(s|stats)", true) )
   {
     showStats = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(p|papi)", true) )
   {
     withPAPI = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(l|loops)", true) )
   {
     emitSeqSeg = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "noiter", true) )
   {
     countIters = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "fast", true) )
   {
     fullLoopStat = false ;
     emitSeqSeg   = false ;
     countIters   = false ;
     withPAPI     = false ;
     enablePostProcessing = true ;
   }

   dumpFunc = (showStats ? "ET_LogStats" : "ET_Dump") ;

   /***********************************************/
   /*               Invoke ROSE                   */
   /***********************************************/

   /* build AST */
   SgProject* project = frontend(argc, argv);
   ROSE_ASSERT(project);

   if (project->get_fileList().empty() == false) {

     /* make sure AST is well formed */
     AstTests::runAllTests(project);

     /* set up some needed typedefs for runtime support */

     SgGlobal *globalScope = SageInterface::getFirstGlobalScope(project) ;
     ETtype = buildTypedefDeclaration("ET_Idx_t", buildShortType(), globalScope)->get_type() ;

     /* insert probes into each function in this file */

     Rose_STL_Container<SgNode*> funcDefs =
         NodeQuery::querySubTree(project, V_SgFunctionDefinition) ;

     for (Rose_STL_Container<SgNode*>::iterator f_itr = funcDefs.begin();
                f_itr != funcDefs.end(); ++f_itr)
     {
        SgFunctionDefinition *funcDef = isSgFunctionDefinition(*f_itr) ;
        ROSE_ASSERT(funcDef);

#ifdef ET_DEBUG 
        printf("--- %s ---\n", funcDef->get_qualified_name().str()) ;
#endif

        SgBasicBlock *funcBody = funcDef->get_body() ;
        if (funcBody == NULL)
           continue ;  /* should be impossible to get here... */

        SgFunctionDeclaration *funcDecl = funcDef->get_declaration() ;
        ROSE_ASSERT(funcDecl);

        /* don't transform header file code  */
        if (strstr(funcDecl->get_name().str(), "operator"))
           continue ;

#ifdef ET_DEBUG
        printf("--- %s ---\n", funcDecl->get_name().str()) ;
#endif

        int loopCount = 0 ;  /* used to create local variable names */
        int segCount = 0 ;

        TransformFunction(funcDecl, funcBody, funcBody, &loopCount, &segCount) ;

        if (loopCount != 0)
        {
           loopTransformApplied = true ;
        }
     }

     SgFunctionDeclaration *mainFunc = SageInterface::findMain(project) ;
     if (countIters == false && (loopTransformApplied || mainFunc != NULL)) {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#define ET_NO_COUNT_ITERS 1\n")) ;
     }

     /* files containing at least one loop require run-time support */

     if (loopTransformApplied)
     {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.h\"\n")) ;
     }

     /* fold run-time support code into file containing main() */

     if (mainFunc != NULL)
     {

        SgFunctionDefinition *mainFuncDef = mainFunc->get_definition() ;

        /* include ETrt.c just before main() in this file */
        if (!fullLoopStat) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_SIMPLE_LOOP_STATS 1\n") );
        }
        if (enablePostProcessing) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_POST_PROCESS_SEQ_TO_LOOP 1\n") );
        }
        if (withPAPI) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_PAPI 1\n\n") );
        }
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.c\"\n") );

        if (withPAPI) {
           /* Insert PAPI initialization code at top of main */
           SgBasicBlock *mainBody = mainFuncDef->get_body() ;

           Rose_STL_Container<SgNode*> blockStmts =
               NodeQuery::querySubTree(mainBody, V_SgStatement,
                                       AstQueryNamespace::ChildrenOnly) ;

           for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin();
                   s_itr != blockStmts.end(); ++s_itr)
           {
              SgStatement *stmt = isSgStatement(*s_itr) ;
              ROSE_ASSERT(stmt);

              /* skip variable declarations */
              if (isSgDeclarationStatement(stmt))
                 continue ;

              SgExprStatement *initCall = buildFunctionCallStmt(
                 SgName("ET_Init"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              stmt->get_scope()->insert_statement(stmt, initCall) ;

              break ;
           }
        }

        /* insert finalization code at end of main() */
        Rose_STL_Container<SgNode*> retStmts =
            NodeQuery::querySubTree(mainFunc, V_SgReturnStmt) ;

        if (retStmts.size() > 0)
        {
           for (Rose_STL_Container<SgNode*>::iterator r_itr = retStmts.begin();
                   r_itr != retStmts.end(); ++r_itr)
           {
              SgReturnStmt *ret = isSgReturnStmt(*r_itr) ;
              ROSE_ASSERT(ret);

              SgExprStatement *sanityCall = buildFunctionCallStmt(
                 SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, sanityCall) ;

              SgExprStatement *logStatCall = buildFunctionCallStmt(
                 SgName(dumpFunc), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, logStatCall) ;
           }
        }
        else
        {
           SgExprStatement *sanityCall = buildFunctionCallStmt(
              SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(sanityCall) ;

           SgExprStatement *logStatCall = buildFunctionCallStmt(
              SgName(dumpFunc), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(logStatCall) ;
        }
     }
   }

   /* make sure AST is well formed */
   AstTests::runAllTests(project);

   // generateDOT (*project);

   return backend(project);
}
Esempio n. 30
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();
	  }
      }
      }
}