Exemple #1
0
void
CompassAnalyses::SizeOfPointer::Traversal::
visit(SgNode* node)
   { 
     int starCount;
     SgSizeOfOp *szOf = isSgSizeOfOp(node);
     if(!szOf) return;
     Rose_STL_Container<SgNode*> pointers = NodeQuery::querySubTree(node,V_SgPointerType);
     Rose_STL_Container<SgNode*> deRefs = NodeQuery::querySubTree(node,V_SgPointerDerefExp);
     Rose_STL_Container<SgNode*> varRefs = NodeQuery::querySubTree(node,V_SgVarRefExp);
     for (Rose_STL_Container<SgNode *>::iterator i = varRefs.begin(); i != varRefs.end(); i++)
       {
         SgVarRefExp *vRef = isSgVarRefExp((*i));
         if (!vRef) return;
         SgType *t = vRef->get_type();
         std::string typeName = t->unparseToString();
         //std::cout << countStars(typeName) <<   std::endl;
         starCount = countStars(typeName);
         if (!starCount or
             (starCount == pointers.size() and 
              deRefs.size() == (starCount - 1)))
           {
             //std::cout << "IT'S OK!" << std::endl;
             return;
           }
         
         
       }
     output->addOutput(new CheckerOutput(node));
} //End of the visit function.
Exemple #2
0
bool MintArrayInterface::isStencilArray(std::vector<SgExpression*> expList) 			
{

//takes all the references of an array in a exp list 
//returns if the accesses are to the north, south, east or west
//Assumes arrays are not represented in 1-dim. (do I handle only 2D? )
//Example :expList contains  E[i][j], E[i][j+1], E[i][j-1] then return "yes" it is stencil
//        :expList contains  E[i][j], E[i][j], E[i][j] then return NO.
//we need a better way to determine if an accesses is strided access.
  
  std::vector<SgExpression*>::iterator it; 

  for(it = expList.begin(); it != expList.end(); it++)
    {
      SgExpression* exp = (*it);

      Rose_STL_Container<SgNode*> arrList = NodeQuery::querySubTree(exp, V_SgPntrArrRefExp);
  
      Rose_STL_Container<SgNode*>::iterator arr;
  
      for(arr = arrList.begin(); arr != arrList.end(); arr++)
	{
	  
	  SgExpression* arrayName; 
	  vector<SgExpression*>  subscripts; //first index is i if E[j][i]
	  
	  //index list are from right to left 
	  bool yes = MintArrayInterface::isArrayReference(isSgExpression(*arr), &arrayName, &subscripts);
	  assert(yes);
	  
	  vector<SgExpression*>::iterator indexExp;

	  for(indexExp = subscripts.begin(); indexExp != subscripts.end(); indexExp++)
	    {
	      //looking for minus, plus 1s: i-1, j+1
	      Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(*indexExp, V_SgIntVal);
	      
	      Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(*indexExp, V_SgVarRefExp);

	      //should I check if it is 0 ?
	      if(constExp.size() > 0 && indexVarExp.size()> 0){
		return true;
	      }
	    }

	  int arrayDim = subscripts.size() ;
	  
	  arr = arr + arrayDim - 1;
	  
	}
    }
  return false;
}
int
main ( int argc, char* argv[] )
   {
     ROSE_INITIALIZE;

     if (SgProject::get_verbose() > 0)
          printf ("In preprocessor.C: main() \n");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

     Rose_STL_Container<SgNode*> nodeList;
     nodeList = NodeQuery::querySubTree (project,V_SgForStatement);
     printf ("\nnodeList.size() = %zu \n",nodeList.size());

     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
     while (i != nodeList.end())
        {
          Sg_File_Info & fileInfo = *((*i)->get_file_info());
          printf ("Query node = %p = %s in %s \n ----- at line %d on column %d \n",
              *i,(*i)->sage_class_name(),fileInfo.get_filename(),
               fileInfo.get_line(), fileInfo.get_col());
          i++;
        }

     if (project->get_verbose() > 0)
          printf ("Calling the backend() \n");

     return 0;
   }
Exemple #4
0
void
CommandlineProcessing::addListToCommandLine ( vector<string> & argv , string prefix, Rose_STL_Container<string> argList )
        {
     for (unsigned int i = 0; i < argList.size(); ++i) {
       argv.push_back(prefix + argList[i]);
   }
   }
void
mergeList ( NodeQuerySynthesizedAttributeType & nodeList, const Rose_STL_Container<SgNode*> & localList )
   {
  // Supporting function for querySolverGrammarElementFromVariantVector
     unsigned localListSize = localList.size();
     unsigned nodeListSize  = nodeList.size();
     for (Rose_STL_Container<SgNode*>::const_iterator i = localList.begin(); i != localList.end(); i++)
        {
       // printf ("Adding node to list (%s) \n",(*i)->sage_class_name());
          nodeList.push_back(*i);
        }
     ROSE_ASSERT (nodeList.size() == nodeListSize+localListSize);
   }
int main(int argc, char * argv[])
{
  SgProject *project = frontend (argc, argv);
  SgFunctionDeclaration* func_decl = SageInterface::findDeclarationStatement<SgFunctionDeclaration> 
     (project, "foo", NULL, true);
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(func_decl->get_definition(), V_SgVarRefExp);
  for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++)
  {
    SgVarRefExp *vRef = isSgVarRefExp((*i));
    cout<<"varRefExp: "<< vRef->unparseToString()<<endl;
  }

  // We expect two references 
  // from input_ompVariableCollecting.C
  if (nodeList.size() !=2)
  {
    cerr<<"Error. We should find exactly two variable references."<<endl;
  }
  ROSE_ASSERT (nodeList.size() ==2);

  return backend(project);
}
DeterminismState getExpectation(SgNode *ast, const char *varName)
{
  SgName name(varName);

  Rose_STL_Container<SgNode*> sdNodes = NodeQuery::querySubTree(ast, &name, NodeQuery::VariableDeclarationFromName);
  if (sdNodes.size() != 1) {
    cerr << "Didn't find target variable " << varName << " in list of size " << sdNodes.size() << endl;

    for (Rose_STL_Container<SgNode*>::iterator i = sdNodes.begin(); i != sdNodes.end(); ++i)
      cerr << "\t" << (*(isSgVariableDeclaration(*i)->get_variables().begin()))->get_name().str() << endl;

    return QUESTIONABLE;
  }

  SgNode *nSd = *(sdNodes.begin());
  SgVariableDeclaration *vdSd = dynamic_cast<SgVariableDeclaration *>(nSd);
  if (!vdSd) {
    cerr << "Node wasn't a variable declaration" << endl;
    return QUESTIONABLE;
  }

  SgInitializedName *inSd = vdSd->get_decl_item(name);
  SgAssignInitializer *aiSd = dynamic_cast<SgAssignInitializer*>(inSd->get_initializer());
  if (!aiSd) {
    cerr << "Couldn't pull an assignment initializer out" << endl;
    return QUESTIONABLE;
  }

  SgIntVal *ivSd = dynamic_cast<SgIntVal*>(aiSd->get_operand());
  if (!ivSd) {
    cerr << "Assignment wasn't an intval" << endl;
    return QUESTIONABLE;
  }

  int value = ivSd->get_value();
  return value ? DETERMINISTIC : NONDETERMINISTIC;
}
int main (int argc, char *argv[])
{
  SgProject *project = frontend (argc, argv);

  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(project,V_SgVarRefExp);
  for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++)
  {
    SgVarRefExp *vRef = isSgVarRefExp((*i));
    cout<<"Found a variable reference ! "<<endl;
  }

  ROSE_ASSERT (nodeList.size() != 0);

  return backend (project);
}
int
main ( int argc, char* argv[] )
   {
     ios::sync_with_stdio();     // Syncs C++ and C I/O subsystems!

     if (SgProject::get_verbose() > 0)
          printf ("In preprocessor.C: main() \n");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

  // AST diagnostic tests
     AstTests::runAllTests(const_cast<SgProject*>(project));

  // test statistics
     if (project->get_verbose() > 1)
        {
          cout << AstNodeStatistics::traversalStatistics(project);
          cout << AstNodeStatistics::IRnodeUsageStatistics();
        }

     if (project->get_verbose() > 0)
          printf ("Generate the pdf output of the SAGE III AST \n");
     generatePDF ( *project );

     if (project->get_verbose() > 0)
          printf ("Generate the DOT output of the SAGE III AST \n");
     generateDOT ( *project );

     Rose_STL_Container<SgNode*> nodeList;
  // nodeList = NodeQuery::querySubTree (project,V_SgType,NodeQuery::ExtractTypes);
     nodeList = NodeQuery::querySubTree (project,V_SgForStatement);
     printf ("\nnodeList.size() = %zu \n",nodeList.size());

     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
     while (i != nodeList.end())
        {
          printf ("Query node = %p = %s = %s \n",*i,(*i)->sage_class_name(),(*i)->unparseToString().c_str());
          i++;
        }

     return 0;
   }
void
CommandlineProcessing::addListToCommandLine ( vector<string> & argv , string prefix, Rose_STL_Container<string> argList )
   {
#if 0
     printf ("In addListToCommandLine(): prefix = %s \n",prefix.c_str());
#endif
  // bool outputPrefix = false;
  // for (unsigned int i = 0; i < argList.size(); ++i)
     for (size_t i = 0; i < argList.size(); ++i)
        {
#if 1
       // DQ (1/25/2017): Original version of code (required for C test codes to pass, see C_tests directory).
       // However, this causes a problem for the --edg_parameter support (which is fixed by the code below).
          argv.push_back(prefix + argList[i]);
#else
       // DQ (1/25/2017): Comment this out as a test of C file command line generation to EDG.

       // DQ (1/21/2017): The prefix should only be on the first argument (if it is non-empty).
       // argv.push_back(prefix + argList[i]);
#if 0
          printf ("   argList[%zu] = %s \n",i,argList[i].c_str());
#endif
          if (i == 0 && argList[i].empty() == false)
             {
               argv.push_back(prefix + argList[i]);
               outputPrefix = true;
             }
            else
             {
            // Account for the first entry in the list being empty.
               if (i > 0 && outputPrefix == false && argList[i].empty() == false)
                  {
                    argv.push_back(prefix + argList[i]);
                    outputPrefix = true;
                  }
                 else
                  {
                    argv.push_back(argList[i]);
                  }
             }
#endif
        }
   }
Exemple #11
0
void
CommandlineProcessing::generateArgcArgvFromList ( Rose_STL_Container<string> argList, int & argc, char** & argv )
   {
  // Build the modified argc and argv (returned by reference)
     if (argv != NULL)
        {
           printf ("Error: argv input shoud be NULL! \n");
           ROSE_ABORT();
        }
      
#ifdef _MSC_VER
#define __builtin_constant_p(exp) (0)
#endif
     ROSE_ASSERT (argv == NULL);
     argc = argList.size();
     argv = (char**) malloc ((argc+1) * sizeof(char**));
     ROSE_ASSERT (argv != NULL);
     argv[argc] = NULL;
     for (int i=0; i < argc; i++)
        {
       // DQ (9/25/2007): Moved from std::list to std::vector.
       // string tempString = argList.front();
       // argList.pop_front();
          string tempString = argList[i];
       // argList.erase(argList.begin());

          int length = tempString.length();
          argv[i] = (char*) malloc ((length+1) * sizeof(char));
          strcpy(argv[i],tempString.c_str());
       // printf ("argv[%d] = %s \n",i,argv[i]);
        }

#if 0
     printf ("Modified argv (argc = %d): \n",argc);
     for (int i=0; i < argc; i++)
        {
          printf ("     argv[%d] = %s \n",i,argv[i]);
        }
#endif
   }
int main(int argc, char **argv)
{
  SgProject *project = frontend(argc, argv);

  // Check that the mpi.h included by the program is the hacked
  // version that defines all the constants as int variables, and not
  // as macros
  SgName hacked("MPI_HACKED_HEADER_INCLUDED");
  Rose_STL_Container<SgNode*> vars = NodeQuery::querySubTree(project, &hacked, NodeQuery::VariableDeclarationFromName);
  if (vars.size() != 1) {
    cerr << "You must be using the hacked mpi.h that defines things nicely for this to work!" << endl;
    return 10;
  }

  //  ConstantPropagationAnalysis cp;

  MpiDeterminismAnalysis a;
  MpiDeterminism d = a.traverse(project);

  DeterminismState sourceExpectation = getExpectation(project, "SOURCE_DETERMINISM");
  DeterminismState tagExpectation = getExpectation(project, "TAG_DETERMINISM");
  DeterminismState functionExpectation = getExpectation(project, "FUNCTION_DETERMINISM");

  int incorrect = 0, imprecise = 0;

  cout << "Analysis finds that this program is" << endl;
  report(d.source, sourceExpectation, "sources", incorrect, imprecise);
  report(d.tag, tagExpectation, "tags", incorrect, imprecise);
  report(d.functions, functionExpectation, "functions", incorrect, imprecise);

  cout << "Analysis was precise in " << 3 - incorrect - imprecise 
       << " cases, imprecise in " << imprecise 
       << " cases, and WRONG in " << incorrect << " cases." << endl;

  delete project;

  return incorrect;
}
int main(int argc, char * argv[])

{
  SgProject *project = frontend (argc, argv);
  SgFunctionDeclaration* func = SageInterface::findMain(project);
  ROSE_ASSERT(func != NULL);
  SgBasicBlock* body = func->get_definition()->get_body();
  ROSE_ASSERT(body!= NULL);
  Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(body,V_SgFortranDo);

  for (size_t i=0; i< loops.size(); i++)
  {
    SgFortranDo* cloop = isSgFortranDo(loops[i]);
    ROSE_ASSERT(cloop != NULL);
    bool result=false;
    result = SageInterface::doLoopNormalization(cloop);
    ROSE_ASSERT(result != false);
  }
  // run all tests
  AstTests::runAllTests(project);

  // Generate source code from AST and call the vendor's compiler
  return backend(project);
}
Exemple #14
0
void PolyoptModule::handleModuleOptions(Rose_STL_Container<string> &argStrings) {

	  Rose_STL_Container<std::string> argStringsCopy = argStrings;

	  // 1- Read PoCC options.
	  // Create argv, argc from string argument list, by removing rose/edg
	  // options.
	  SgFile::stripRoseCommandLineOptions (argStringsCopy);
	  SgFile::stripEdgCommandLineOptions (argStringsCopy);
	  int newargc = argStringsCopy.size ();
	  char* newargv[newargc];
	  int i = 0;
	  SgStringList::iterator argIter;
	  for (argIter = argStringsCopy.begin (); argIter != argStringsCopy.end (); ++argIter)
	    newargv[i++] = strdup ((*argIter).c_str ());

	  // 2- Parse PoCC options.
	  PolyRoseOptions polyoptions_ (newargc, newargv);

	  polyoptions = polyoptions_;

	  // 3- Remove PoCC options from arg list.
	  cleanCommandLine(argStrings);
}
void
CompassAnalyses::VariableNameEqualsDatabaseName::Traversal::
visit(SgNode* node)
   { 
     if( isSgAssignInitializer(node) != NULL )
          assignExp = node;
  
     if( isSgAssignOp(node) != NULL )
          assignExp = node; 

     SgFunctionCallExp* funcCall = isSgFunctionCallExp(node);

  // See if we have a dot expression or arrow expression which
  // accesses the desired member function in the class we are looking for.
     if ( funcCall != NULL  )
        {
          SgExpression* funcExp = funcCall->get_function();

          if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) )
             {
               SgBinaryOp*     binOp = isSgBinaryOp(funcExp);
               SgExpression*   rhsOp = binOp->get_rhs_operand();
            // SgExpression*   lhsOp = binOp->get_lhs_operand();
               if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp)  )
                  {
                 // std::cout << "c1\n" ;

                    SgMemberFunctionSymbol*      funcSymbol = funcRef->get_symbol();
                    ROSE_ASSERT(funcSymbol->get_declaration() != NULL);

                 // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C)
                 // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL);
                    if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL)
                       {
                         SgMemberFunctionDeclaration* funcDecl   = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration());
                         ROSE_ASSERT( funcDecl != NULL );

                         SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope());
                         SgClassDeclaration*          clDecl     = isSgClassDeclaration(clDef->get_declaration());  

                      // SgClassDeclaration*          clDecl     = funcDecl->get_associatedClassDeclaration();

                         ROSE_ASSERT( clDecl != NULL );
                         std::string className    = clDecl->get_name().getString();

                         ROSE_ASSERT(funcDecl != NULL);
                         std::string functionName = funcDecl->get_name().getString();
 
                      // If the class is the class we are looking for see if the member function
                      // access is to the member function we are interested in.
                      // std::cout << "className = " << className << std::endl;
                      // std::cout << "functionName = " << functionName << std::endl;

                         if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) )
                            {
                              SgExprListExp*         actualArgs    = funcCall->get_args();
                              SgExpressionPtrList&   actualExpArgs = actualArgs->get_expressions ();

                              ROSE_ASSERT(actualExpArgs.size() == 1);
                              Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal);

                              ROSE_ASSERT( nodeLst.size() > 0);
                              SgStringVal* actualArg = isSgStringVal(*nodeLst.begin());
                              ROSE_ASSERT(actualArg != NULL);

                              std::string  stringArg = actualArg->get_value();

                              std::cout << "arg:" << stringArg << std::endl;

                              std::string varName;

                           // SgInitializedName* initName = NULL; 
                              if ( SgAssignInitializer* assignInit =  isSgAssignInitializer(assignExp) )
                                 {
                                   SgInitializedName* initName = isSgInitializedName(assignInit->get_parent());
                                   ROSE_ASSERT(initName != NULL);
                                 
                                   varName = initName->get_name().getString();
                                 }
                                else
                                 {
                                   if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) )
                                      {
                                        SgExpression*     lhsOp  = assignOp->get_lhs_operand();
                                        SgVarRefExp*      varRef = isSgVarRefExp(lhsOp);
                                        ROSE_ASSERT(varRef!=NULL);
                                        SgVariableSymbol* varSymbol = varRef->get_symbol();
                                        ROSE_ASSERT(varSymbol != NULL);
                                        SgInitializedName* initName = varSymbol->get_declaration();
                                        varName = initName->get_name().getString();
                                      }
                                 }
 
                              if (varName != "")
                                 {
                                // we are only interested in the part of the argument after the last ":"
                                // Database scopes in ALE3D are separated by ":"

                                   size_t posCol = stringArg.find_last_of(':');
                                 
                                   if (posCol != std::string::npos)
                                        stringArg = stringArg.substr(posCol+1);

                                 //Find violations to the rule
                                   if ( stringArg != varName)
                                      {
                                        output->addOutput(new CheckerOutput(assignExp));
                                        std::cout << "violation" << varName << std::endl;
                                      }
                                     else 
                                      {
                                        std::cout << "non=violation" << varName << std::endl;
                                      }
                                 }
                            }
                       }
                  }
             } 
        }
   } // End of the visit function.
Exemple #16
0
Rose_STL_Container<string>
CommandlineProcessing::generateSourceFilenames ( Rose_STL_Container<string> argList, bool binaryMode )
   {
     Rose_STL_Container<string> sourceFileList;

     Rose_STL_Container<string>::iterator i = argList.begin();

  // skip the 0th entry since this is just the name of the program (e.g. rose)
     ROSE_ASSERT(argList.size() > 0);
     i++;

     int counter = 0;
     while ( i != argList.end() )
        {
       // Count up the number of filenames (if it is ZERO then this is likely a 
       // link line called using the compiler (required for template processing 
       // in C++ with most compilers)) if there is at least ONE then this is the 
       // source file.  Currently their can be up to maxFileNames = 256 files 
       // specified.

       // most options appear as -<option>
       // have to process +w2 (warnings option) on some compilers so include +<option>

       // DQ (1/5/2008): Ignore things that would be obvious options using a "-" or "+" prefix.
       // if ( ((*i)[0] != '-') || ((*i)[0] != '+') )
          if ( ((*i)[0] != '-') && ((*i)[0] != '+') )
             {
            // printf ("In CommandlineProcessing::generateSourceFilenames(): Look for file names:  argv[%d] = %s length = %" PRIuPTR " \n",counter,(*i).c_str(),(*i).size());

            // bool foundSourceFile = false;

               if ( isSourceFilename(*i) == false && isExecutableFilename(*i) == true )
                  {
                 // printf ("This is an executable file: *i = %s \n",(*i).c_str());
                 // executableFileList.push_back(*i);
                    sourceFileList.push_back(*i);
                  }
            // PC (4/27/2006): Support for custom source file suffixes
            // if ( isSourceFilename(*i) )
               if ( isObjectFilename(*i) == false && isSourceFilename(*i) == true )
                  {
                 // printf ("This is a source file: *i = %s \n",(*i).c_str());
                 // foundSourceFile = true;
                    sourceFileList.push_back(*i);
                  }
#if 0
               if ( isObjectFilename(*i) )
                  {
                    objectFileList.push_back(*i);
                  }
#endif

             }

       // DQ (12/8/2007): Looking for rose options that take filenames that would accidentally be considered as source files.
          if (isOptionTakingFileName(*i) == true)
             {
            // Jump over the next argument when such options are identified.
               counter++;
               i++;
             }

          counter++;
          i++;
        }

     return sourceFileList;
   }
// Static function (interface function)
ArrayAssignmentStatementQuerySynthesizedAttributeType ArrayAssignmentStatementTransformation::transformation(
		const ArrayStatementQueryInheritedAttributeType & X, SgNode* astNode) {

#if DEBUG
	printf (" Top of ArrayAssignmentStatementTransformation::transformation \n");
#endif

	// This function returns the string representing the array statement transformation
	ROSE_ASSERT (isSgExprStatement(astNode) != NULL);

	// Pass in the ArrayStatementQueryInheritedAttributeType object so
	// that all previously visited scopes can be copied to the new
	// inherited attribute.
	ArrayAssignmentStatementQueryInheritedAttributeType arrayAssignmentStatementQueryInheritedData(X, astNode);
	list<int> & transformationOptions = arrayAssignmentStatementQueryInheritedData.getTransformationOptions();

	// Find all the hints specified as enum values constructor parameters for declarations of
	// variables of type "TransformationAssertion".  The current scope and all parent scopes are
	// searched back to the global scope. (Maybe this should return a value rather than modify a
	// reference parameter???)
	TransformationSupport::getTransformationOptions(astNode, transformationOptions, "TransformationAssertion");

#if DEBUG
	printf(" In ArrayAssignmentStatementTransformation::transformation (Need to handle indexObjectNameStringList) ");
#endif

	// Generate a list of names of variables of type InternalIndex
	// Kamal (07/21/2011) Check later to see if the list is still needed
	Rose_STL_Container < string > indexObjectNameStringList = NameQuery::querySubTree(astNode, "InternalIndex",
			NameQuery::VariableNamesWithTypeName);

	// Now use STL to build a list of unique names
	//indexObjectNameStringList.unique();

	// If Index objects are used in the array statement then we want to use special indexing based
	// substript computation and we need to communicate this to all phases of the transformation
	// (through use of an inherited attribute!).
	// ROSE_ASSERT (arrayAssignmentStatementQueryInheritedData.getUsingIndexObjectsInSubscriptComputation() == FALSE);
	if (indexObjectNameStringList.size() > 0)
		arrayAssignmentStatementQueryInheritedData.setUsingIndexObjectsInSubscriptComputation(true);
	else
		arrayAssignmentStatementQueryInheritedData.setUsingIndexObjectsInSubscriptComputation(false);

	// The dimension of the array statement must be computed on the way down (in the traversal of the AST).
	// This query gets the list of integer associated with the dimension of each array operand (array
	// operands using the doubleArray::operator() member function).

#if DEBUG
	cout << " Checking queryNumberOfArgsInParenthesisOperator " << astNode->unparseToString() << astNode->class_name() << " Variant: " << astNode->variantT() << " " << V_SgExprListExp << " " << V_SgFunctionCallExp << endl;
#endif

	vector<SgFunctionCallExp*> functionExpList = querySubTree<SgFunctionCallExp>(astNode, V_SgFunctionCallExp);
	SgFunctionCallExp* functionCall;
	Rose_STL_Container<int> operandDimensionList;
	for (vector<SgFunctionCallExp*>::iterator iter = functionExpList.begin(); iter != functionExpList.end(); iter++) {
		string operatorName = TransformationSupport::getFunctionName(*iter);

#if DEBUG
		cout << " Arg List Size: " << (*iter)->get_args()->get_expressions().size() << " " << TransformationSupport::getFunctionName ( *iter ) << endl;
#endif

		if (operatorName == "operator()") {
			operandDimensionList.push_back((*iter)->get_args()->get_expressions().size());
			break;
		}
	}

#if DEBUG
	printf(" operandDimensionList size : %d \n", operandDimensionList.size());
#endif

	// If there is no dimension computed for the query then it means that there were no operator()
	// used in which case we have to assume 6D array operations
	int dimensionOfArrayStatement = (operandDimensionList.size() == 0) ? 6 : *(operandDimensionList.begin());

#if DEBUG
	printf("Array statement is %d dimensional \n", dimensionOfArrayStatement);
	printf("arrayAssignmentStatementQueryInheritedData.arrayStatementDimension = %d \n",
			arrayAssignmentStatementQueryInheritedData.arrayStatementDimension);
#endif

	// Make sure that it has the default value before we change it (error checking)
	ROSE_ASSERT (arrayAssignmentStatementQueryInheritedData.arrayStatementDimension == -1);

	// Modify the inherited attribute using the array statement dimension data
	arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined = TRUE;
	arrayAssignmentStatementQueryInheritedData.arrayStatementDimension = dimensionOfArrayStatement;

#if DEBUG
	printf("(after search for array statement dimension = %d) ... \n", dimensionOfArrayStatement);
#endif

	// Build a transformation object so we can setup the accumulatorValue which is not a static data
	// member.  Other transformations which don't use an accumulatorValue attribute don't require this
	// step.
	ArrayAssignmentStatementTransformation transformation;

	// Build a return value for the transformation function
	ArrayAssignmentStatementQuerySynthesizedAttributeType returnArrayStatementTransformation(astNode);

	// WARNING: It is a design problem that we have the dimension set in two locations
	// Set the dimension of the array statement in the array operand database
	transformation.accumulatorValue.operandDataBase.setDimension(dimensionOfArrayStatement);
	ROSE_ASSERT (transformation.accumulatorValue.operandDataBase.getDimension() > 0);

	// Setup the data base with the options specified by the use and extracted from the current scope
	// of the application code.
	transformation.accumulatorValue.operandDataBase.setUserOptimizationAssertions(
			arrayAssignmentStatementQueryInheritedData.transformationOptions);
	ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption >
			ArrayTransformationSupport::UnknownIndexingAccess );

	// Make sure the data base has been setup properly
	ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption >
			ArrayTransformationSupport::UnknownIndexingAccess );
	ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.dimension > -1 );

	// Call the tree traversal mechanism (tree walker)
	returnArrayStatementTransformation = transformation.traverse(astNode, arrayAssignmentStatementQueryInheritedData);

#if DEBUG
	printf ("(after ASSIGNMENT TRANSFORMATION QUERY) ... \n");
#endif

	return returnArrayStatementTransformation;
}
Exemple #18
0
  void instr(SgProject* project, Rose_STL_Container<SgType*> types)
  {
    SgGlobal* global = SI::getFirstGlobalScope(project);
    std::string prefix("rtc_ti_"); //struct prefix
    std::string ti_type_str("struct rtc_typeinfo*");
    SgType* ti_type = SB::buildOpaqueType(ti_type_str,global);

    //Insert declarations from the typechecking library.

    //void minalloc_check(unsigned long long addr)
    SgFunctionDeclaration* minalloc_check_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("minalloc_check"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType())),
          global,NULL);
    SI::prependStatement(minalloc_check_decl,global);

    //void typetracker_add(unsigned long long addr, struct rtc_typeinfo* ti);
    SgFunctionDeclaration* typetracker_add_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("typetracker_add"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType()),
            SB::buildInitializedName("ti",ti_type)),
          global,NULL);
    SI::prependStatement(typetracker_add_decl,global);

    //void setBaseType(rtc_typeinfo* ti, rtc_typeinfo* base)
    SgFunctionDeclaration* setBaseType_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("setBaseType"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("ti",ti_type),
            SB::buildInitializedName("base",ti_type)),
          global,NULL);
    SI::prependStatement(setBaseType_decl,global);

    //struct rtc_typeinfo* ti_init(const char* a, size_t sz, int c)
    SgFunctionDeclaration* ti_init_decl = SB::buildNondefiningFunctionDeclaration(
                                            SgName("ti_init"),
                                            ti_type,
                                            SB::buildFunctionParameterList(
//    SB::buildInitializedName("a",SB::buildPointerType(SB::buildConstType(SB::buildCharType()))),
                                                SB::buildInitializedName("a",SB::buildPointerType(SB::buildCharType())),
//    SB::buildInitializedName("sz", SB::buildOpaqueType("size_t",global)),
                                                SB::buildInitializedName("sz", SB::buildLongLongType()),
                                                SB::buildInitializedName("c", SB::buildIntType())),
                                            global,NULL);
    SI::prependStatement(ti_init_decl,global);

    //void traverseAndPrint()
    SgFunctionDeclaration* traverseAndPrint_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("traverseAndPrint"),SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(traverseAndPrint_decl,global);

    //non-defining declaration of rtc_init_typeinfo
    SgName init_name("rtc_init_typeinfo");
    SgFunctionDeclaration* init_nondef = SB::buildNondefiningFunctionDeclaration(init_name,SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(init_nondef,global);

    //call to rtc_init_typeinfo placed in main function.
    SgFunctionDeclaration* maindecl = SI::findMain(project);
    SgExprStatement* initcall = SB::buildFunctionCallStmt(init_name,SgTypeVoid::createType(),NULL,maindecl->get_definition());
    maindecl->get_definition()->prepend_statement(initcall);

    //defining declaration of rtc_init_typeinfo
    SgFunctionDeclaration* init_definingDecl = new SgFunctionDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_name,init_nondef->get_type(),NULL);
    init_definingDecl->set_firstNondefiningDeclaration(init_nondef);
    SgFunctionDefinition* init_definition = new SgFunctionDefinition(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_definingDecl,SB::buildBasicBlock());
    init_definingDecl->set_definition(init_definition);
    SI::appendStatement(init_definingDecl,global);

    std::vector<std::string> lst;
    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];

      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string nameStr = prefix + Util::getNameForType(ptr).getString();
      if(!contains(lst,nameStr))
      {
        SgVariableDeclaration* decl = SB::buildVariableDeclaration(nameStr,ti_type,NULL,global);
        SI::prependStatement(decl,global);
        lst.push_back(nameStr);
      }
    }

    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];
      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string typeNameStr = Util::getNameForType(ptr).getString();
      std::string structNameStr = prefix + Util::getNameForType(ptr).getString();

      if(contains(lst,structNameStr))
      {
        SgExpression* lhs;
        SgExpression* rhs;

        //In case of an anonymous struct or union, we create a local, named version of the declaration so we can know its size.
        SgClassDeclaration* altDecl = NULL;
        if(isSgNamedType(ptr) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration())->get_isUnNamed())
        {
          SgClassDeclaration* originalDecl = isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()->get_definingDeclaration());
          SgName altDecl_name(typeNameStr + "_def");
          altDecl = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          SgClassDefinition* altDecl_definition = SB::buildClassDefinition(altDecl);

          SgDeclarationStatementPtrList originalMembers = originalDecl->get_definition()->get_members();
          for(SgDeclarationStatementPtrList::iterator it = originalMembers.begin(); it != originalMembers.end(); it++)
          {
            SgDeclarationStatement* member = *it;
            SgDeclarationStatement* membercpy = isSgDeclarationStatement(SI::copyStatement(member));
            altDecl_definition->append_member(membercpy);
          }


          SgClassDeclaration* altDecl_nondef = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          altDecl_nondef->set_scope(global);
          altDecl->set_scope(global);

          altDecl->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl_nondef->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl->set_definingDeclaration(altDecl);
          altDecl_nondef->set_definingDeclaration(altDecl);


          SgClassType* altDecl_ct = SgClassType::createType(altDecl_nondef);
          altDecl->set_type(altDecl_ct);
          altDecl_nondef->set_type(altDecl_ct);

          altDecl->set_isUnNamed(false);
          altDecl_nondef->set_isUnNamed(false);

          altDecl_nondef->set_forward(true);

          SgSymbol* sym = new SgClassSymbol(altDecl_nondef);
          global->insert_symbol(altDecl_name, sym);

          altDecl->set_linkage("C");
          altDecl_nondef->set_linkage("C");

          ROSE_ASSERT(sym && sym->get_symbol_basis() == altDecl_nondef);
          ROSE_ASSERT(altDecl->get_definingDeclaration() == altDecl);
          ROSE_ASSERT(altDecl->get_firstNondefiningDeclaration() == altDecl_nondef);
          ROSE_ASSERT(altDecl->search_for_symbol_from_symbol_table() == sym);
          ROSE_ASSERT(altDecl->get_definition() == altDecl_definition);
          ROSE_ASSERT(altDecl->get_scope() == global && altDecl->get_scope() == altDecl_nondef->get_scope());
          ROSE_ASSERT(altDecl_ct->get_declaration() == altDecl_nondef);

          //For some reason, this is not working...

          //global->append_statement(altDecl);
          //global->prepend_statement(altDecl_nondef);

          //SI::setOneSourcePositionForTransformation(altDecl);
          //SI::setOneSourcePositionForTransformation(altDecl_nondef);
        }

        SgType* baseType;
        if(isSgPointerType(ptr))
          baseType = ptr->dereference();
        else
          baseType = ptr->findBaseType();

        baseType = baseType->stripTypedefsAndModifiers();
        if(baseType == NULL || baseType == ptr)
        {
          //In this case, there is no base type.
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),SgTypeVoid::createType(),SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);
        }
        else
        {
          //The type has a base type.
          std::string baseStructNameStr = prefix + Util::getNameForType(baseType).getString();
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),ti_type,SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);

          SgExprStatement* set_BT = SB::buildFunctionCallStmt(SgName("setBaseType"),ti_type,SB::buildExprListExp(
                                      SB::buildVarRefExp(structNameStr),
                                      SB::buildVarRefExp(baseStructNameStr)),
                                    init_definition);
          init_definition->append_statement(set_BT);
        }
        lhs = SB::buildVarRefExp(structNameStr);


        SgExprStatement* assignstmt = SB::buildAssignStatement(lhs,rhs);
        init_definition->prepend_statement(assignstmt);
        std::remove(lst.begin(),lst.end(),structNameStr);

      }



    }
  }
Exemple #19
0
Rose_STL_Container<SgNode*> NodeQuery::generateListOfTypes ( SgNode* astNode )
{
  // Insert your own manipulation of the AST here...
#if 0
  printf ("\n\n");
  printf ("************************** \n");
  printf ("Generate list of types ... \n");
#endif

  Rose_STL_Container<SgNode*> nodeList;

  // if (isSgProject(astNode) != NULL || (isSgFile(astNode) != NULL && SgProject::numberOfFiles() == 1) )
  // if (isSgProject(astNode) != NULL)
  bool useMemoryPool = (isSgProject(astNode) != NULL);
  if (useMemoryPool == false)
  {
    // Check if this is a SgFile or SgGlobal where there is only a single SgFile in the SgProject!
    if (isSgFile(astNode) != NULL || isSgGlobal(astNode) != NULL)
    {
   // DQ (1/25/2011): We want to be able to use this functionality, it is not depreicated...
   // printf ("This is not a SgProject, but it is a SgFile or SgGlobal so check if this is an only file before using the memory pool! \n");
      SgProject* project = TransformationSupport::getProject(astNode);

      // 2nd chance to reset useMemoryPool and provide an optimized query for types!
      useMemoryPool = (project->numberOfFiles() == 1);
    }
  }

  if (useMemoryPool == true)
  {
    // Then just query the memory pool and provide a much faster query.
    // printf ("Using memory pool access to type information ... \n");

    TypeQueryDummyFunctionalTest funcTest;

    // Build the list of all IR node variants that are derived from SgType (including SgType)
    VariantVector ir_nodes (V_SgType);

    // Execute the query on each separate memory pool for the list of IR node variants

    // DQ (3/14/2007): The NodeQuery::queryMemoryPool() function assumes that the function return type is a std::list
    // so try to use the AstQueryNamespace::queryMemoryPool() function directly.
    // nodeList = NodeQuery::queryMemoryPool(funcTest,&ir_nodes);
    // AstQueryNamespace::queryMemoryPool(funcTest,nodeList,&ir_nodes);

    // DQ (2/16/2007): This is Andreas's fix for the performance problem represented by the previous 
    // implementat which built and returns STL lists by value with only a single IR node in the list.
    AstQueryNamespace::queryMemoryPool(std::bind2nd(funcTest,&nodeList),&ir_nodes); 
  }
  else
  {
    // This operation is expensive and not always accurate (though only vacuious destructors might be missing).
    // As a result we would like to depricate its use in ROSE (at least for V_SgType \n");
#if 0
    printf ("The use of this mechanism to get type information on arbitrary subtrees is depricated! (subtree at %p = %s) \n",astNode,astNode->class_name().c_str());
#endif

    // Get the types from the specified subtree
#if 1
 // DQ (1/13/2011): This will only get a subset of types.
    nodeList = NodeQuery::querySubTree (astNode,V_SgType);
#else
 // DQ (1/13/2011): But I don't think this is the correct approach...
    AstQueryNamespace::QueryDepth defineQueryType = AstQueryNamespace::ExtractTypes;
    nodeList = NodeQuery::querySubTree (astNode,V_SgType,defineQueryType);
#endif

#if 0
    printf ("/* AST Test: nodeList.size() = %zu */ \n",nodeList.size());
    printNodeList(nodeList);
    printf ("*** Sorted list *** \n");
#endif

    // DQ (9/25/2007): These operations don't exist for a std::vector and were used with we used std::list.
    // nodeList.sort();
    // nodeList.unique();
#if 0
    printf ("Skipping use of std::list<>::sort() and std::list<>::unique() now that we are using std::vector! (Is this a problem for NodeQuery::generateListOfTypes()?) \n");
#endif
  }

#if 0
  printNodeList(nodeList);
  printf ("DONE: Generate list of types ... \n");
  printf ("************************** \n\n\n");
#endif

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

		return 0;
	}

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

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

	command_processing( argvList );

	if( !parse_OmpTask( argvList ) ) {

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

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

	t_start = usecs(); 
	// for time counter

	transform_Task2Loop( argvList );

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

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

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

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

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

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

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

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

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

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

			SgBasicBlock *body = defn->get_body();

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

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

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

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

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

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

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

				if( invarname != NULL ) {

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

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

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

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

						TaskValidation( current_loop );

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

				}

			}// end for loops

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

	}//end loop for each source file

	release_analysis();

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

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

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

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

	return 0;
}
// DQ (4/7/2004): Added to support more general lookup of data in the AST (vector of variants)
void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector,  NodeQuerySynthesizedAttributeType* returnNodeList )
   {
  // This function extracts type nodes that would not be traversed so that they can
  // accumulated to a list.  The specific nodes collected into the list is controlled
  // by targetVariantVector.

     ROSE_ASSERT (astNode != NULL);

#if 0
     printf ("Inside of void* querySolverGrammarElementFromVariantVector() astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     Rose_STL_Container<SgNode*> nodesToVisitTraverseOnlyOnce;

     pushNewNode (returnNodeList,targetVariantVector,astNode);

     vector<SgNode*>               succContainer      = astNode->get_traversalSuccessorContainer();
     vector<pair<SgNode*,string> > allNodesInSubtree  = astNode->returnDataMemberPointers();

#if 0
     printf ("succContainer.size()     = %zu \n",succContainer.size());
     printf ("allNodesInSubtree.size() = %zu \n",allNodesInSubtree.size());
#endif

     if ( succContainer.size() != allNodesInSubtree.size() )
        {
          for (vector<pair<SgNode*,string> >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end(); ++iItr )
             {
#if 0
               if ( iItr->first != NULL  )
                  {
                 // printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                    printf ("iItr->first = %p \n",iItr->first);
                    printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                  }
#endif
            // DQ (7/27/2014): Check if this is always non-NULL.
            // ROSE_ASSERT(iItr->first != NULL);
#if 0
               if (iItr->first != NULL)
                  {
                 // printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d class_name = %s \n",iItr->first->variantT(),iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first             = %p \n",iItr->first);
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->class_name = %s \n",iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d \n",(int)iItr->first->variantT());
                  }
                 else
                  {
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first == NULL \n");
                  }
#endif
               SgType* type = isSgType(iItr->first);
               if ( type != NULL  )
                  {
                 // DQ (1/13/2011): If we have not already seen this entry then we have to chase down possible nested types.
                 // if (std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() )
                    if (std::find(succContainer.begin(),succContainer.end(),type) == succContainer.end() )
                       {
                      // DQ (1/30/2010): Push the current type onto the list first, then any internal types...
                         pushNewNode (returnNodeList,targetVariantVector,type);

                      // Are there any other places where nested types can be found...?
                      // if ( isSgPointerType(iItr->first) != NULL  || isSgArrayType(iItr->first) != NULL || isSgReferenceType(iItr->first) != NULL || isSgTypedefType(iItr->first) != NULL || isSgFunctionType(iItr->first) != NULL || isSgModifierType(iItr->first) != NULL)
                      // if (type->containsInternalTypes() == true)
                         if (type->containsInternalTypes() == true)
                            {
#if 0
                              printf ("If we have not already seen this entry then we have to chase down possible nested types. \n");
                           // ROSE_ASSERT(false);
#endif

                              Rose_STL_Container<SgType*> typeVector = type->getInternalTypes();
#if 0
                              printf ("----- typeVector.size() = %zu \n",typeVector.size());
#endif
                              Rose_STL_Container<SgType*>::iterator i = typeVector.begin();
                              while(i != typeVector.end())
                                 {
#if 0
                                   printf ("----- internal type = %s \n",(*i)->class_name().c_str());
#endif
                                // DQ (1/16/2011): This causes a test in tests/roseTests/programAnalysisTests/variableLivenessTests 
                                // to fail with error "Error :: Number of nodes = 37  should be : 36"

                                // Add this type to the return list of types.
                                   pushNewNode (returnNodeList,targetVariantVector,*i);

                                   i++;
                                 }
                            }

                      // DQ (1/30/2010): Move this code to the top of the basic block.
                      // pushNewNode (returnNodeList,targetVariantVector,iItr->first);
                      // pushNewNode (returnNodeList,targetVariantVector,type);
                       }
                  }
             }
        }

#if 0
    // This code cannot be put here. Since the same SgVarRefExp will also be found during variable substitution phase.
    // We don't want to replace the original SgVarRefExp!!
    // Liao 1/19/2011. query the dim_info of SgArrayType associated with SgPntrArrRefExp
    // e.g.  assuming a subtree has a reference to an array, then the variables used to declare the array dimensions should also be treated as referenced/used by the subtree
    // even though the reference is indirect. 
    // AST should look like: 
    //    SgPntrArrRefExp -> SgVarRefExp (lhs) -> SgVariableSymbol(symbol) -> SgInitializedName -> SgArrayType (typeptr)  -> SgExprListExp (dim_info)
    // AST outlining needs to find indirect use of a variable to work properly
    if (std::find(targetVariantVector.begin(), targetVariantVector.end(), V_SgVarRefExp) != targetVariantVector.end())
    // Only do this if SgVarRefExp is of interest
    { 
      if (SgPntrArrRefExp * arr_exp = isSgPntrArrRefExp(astNode))
      {
        printf("Debug: queryVariant.C Found SgPntrArrRefExp :%p\n", arr_exp);
        Rose_STL_Container<SgNode*> refList = NodeQuery::querySubTree(arr_exp->get_lhs_operand(),V_SgVarRefExp);
        // find the array reference from the lhs operand, which could be a complex arithmetic expression
        SgVarRefExp* array_ref = NULL; 
        for (Rose_STL_Container<SgNode*>::iterator iter = refList.begin(); iter !=refList.end(); iter ++)
        {
          SgVarRefExp* cur_ref = isSgVarRefExp(*iter);
          ROSE_ASSERT (cur_ref != NULL);
          SgVariableSymbol * sym = cur_ref->get_symbol();
          ROSE_ASSERT (sym != NULL);
          SgInitializedName * i_name = sym->get_declaration();
          ROSE_ASSERT (i_name != NULL);
          SgArrayType * a_type = isSgArrayType(i_name->get_typeptr());
          if (a_type)
          {
            Rose_STL_Container<SgNode*> dim_ref_list = NodeQuery::querySubTree(a_type->get_dim_info(),V_SgVarRefExp);
            for (Rose_STL_Container<SgNode*>::iterator iter2 = dim_ref_list.begin(); iter2 != dim_ref_list.end(); iter2++)
            {
              SgVarRefExp* dim_ref = isSgVarRefExp(*iter2); 
              printf("Debug: queryVariant.C Found indirect SgVarRefExp as part of array dimension declaration:%s\n", dim_ref->get_symbol()->get_name().str());
              pushNewNode (returnNodeList, targetVariantVector, *iter2);
            }

          }  

        }
      } // end if SgPntrArrRefExp
    } // end if find()
#endif
     return NULL;
   } /* End function querySolverUnionFields() */
Exemple #22
0
SgExpression* MintArrayInterface::linearizeThisArrayRefs(SgNode* arrayNode, 
							 SgBasicBlock* kernel_body, 
							 SgScopeStatement* indexScope, 
							 SgInitializedName* arr_iname, 
							 bool useSameIndex) 
					
{
	//an instance of an array reference E[k][j+1][i]
	SgExpression* arrRefWithIndices = isSgExpression(arrayNode);

	SgExpression* arrayName;

	//index list are from right to left //first index is i if E[j][i]                                                                                                                                     
	vector<SgExpression*>  subscripts; 

	//get each subscripts of an array reference
	bool yes = MintArrayInterface::isArrayReference(arrRefWithIndices, &arrayName, &subscripts);
	ROSE_ASSERT(yes);

	if(subscripts.size() <= 1)
	  return NULL; //no need to flatten

	//step 7
	//simplfy means that we can simplfy the index expression (subexpression elimination) 
	//by rewriting it in terms of index + some offset instead of computing the offset from address 0.
	//if simplfy is false, then we cannot figure out the offset. We need to use offset from the address zero.

	bool simplfy = canWeSimplfyIndexExpression(subscripts);
	
	string arr_str = arr_iname -> get_name().str();
	string index_str = "index" + arr_str;
	string width_str = "width" + arr_str;
	string slice_str = "slice" + arr_str;

	if(useSameIndex)
	  {
	    width_str = "_width";
	    slice_str = "_slice";

	    if(subscripts.size() == 3){
	      index_str = "_index3D";
	    }
	    else if(subscripts.size() == 2){
		index_str = "_index2D";
	      }
	    else if(subscripts.size() == 1){
		index_str = "_index1D";
	      }
	  }

	//base offset, we need to find the relative offset 
	//index expression can be [k +|- c]
	SgExpression* indexExp = buildVarRefExp(index_str, indexScope);	

	if(simplfy) //continue step 7
	  {
	    int indexNo=0;
	    
	    vector<SgExpression*>::iterator index_itr = subscripts.begin();
	    
	    for(index_itr = subscripts.begin(); index_itr != subscripts.end(); index_itr++)
	      {
		//We assume that if there is binary operation, then it has to be 
		//plus/minus i,j,k with a constant
		//Otherwise it is just i,j,k
		SgExpression* index = *index_itr;
		ROSE_ASSERT(index);

		//looking for minus, plus 1s: i-1, j+1 or just i,j,k
		Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(index, V_SgIntVal);      
		Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp);
		Rose_STL_Container<SgNode*> subtractExp = NodeQuery::querySubTree(index, V_SgSubtractOp);
		Rose_STL_Container<SgNode*> addExp = NodeQuery::querySubTree(index, V_SgAddOp);
		
		indexNo++;
		
		if(subtractExp.size() == 1 || addExp.size() == 1) // it is addOp or subtractOp
		  {
		    //e.g. [k][j-1][i+1] becomes [index - 1* width + 1]
		    //optimize it further if the constant is 1 or 0.
		    if(indexVarExp.size() == 1)
		      {
			ROSE_ASSERT(constExp.size() == 1);
			
			SgIntVal* constVal = isSgIntVal(*(constExp.begin()));
			int constIntVal = constVal->get_value();
			SgExpression* offset = NULL;
			
			if(indexNo == 1) //gidx
			  {
			    offset = buildIntVal(constIntVal);
			  }
			else if (indexNo==2) //idy
			  {
			    offset = buildVarRefExp(width_str, kernel_body) ; 
			    if(constIntVal != 1)
			      offset = buildMultiplyOp(offset, buildIntVal(constIntVal));
			  }
			else if(indexNo==3) //idz
			  {
			    offset = buildVarRefExp(slice_str, kernel_body) ; 
			    if(constIntVal != 1)
			      offset = buildMultiplyOp(offset, buildIntVal(constIntVal));
			  }
			if(constIntVal != 0 )
			  {
			    ROSE_ASSERT(offset);
			    if(subtractExp.size() == 1)
			      indexExp = buildSubtractOp(indexExp, offset);
			    else if (addExp.size() == 1)
			      indexExp = buildAddOp(indexExp, offset);
			  }
		      }
		    else if (indexVarExp.size() == 2)
		      { //Added in (3 March 2011) to handle boundary loads
			//they are typically A[z][y][x + borderOffset] so it is worth to optimize them
			
			Rose_STL_Container<SgNode*>::iterator it = indexVarExp.begin();	      
			SgVarRefExp* first = isSgVarRefExp(*it);
			SgVarRefExp* second = isSgVarRefExp(*(++it));
			
			ROSE_ASSERT(first);
			ROSE_ASSERT(second);
			
			string secondRef = second->unparseToString();
			
			SgExpression* offset =copyExpression(first);
			
			if(secondRef.find(GIDX) == string::npos && secondRef.find(GIDY) && string::npos && secondRef.find(GIDZ) == string::npos)
			  {//borderOffset is the second var 
			    offset = copyExpression(second);
			  }
			
			if (indexNo==2) //idy
			  {
			    offset = buildMultiplyOp(offset,buildVarRefExp(width_str, kernel_body)) ; 
			  }
			if(indexNo==3) //idz
			  {
			    offset = buildMultiplyOp(offset, buildVarRefExp(slice_str, kernel_body)) ; 
			  }
			
			ROSE_ASSERT(offset);
			if(subtractExp.size() == 1)
			  indexExp = buildSubtractOp(indexExp, offset);
			else if (addExp.size() == 1)
			  indexExp = buildAddOp(indexExp, offset);
			
		      }
		    else {
		      ROSE_ABORT();
		    }
		  }
		else 
		  {
		    ROSE_ASSERT(constExp.size() == 0);
		    //do nothing because it is in the base index
		  }		
	      } //end of subscript loop 
	    
	  }//end of simplfy = true 
	
	else  //step 8
	  {
		
	    //index expression cannot be simplfied 
	    //e.g A[0][n-1][i-j+1][0+3-i]
	    //output:
	    //e.g. _gidx + _gidy * widthUnew  in 2D
	    //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D
	    
	    vector<SgExpression*>::iterator index_itr = subscripts.begin();
	    
	    //first index is i if E[j][i]           
	    ROSE_ASSERT(*index_itr);
	    
	    //first index
	    indexExp = deepCopy(*index_itr);
	    
	    if(subscripts.size() >= 2) //second index
	      {
		index_itr++; 
		ROSE_ASSERT(*index_itr);
		
		SgVarRefExp* sizeExp = buildVarRefExp(width_str, kernel_body);   
		ROSE_ASSERT(sizeExp);
		
		indexExp = buildAddOp(indexExp, buildMultiplyOp( deepCopy(*index_itr), sizeExp));
	      }
	    if (subscripts.size() == 3) //third index
	      {
		index_itr++; 
		ROSE_ASSERT(*index_itr);
		
		SgVarRefExp* sizeExp2 = buildVarRefExp(slice_str, kernel_body);
		ROSE_ASSERT(sizeExp2);
		
		indexExp = buildAddOp(indexExp, buildMultiplyOp( deepCopy(*index_itr), sizeExp2)); 
		
	      }
	    
	    ROSE_ASSERT(subscripts.size() <= 3);
	    
	  }//end of !simplfy
	
	return indexExp;

}//end of indexList of one array
Exemple #23
0
bool canWeSimplfyIndexExpression(vector<SgExpression*>  subscripts)
{
  //valid means that we can use common subexpression elimination.

  //simplfy means that we can simplfy the index expression (subexpression elimination) 
  //by rewriting it in terms of index_arrname + offset (some offset)
  //false: we cannot figure out the offset,then we leave it as it is. 

  bool valid = false ;
  int indexNo = 0 ; 
  
  vector<SgExpression*>::iterator it;	

  for(it = subscripts.begin(); it != subscripts.end(); it++)
    {
      //looking for minus, plus a small constant: i-c, j+c
      SgExpression* index = isSgExpression(*it);
      ROSE_ASSERT(index);
      
      indexNo++;
      
      Rose_STL_Container<SgNode*> expListInIndex = NodeQuery::querySubTree(index, V_SgExpression);      
      for(Rose_STL_Container<SgNode*>::iterator one_exp = expListInIndex.begin(); one_exp != expListInIndex.end(); one_exp++)
	{
	  SgExpression* tmp_exp = isSgExpression(*one_exp);
	  
	  //these are only allowable expressions that appear in the index expression
	  //we are interested in [i +|- c ]
	  if( isSgAddOp(tmp_exp) || isSgSubtractOp(tmp_exp) || isSgIntVal(tmp_exp) || isSgVarRefExp(tmp_exp)){
	      valid = true; 
	    }
	  else
	    {
	      return false;
	    } 	    
	}

      //looking for minus, plus 1s: i-1, j+1
      Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(index, V_SgIntVal);      
      Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp);
      Rose_STL_Container<SgNode*> binaryOp = NodeQuery::querySubTree(index, V_SgBinaryOp);
     
      //we allow only one constant in the index expression 
      //because we already apply constant folding 
      
      if(constExp.size() > 1)
	return false; 
      
      else if(binaryOp.size() > 1)
	return false; 
      
      else if(indexVarExp.size() < 1 || indexVarExp.size() > 2)
	return false;
      
      else if(indexVarExp.size() == 2)
	{//one of them should idx, y, z other can be anything 
	  Rose_STL_Container<SgNode*>::iterator it = indexVarExp.begin();

	  SgExpression* first = isSgExpression(*(it));
	  SgExpression* second = isSgExpression(*(++it));

	  string first_str = first->unparseToString();
	  string second_str = second->unparseToString();

	  if(indexNo == 1) //gidx
	    {
	      if(first_str.find(GIDX) == string::npos && second_str.find(GIDX) == string::npos)
		return false;
	    }
	  else if (indexNo == 2)
	    {
	      if(first_str.find(GIDY) == string::npos && second_str.find(GIDY) == string::npos)
		return false; 
	    }
	  else if (indexNo == 3)
	    {
	      if(first_str.find(GIDZ) == string::npos && second_str.find(GIDZ) == string::npos)
		return false; 
	    }
	  else
	    return false;

	}
      else // there is a least one variable 
	{
	  SgExpression* varExp = isSgExpression(*(indexVarExp.begin())); 
	  string varExp_str = varExp->unparseToString();

	  if(indexNo == 1) //gidx
	    {
	      if(varExp_str.find(GIDX) == string::npos)
		return false;
	    }
	  else if (indexNo == 2)
	    {
	      if(varExp_str.find(GIDY) == string::npos)
		return false; 
	    }
	  else if (indexNo == 3)
	    {
	      if(varExp_str.find(GIDZ) == string::npos)
		return false; 
	    }
	  else
	    return false;
	}

    }//end of indices of a single array reference

  return valid;

}
void
instantiateTemplates ( SgProject* project )
   {
  // DQ (7/12/2005): Introduce tracking of performance of ROSE.
     TimingPerformance timer ("AST Object Code Generation (instantiateTemplates): time (sec) = ");

  // DQ (9/6/2005): I think these operations have been superseded
  // by the AST post processing mechanism which is more complete.
     printf ("In instantiateTemplates(): I think this may be dead code! \n");
     ROSE_ASSERT(false);

  // After compilation we can start the process of template instantiation
  //    1) Compiling to object files (building *.ti files)
  //         a) build *.ti files (call instantiateTemplates() function)
  //    2) Linking
  //         a) call prelink utility
  //              * builds instantiation information (*.ii files)
  //              * calls compilation step to force instantiation (using info in *.ii files)
  //              * calls prelink utility iteratively
  //         b) call g++ to do final linking with all templates resolved

     ROSE_ASSERT (project != NULL);
  // printf ("In instantiateTemplates(project = %p) \n",project);

#if 1
  // ***********************
  // Calling prelink utility
  // ***********************
  // printf ("Calling prelink utility ... \n");

     Rose_STL_Container<string> sourceFilenameList = project->get_sourceFileNameList();

     ROSE_ASSERT (sourceFilenameList.size() <= 1);
     if ( project->get_prelink() == false )
        {
          Rose_STL_Container<string> objectFilenameList = project->get_objectFileNameList();

          string prelinkOptions = "-v -d9 -i ";
          string objectFiles;
          Rose_STL_Container<string> argList;
          if ( (sourceFilenameList.size() == 1) && (objectFilenameList.size() == 0) )
             {
               printf ("Handling (debugging) single file case of template instantiation \n");

               Rose_STL_Container<string>::iterator fileIndex = sourceFilenameList.begin();
               ROSE_ASSERT (sourceFilenameList.size() == 1);
               string filenameWithPath = *fileIndex;
               string filename         = Rose::utility_stripPathFromFileName(filenameWithPath.c_str());

               int filenameLength = filename.length();
               printf ("In instantiateTemplates(): filename = %s \n",filename.c_str());

            // This would not handle a foo.cpp file name (with ".cpp" as a suffix), I think
               string nameWithoutSuffix = filename.substr(0,filenameLength-2);
#if 0
               objectFiles = nameWithoutSuffix + ".o";
#else
            // Make the prelink phase operate on a rose_<file name>.o file and fix 
            // the object file name generated by the vendor compiler (to generate 
            // the same file name).
               objectFiles = string("rose_") + nameWithoutSuffix + ".o";
#endif
               printf ("In instantiateTemplates(): objectFiles = %s \n",objectFiles.c_str());

            // DQ (9/25/2007): This is the first element to be put into the list, so we can use push_back() inplace of push_front().
            // argList.push_front(objectFiles);
               argList.push_back(objectFiles);
             }
            else
             {
            // linking only (this processing is different than that of a single file)
            // Debug the single file case before addressing multiple files required 
            // for link only processing.

               printf ("Linking only, template instantiation stil being debugged (similar to single file case) \n");
            // ROSE_ASSERT (false);

               objectFiles = CommandlineProcessing::generateStringFromArgList(project->get_objectFileNameList());
               argList = project->get_objectFileNameList();
             }

       // DQ (1/13/2005):
       // We could check to make sure there are valid *.ti (template instantiation files) associated with the objectFiles
       // if not then calling "edg_prelink" will cause an error.  But it is not required!  It is not an error for edg_prelink
       // to not find a corresponding *.ti file for each object file!
       // printf ("Check for corresponding template instantiation files: objectFiles = %s \n",objectFiles.c_str());

       // Build the command line to execute the edg_prelink utility 
       // (user's path must include location of edg_prelink utility).
          string prelinkCommandLine = "edg_prelink " + prelinkOptions + objectFiles;

#if 0
          printf ("\n\n");
          printf ("######################################### \n");
          printf ("######################################### \n");
          printf ("######################################### \n");
          printf ("prelinkCommandLine = %s \n",prelinkCommandLine.c_str());
          printf ("######################################### \n");
          printf ("######################################### \n");
          printf ("######################################### \n");
          printf ("\n\n");

          printf ("Print out rose_test2005_74.C (before prelink) \n");
          system("cat /home/dquinlan2/ROSE/LINUX-3.3.2/developersScratchSpace/Dan/rose_test2005_74.C");
#endif

          int argc    = 0;
          char** argv = NULL;

       // Add the commandline parameters as separate strings (in reverse order)
       // argList.push_front(" -i ");
       // argList.push_front(" -d9 ");
       // argList.push_front(" -a 0 ");

       // DQ (9/25/2007): Move from std::list to std::vector.
       // argList.push_front(" -v ");
          argList.insert(argList.begin()," -v ");

       // Separate list out into form traditional argc and argv form parameters
          CommandlineProcessing::generateArgcArgvFromList (argList,argc,argv);

          printf ("Calling generateArgcArgvFromList: argc = %d compressed argList = %s \n",
               argc,CommandlineProcessing::generateStringFromArgList(argList).c_str());

       // Declaration of prelink_main() function
          int prelink_main(int argc, char *argv[]);

          printf ("############### Before call to prelink_main ... ################ \n");

       // Use original interface (from when it was a command line utility!
          prelink_main(argc,argv);

          printf ("############### After call to prelink_main ... ################ \n");
       // ROSE_ASSERT(false);
        }
       else
        {
       // printf ("############### Prelink option specified (exited compilation!) ################ \n");
        }

  // printf ("Print out rose_test2004_18.C (after prelink) \n");
  // system("cat /home/dquinlan2/ROSE/LINUX-3.3.2/dqDevelopmentDirectory/rose_test2004_18.C");

#else
     printf ("Skipping calls to iterative prelink utility ... \n");
#endif

#if 0
     printf ("Exiting after handling newly instantiated code! \n");
     ROSE_ASSERT (false);
#endif
   }
void
fixupInstantiatedTemplates ( SgProject* project )
   {
  // DQ (7/12/2005): Introduce tracking of performance of ROSE.
     TimingPerformance timer ("AST Object Code Generation (fixupInstantiatedTemplates): time (sec) = ");

  // DQ (9/6/2005): I think these operations have been superseded
  // by the AST post processing mechanism which is more complete.
     printf ("In fixupInstantiatedTemplates(): I think this may be dead code! \n");
     ROSE_ASSERT(false);

  // This must be done prior to the unparsing of the SAGE III AST, so that any transformations
  // (new function prototypes for the specialized template function) can be inserted before we 
  // unparse the final code!  Could be done in AST fixup!  Not clear if it should be done in
  // the EDG/SAGE III connection!  It is currently called from the backend() function just 
  // before the unparser!

  // Add forward references for instantiated template functions and member functions 
  // (which are by default defined at the bottom of the file (but should be declared 
  // at the top once we know what instantiations should be built)).  They must be 
  // defined at the bottom since they could call other functions not yet declared in 
  // the file.  Note that this fixup is required since we have skipped the class template 
  // definitions which would contain the declarations that we are generating.  We might 
  // need that as a solution at some point if this fails to be sufficently robust.

  // Build a lists of intatiatied templates
     Rose_STL_Container<SgNode*> classList          = NodeQuery::querySubTree (project,V_SgTemplateInstantiationDecl);
     Rose_STL_Container<SgNode*> functionList       = NodeQuery::querySubTree (project,V_SgTemplateInstantiationFunctionDecl);
     Rose_STL_Container<SgNode*> memberFunctionList = NodeQuery::querySubTree (project,V_SgTemplateInstantiationMemberFunctionDecl);

#if 1
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationDecl:               classList.size()          = %ld \n",classList.size());
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationFunctionDecl:       functionList.size()       = %ld \n",functionList.size());
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationMemberFunctionDecl: memberFunctionList.size() = %ld \n",memberFunctionList.size());
#endif

  // These are not handled yet!
  // ROSE_ASSERT(classList.size()    == 0);
  // ROSE_ASSERT(functionList.size() == 0);

     Rose_STL_Container<SgNode*>::iterator functionIndex = functionList.begin();
     while ( functionIndex != functionList.end() )
        {
       // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
          SgTemplateInstantiationFunctionDecl* templateInstantiationFunctionDeclaration = 
               isSgTemplateInstantiationFunctionDecl(*functionIndex);
          ROSE_ASSERT (templateInstantiationFunctionDeclaration != NULL);

       // printf ("SgTemplateInstantiationFunctionDecl: *i = %p = %s \n",*functionIndex,(*functionIndex)->unparseToString().c_str());

       // Mark this function as a specialization, since we have transformed it into one when we converted the
       // name format (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
          printf ("Error in fixupInstantiatedTemplates (function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
          templateInstantiationFunctionDeclaration->set_specialization(SgTemplateInstantiationFunctionDecl::e_specialization);

          bool generateForwardDeclarationForFunction = (templateInstantiationFunctionDeclaration->isForward() == false);

          if ( generateForwardDeclarationForFunction == true )
             {
            // This is just a regular member function inside of a templated class (or a class nested in a templated class)
            // it's associated template declaration will not have the template text (appears to be lost in EDG), but it 
            // is not essential if we unparse the instantated template for the member function.

            // This is the instantiate template member function definition, the steps are:
            //    1) Build a forward declaration for the instantiated template (member function).
            //    2) Place the new forward declaration after the class containing the templated member function.
             }

          functionIndex++;
        }

     Rose_STL_Container<SgNode*>::iterator classIndex = classList.begin();
     while ( classIndex != classList.end() )
        {
          SgTemplateInstantiationDecl* templateInstantiationClassDeclaration = 
               isSgTemplateInstantiationDecl(*classIndex);
          ROSE_ASSERT (templateInstantiationClassDeclaration != NULL);

       // printf ("SgTemplateInstantiationDecl: *i = %p = %s \n",*classIndex,(*classIndex)->unparseToString().c_str());

#if 0
          printf ("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration = %p compilerGenerated = %s \n",
                  templateInstantiationClassDeclaration,
                  templateInstantiationClassDeclaration->get_file_info()->isCompilerGenerated() ? "true" : "false");
          templateInstantiationClassDeclaration->get_file_info()->display("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration");
#endif

       // Mark this class as a specialization, since we have transformed it into one when we converted the
       // name format (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
          printf ("Error in fixupInstantiatedTemplates (class templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
          templateInstantiationClassDeclaration->set_specialization(SgTemplateInstantiationDecl::e_specialization);

          bool generateForwardDeclarationForClass = (templateInstantiationClassDeclaration->isForward() == false);

          if ( generateForwardDeclarationForClass == true )
             {
            // Nothing to do in this case since EDG should have already instered the forward class declaration!
             }

          classIndex++;
        }

  // Loop over the SgTemplateInstantiationMemberFunction objects and insert a function prototype.
  // We need the function prototypes because the template instatiation function definitions appear 
  // at the end of the file!
     Rose_STL_Container<SgNode*>::iterator i = memberFunctionList.begin();
     while ( i != memberFunctionList.end() )
        {
       // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
          SgTemplateInstantiationMemberFunctionDecl* templateInstantiationMemberFunctionDeclaration = 
               isSgTemplateInstantiationMemberFunctionDecl(*i);
          ROSE_ASSERT (templateInstantiationMemberFunctionDeclaration != NULL);
#if 0
          printf ("templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == %s \n",
               templateInstantiationMemberFunctionDeclaration->isTemplateFunction() ? "true" : "false");
#endif
       // Mark this function as a specialization, since we have transformed it into one when we converted the
       // name formate (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
       // If this is not a truely templated function then it can't be a specialization!
       // if it is not a templated function then is is likely just a member function of a templated class.
          if (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == true)
             {
               printf ("Error in fixupInstantiatedTemplates (member function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
               templateInstantiationMemberFunctionDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization);
             }
#if 0
       // DQ (9/5/2005): Updated comment.
       // DQ (5/31/2005): Commented out since the class declaration itself is the forward declaration 
       // for the member function. I don't think we need another one!  Actually we do but this is now 
       // handled within ROSE/src/frontend/SageIII/astPostProcessing/ files.

          bool generateForwardDeclarationForInlinedMemberFunction = 
               (templateInstantiationMemberFunctionDeclaration->isForward() == false) &&
               (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == false);

          if ( generateForwardDeclarationForInlinedMemberFunction == true )
             {
            // This is just a regular member function inside of a templated class (or a class nested in a templated class)
            // it's associated template declaration will not have the templae text (appears to be lost in EDG), but it 
            // is not essential if we unparse the instantated template for the member function.

               printf ("For inlined template member functions get the templateDeclaration from the class declaration \n");

            // This is the instantiate template member function definition, the steps are:
            //    1) Build a forward declaration for the instantiated template (member function).
            //    2) Place the new forward declaration after the class containing the templated member function.

               printf ("SgTemplateInstantiationMemberFunctionDecl: *i = %p = %s \n",*i,(*i)->unparseToString().c_str());

            // Call the AST's copy mechanism
               SgShallowCopy shallow;
               SgNode * forwardDeclarationNode = templateInstantiationMemberFunctionDeclaration->copy(shallow);
               SgTemplateInstantiationMemberFunctionDecl* forwardDeclaration = isSgTemplateInstantiationMemberFunctionDecl(forwardDeclarationNode);
               ROSE_ASSERT(forwardDeclaration != NULL);

            // find the template declaration of the class contining the member function
               SgClassDeclaration* classDeclaration = templateInstantiationMemberFunctionDeclaration->get_class_scope()->get_declaration();
               ROSE_ASSERT(classDeclaration != NULL);
               SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(classDeclaration);
               ROSE_ASSERT(templateInstantiationDeclaration != NULL);
               SgTemplateDeclaration* templateDeclaration = templateInstantiationDeclaration->get_templateDeclaration();
               ROSE_ASSERT (templateDeclaration != NULL);

            // Reset the file info object so that we can mark this as compiler generated (copy builds a new Sg_File_Info object)
            // ROSE_ASSERT (forwardDeclaration->get_file_info() != NULL);
            // forwardDeclaration->set_file_info(new Sg_File_Info(*(forwardDeclaration->get_file_info())));
               ROSE_ASSERT(forwardDeclaration->get_file_info() != templateInstantiationMemberFunctionDeclaration->get_file_info());

            // Both of these may be set (implemented as bit flags internally)
               forwardDeclaration->get_file_info()->setCompilerGenerated();
               forwardDeclaration->get_file_info()->setTransformation();

            // Remove the shallow copy of the function definition
               forwardDeclaration->set_definition(NULL);

            // Mark the declaration as a forward declarations
               forwardDeclaration->setForward();

            // Mark this function as a specialization (should be done within copy function)
            // forwardDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization);

               ROSE_ASSERT(forwardDeclaration->isSpecialization() == true);
               ROSE_ASSERT(forwardDeclaration->isPartialSpecialization() == false);

            // Now insert the forwardDeclaration after the templateDeclaration!
            // templateDeclaration.insert_statement(forwardDeclaration,true);
               SgScopeStatement* templateDeclarationScope = templateDeclaration->get_scope();
               ROSE_ASSERT (templateDeclarationScope != NULL);
               printf ("BEFORE loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());

            // Trace back through the scopes to find a non class declaration scope into which to put the forward declaration
            // Does this then work with nested template classes?????
               while (isSgTemplateInstantiationDefn(templateDeclarationScope) != NULL)
                  {
                    templateDeclarationScope = templateDeclarationScope->get_scope();
                    printf ("In loop templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());
                  }

               ROSE_ASSERT (templateDeclarationScope != NULL);
               printf ("AFTER loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());

               templateDeclaration->get_file_info()->display("templateDeclaration");
               templateDeclarationScope->get_file_info()->display("templateDeclarationScope");

               int insertBeforeStatement = false;
            // printf ("Calling templateDeclarationScope->insert_statement() \n");
            // templateDeclaration->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement );
               SgTemplateInstantiationDefn *templateClassDefinition = isSgTemplateInstantiationDefn(templateDeclarationScope);
               if (templateClassDefinition != NULL)
                  {
                    SgDeclarationStatementPtrList::iterator start = templateClassDefinition->get_members().begin();
                    SgDeclarationStatementPtrList::iterator end   = templateClassDefinition->get_members().end();

                    printf ("templateDeclaration unparsed = %s \n",templateDeclaration->unparseToString().c_str());
                    printf ("templateDeclaration name = %s string = %s \n",
                         templateDeclaration->get_name().str(),templateDeclaration->get_string().str());

                    for (SgDeclarationStatementPtrList::iterator i = start; i != end; i++)
                       {
                         string s = (*i)->unparseToString();
                         printf ("(*i)->unparseToString() = %s \n",s.c_str());
                       }

                    ROSE_ASSERT(find(start,end,templateInstantiationMemberFunctionDeclaration) != end);
                    templateDeclarationScope->insert_statement ( templateInstantiationMemberFunctionDeclaration, forwardDeclaration, insertBeforeStatement );
                  }
                 else
                  {
                 // ROSE_ASSERT(find(templateDeclarationScope->get_members().begin(),templateDeclarationScope->get_members().end(),templateDeclaration) != templateDeclarationScope->get_members().end() );
                    templateDeclarationScope->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement );
                  }

               printf ("forwardDeclaration = %s \n",forwardDeclaration->unparseToString().c_str());

            // printf ("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD \n");
            // printf ("Exiting after construction of forward declaration for template instantiation! \n");
            // ROSE_ASSERT (false);
             }
            else
             {
            // This is a forward declaration (does it have the template arguments!)
               printf ("SgTemplateInstantiationMemberFunctionDecl: (forward) *i = %p = %s \n",*i,(*i)->unparseToString().c_str());
             }
#endif
          i++;
        }
   }
Exemple #26
0
void MintConstantFolding::constantFoldingOnArrayIndexExpressions(SgNode* node)
{
  //Assumptions: constant array indices are always integer
  /* we replace var ref exp with 0 and then put that back to the index var
     after constant folding 
     e.g let's say we have an expression A[i + 2 - 3]
     1.step we replace i with 0 (we previously check that all the operations are either -/+)
     if there is only one occurance of i in the index expression 
     2.step we call ROSE's constant folding function
     3.step we create new expression using the constant and i
     4.step replace it with the old index expression
     Tricky part is to figure out the sign of i.
  */
  
  MintInitNameMapExpList_t arrRefList;
  MintArrayInterface::getArrayReferenceList(node, arrRefList); 

  MintInitNameMapExpList_t::iterator it; 
  
  for(it = arrRefList.begin(); it != arrRefList.end(); it++)
    {
      SgInitializedName* array = it->first;
      ROSE_ASSERT(array);
      std::vector<SgExpression*> expList = it->second;       

      std::vector<SgExpression*>::iterator arrayNode;
      
      for(arrayNode = expList.begin(); arrayNode != expList.end() ; arrayNode++)
	{
	  ROSE_ASSERT(*arrayNode);	  

	  SgExpression* arrRefWithIndices = isSgExpression(*arrayNode);

	  SgExpression* arrayExp; 
	  vector<SgExpression*>  subscripts; //first index is i if E[j][i]
	  
	  if(MintArrayInterface::isArrayReference(arrRefWithIndices, &arrayExp, &subscripts))
	    {
	      std::vector<SgExpression*>::reverse_iterator sub;
	      
	      int subNo = subscripts.size() ;
 
	      for(sub= subscripts.rbegin(); sub != subscripts.rend(); sub++)
		{		  
		  subNo--;

		  //SgExpression* orig_index = *sub;
		  SgExpression* index = *sub;

		  bool minusSign = false; 
		  bool folding = canWeFold(index, &minusSign);

		  if(folding){
		    
		    Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp);
		    ROSE_ASSERT(indexVarExp.size() ==1);
		    
		    SgExpression* indexVar = isSgExpression(*(indexVarExp.begin()));
		    SgExpression* orig_IndexVar = copyExpression(indexVar);
		    
		    replaceExpression(indexVar, buildIntVal(0));

		    ConstantFolding::constantFoldingOptimization(arrRefWithIndices);		      			
		    
 		    //TODO: need to figure out the sign of index var -/+
		    //insert back the index var i to the index expression -/+ i + constant index exp
		    //we computed that and stored its sign in minusSign variable 

		    SgExpression* newArrayExp; 
		    vector<SgExpression*>  newSubscripts; //first index is i if E[j][i]
		    
		    if(MintArrayInterface::isArrayReference(arrRefWithIndices, &newArrayExp, &newSubscripts))
		      {
			vector<SgExpression*>::iterator it= newSubscripts.begin();
			SgExpression* newIndex = *(it+subNo);
			
			ROSE_ASSERT(newIndex);
			
			if(isSgIntVal(newIndex))
			  {
			    int folded_val =  isSgIntVal(newIndex) ->get_value();
			    SgExpression* newExp = NULL;
			    
			    if(folded_val > 0 ){
			      if(minusSign)
				newExp = buildSubtractOp( buildIntVal(folded_val), orig_IndexVar);
			      else
				newExp = buildAddOp(orig_IndexVar , buildIntVal(folded_val));
			    }
			    else if (folded_val == 0 )
			      {
				newExp = orig_IndexVar;
				if(minusSign)
				  newExp = buildMinusOp(orig_IndexVar);				  
			      }
			    else {
			      if(minusSign)
				newExp = buildSubtractOp(buildMinusOp(orig_IndexVar) , buildIntVal(-folded_val));			 
			      else
				newExp = buildSubtractOp(orig_IndexVar , buildIntVal(-folded_val));
			    }
			    replaceExpression(newIndex, newExp);
			  }			
		      }
		  }//end of folding 

		}//end of for subscript
	      
	    }//end of if array exp
	  
	}//end of for references of an array

    }//end of array ref list 
}
Exemple #27
0
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);
}
Exemple #28
0
//bool canWeFold(SgExpression* index, bool minusSign = false)
bool canWeFold(SgExpression* index, bool * minusSign)
{
  //we count the (-) signs affecting the index variable 
  //to understand if we should add a minus sign to the variable 
  //after folding or not
  
  int sign = 0;
  bool folding =true;

  Rose_STL_Container<SgNode*> constList = NodeQuery::querySubTree(index, V_SgIntVal);
  
  //we need at least 2 constants to fold
  if(constList.size() <= 1)
    {
      folding = false; 
    }

  Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp);
  if(indexVarExp.size() == 0 ) //e.g A[1 + 2 - 3]
    {
      //ROSE handled this 
      folding = false; 
    }
  else if(indexVarExp.size() > 1) //e.g A[i + 2 - 2 + j - 1]
    {//cannot handle this case, it is not so common anyways
      folding = false; 
    }
  else //size() == 1 //e.g A[i + 2 - 2 - 1]
    {
      Rose_STL_Container<SgNode*> expList = NodeQuery::querySubTree(index, V_SgExpression);		      
      Rose_STL_Container<SgNode*>::iterator exp;
      
      for(exp=expList.begin(); exp != expList.end() ; exp++)
	{
	  SgExpression* expression= isSgExpression(*exp);

	  //All the binary operations should be -/+
	  if(isSgBinaryOp(expression))
	    {	      
	      if( !( isSgAddOp(expression) || isSgSubtractOp(expression) ) )
		{//we want all operators either - or +
		  folding = false;
		  break; 
		}	      
	      else if(isSgSubtractOp(expression)) 
		{//check if the binary operation changes the sign of the varref
		  SgExpression* rhs = isSgBinaryOp(expression)->get_rhs_operand();
		  ROSE_ASSERT(rhs);
		  Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(rhs, V_SgVarRefExp);		      
		  if(varList.size() > 0)
		    sign++;
		}
	    }
	  else if(isSgMinusOp(expression) ){	

	    SgExpression* rhs = isSgMinusOp(expression)->get_operand();
	    ROSE_ASSERT(rhs);
	    Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(rhs, V_SgVarRefExp);		      
	    if(varList.size() > 0)
	      sign++;
	    
	    }
	  else if(isSgIntVal(expression) || isSgVarRefExp(expression))
	    {
	      //do nothing
	    }
	  else 
	    {
	      folding = false; 
	      break;
	    }
	}      
    }

  if(sign % 2 != 0)
    *minusSign = true; 

  return folding;

}
Exemple #29
0
SgModuleStatement*
FortranModuleInfo::getModule(string modName)
   {
  // DQ (11/12/2008): I am unclear if the conversion of the module name to lowercase 
  // should happen here, it does not appear to be required since at least the tests 
  // codes we have appear to work.

     size_t numberOfModules_before = moduleNameAstMap.size();

#if 0
     printf ("In FortranModuleInfo::getModule(%s): numberOfModules_before = %" PRIuPTR " \n",modName.c_str(),numberOfModules_before);
#endif

  // DQ (10/1/2010): STL Maps should not be used this way (a side-effect is that it adds a null entry to the map).
  // This results in fragle code.  I don't know why, but this breaks in the move to OFP 0.8.2 (likely due to case
  // issues since 0.8.2 eliminates the reduction of all keywords and identifiers to lower case).
  // SgModuleStatement *modStmt = moduleNameAstMap[modName];
  // map<string, SgModuleStatement*>::iterator mapIterator = moduleNameAstMap.find(modName);
     ModuleMapType::iterator mapIterator = moduleNameAstMap.find(modName);
     SgModuleStatement *modStmt = (mapIterator != moduleNameAstMap.end()) ? mapIterator->second : NULL;

  // DQ (10/1/2010): This assert (below) used to fail because STL maps were not being properly handled.
  // Note that it is a little known side-effect of "moduleNameAstMap[modName]" that is will insert an
  // entry into the map.
     size_t numberOfModules_after = moduleNameAstMap.size();
     ROSE_ASSERT(numberOfModules_before == numberOfModules_after);

#if 0
     printf ("In FortranModuleInfo::getModule(%s): modStmt = %p \n",modName.c_str(),modStmt);
#endif

     if (modStmt != NULL)
        {
          if (SgProject::get_verbose() > 1)
               printf ("This module has been previously processed (seen) in this compilation unit. \n");

          return modStmt;
        }

     string nameWithPath = find_file_from_inputDirs(modName);

     if (SgProject::get_verbose() > 1)
          printf ("In FortranModuleInfo::getModule(%s): nameWithPath = %s \n",modName.c_str(),nameWithPath.c_str());

  // if (createSgSourceFile(nameWithPath) == NULL )

#if 0
     printf ("********* BUILD NEW MODULE FILE IF NOT ALREADY BUILT **************** \n");
#endif

     SgSourceFile* newModuleFile = createSgSourceFile(nameWithPath);

#if 0
     printf ("********************************************************************* \n");
#endif

#if 0
  // Output an optional graph of the AST (just the tree, when active)
     generateDOT ( *newModuleFile );

  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 10000;
     generateAstGraph(newModuleFile,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"");
#endif

     if (newModuleFile == NULL )
        {
          cerr << "error: No declaration found for the module: "<<modName << endl;
          return NULL;
        }
       else
        {
       // in createSgSourceFile: insert moduleNameAstMap[modName]

          if (SgProject::get_verbose() > 1)
               printf ("In FortranModuleInfo::getModule(%s): createSgSourceFile(nameWithPath) != NULL nameWithPath = %s \n",modName.c_str(),nameWithPath.c_str());
#if 1
       // DQ (10/1/2010): This is a work-around for OFP 0.8.2 failing to call the c_action_end_module_stmt() 
       // rule for an included module (from use statement) that includes another module (again, using 
       // a use statment).  The first module using the use statment will not have its 
       // c_action_end_module_stmt() rule called. See the test_forcing.F90 example test code.

       // Extract the pointer to the SgModule from the SgSourceFile
          Rose_STL_Container<SgNode*> moduleDeclarationList = NodeQuery::querySubTree (newModuleFile,V_SgModuleStatement);

       // There should only be a single module defined in the associated *.rmod file.
          if (moduleDeclarationList.size() != 1)
             {
               printf ("Error: moduleDeclarationList.size() = %" PRIuPTR " \n",moduleDeclarationList.size());
             }
          ROSE_ASSERT(moduleDeclarationList.size() == 1);

          modStmt = isSgModuleStatement(moduleDeclarationList[0]);
          ROSE_ASSERT(modStmt != NULL);

       // Insert the extracted module into the moduleNameAstMap (this is the only location where the moduleNameAstMap is modified).
       // moduleNameAstMap.insert(std::pair<string,SgModuleStatement*>(modName,modStmt));
              moduleNameAstMap.insert(ModuleMapType::value_type(modName,modStmt));

#ifdef USE_STMT_DEBUG
          printf ("In FortranModuleInfo::getModule(%s) modStmt = %p: display the moduleNameAstMap \n",modName.c_str(),modStmt);
          dumpMap();
          printf ("DONE: In FortranModuleInfo::getModule(%s) modStmt = %p: display the moduleNameAstMap \n\n",modName.c_str(),modStmt);
#endif
#else
       // ROSE_ASSERT(moduleNameAstMap[modName] != NULL);
       // ROSE_ASSERT(moduleNameAstMap.find(modName) != moduleNameAstMap.end());

#error "DEAD CODE!"

       // This is the correct (safer) way to check the existence of an entry 
       // in an STL map (without the side-effect of adding a null entry).
       // return moduleNameAstMap[modName];
          mapIterator = moduleNameAstMap.find(modName);
          modStmt = (mapIterator != moduleNameAstMap.end()) ? mapIterator->second : NULL;
       // ROSE_ASSERT(modStmt != NULL);
#endif
#if 0
       // DQ (10/1/2010): Workaround to OFP failing to call the c_action_end_module_stmt()
          if (mapIterator == moduleNameAstMap.end())
             {
               printf ("Insert newModuleFile = %p modName = %s into moduleNameAstMap \n",newModuleFile,modName.c_str());
            // moduleNameAstMap.insert(std::pair<string,SgModuleStatement*>(modName,newModuleFile));
               moduleNameAstMap.insert(ModuleMapType::pair(modName,newModuleFile));
             }
#endif

          if ( SgProject::get_verbose() > 2 )
               printf ("Leaving FortranModuleInfo::getModule(%s): modStmt = %p \n",modName.c_str(),modStmt);

          return modStmt;
        }
   }
Exemple #30
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  //  autopar_command_processing(argvList);
  argvList = commandline_processing (argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  //project->unparse();
  return backend (project);
}