/*
 *  Replace the op_par_loop with respective kernel function
 */
void OPSource::fixParLoops(SgNode *n)
{
  SgName kernel_name;
  SgFunctionCallExp *fn = isSgFunctionCallExp(n);
  if(fn != NULL)
  {
    string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString();
    if(fn_name.compare("op_par_loop_2")==0 
    || fn_name.compare("op_par_loop_3")==0 
    || fn_name.compare("op_par_loop_4")==0
    || fn_name.compare("op_par_loop_5")==0
    || fn_name.compare("op_par_loop_6")==0
    || fn_name.compare("op_par_loop_7")==0
    || fn_name.compare("op_par_loop_8")==0
    || fn_name.compare("op_par_loop_9")==0) 
    {
      SgExprListExp* exprList = fn->get_args();
      SgExpressionPtrList &exprs = exprList->get_expressions();
      SgFunctionRefExp* varExp =  isSgFunctionRefExp(exprs[0]);
      if(varExp != NULL)
      {
        kernel_name = varExp->get_symbol()->get_name();
      }
      exprs.erase(exprs.begin());

      SgExpressionPtrList::iterator it = exprs.begin() + op_par_loop_args::num_params - 1;
      for(; it != exprs.end(); it += op_argument::num_params)
      {
        *it = buildCastExp( *it, buildPointerType(SgClassType::createType( buildStructDeclaration("op_dat<void>"))) );
      }

      // Inject Name
      exprs.insert(exprs.begin(), buildStringVal(kernel_name));
      
      // Fetch the declaration
      SgName name = SgName("op_par_loop_") + kernel_name;
      SgFunctionDeclaration *funcDecl = cudaFunctionDeclarations[kernel_name];
      if(funcDecl)
      {
        SgFunctionRefExp* ref = isSgFunctionRefExp(fn->get_function());
        SgFunctionSymbol *symbol = ref->get_symbol();
        symbol->set_declaration(funcDecl);
        ref->set_symbol(symbol);
        fn->set_function(ref);
      }
    }
  }
}
Exemple #2
0
void
CompassAnalyses::PreferFseekToRewind::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  
     if(isSgFunctionCallExp(node))
     {
       SgFunctionCallExp* callSite = isSgFunctionCallExp(node);

       if(callSite->get_function() != NULL)
       {
         SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function());
         if(functionRefExp != NULL)
         {

           SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
           ROSE_ASSERT(functionSymbol != NULL);

           std::string functionName = functionSymbol->get_name().getString();

           if(functionName == "rewind")
           {
             output->addOutput(new CheckerOutput(node));
           }
         }
       }
     }

   } //End of the visit function.
Exemple #3
0
void
CompassAnalyses::NoVariadicFunctions::Traversal::
visit(SgNode* node)
   { 
     switch( node->variantT() )
     {
       case V_SgFunctionRefExp:
       {
         SgFunctionRefExp *fref = isSgFunctionRefExp(node);

         ROSE_ASSERT(fref != NULL);

         SgFunctionDeclaration *fdecl = fref->get_symbol()->get_declaration();

         this->functionDeclarationHandler(
           fdecl, fref );
       } break; //case V_SgFunctionRefExp
       case V_SgMemberFunctionRefExp:
       {
         SgMemberFunctionRefExp *fref = isSgMemberFunctionRefExp(node);

         ROSE_ASSERT(fref != NULL);

         SgFunctionDeclaration *fdecl = fref->get_symbol()->get_declaration();

         this->functionDeclarationHandler(
           fdecl, fref );
       } break; //case V_SgMemberFunctionRefExp
       default: break;
     } //switch( node->variantT() )

     return;
   } //End of the visit function.
void
CompassAnalyses::StringTokenToIntegerConverter::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  
     if(isSgFunctionCallExp(node))
     {
       SgFunctionCallExp* callSite = isSgFunctionCallExp(node);

       if(callSite->get_function() != NULL)
       {
         SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function());
         if(functionRefExp != NULL)
         {
           SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
           ROSE_ASSERT(functionSymbol != NULL);

           std::string functionName = functionSymbol->get_name().getString();

           if(functionName == "atoi" || functionName == "atol" || 
               functionName == "atoll" || functionName == "sscanf" )
           {
             output->addOutput(new CheckerOutput(node));
           }
         }
       }
     }

   } //End of the visit function.
Exemple #5
0
static void
run(Compass::Parameters parameters, Compass::OutputObject* output)
{
  // We only care about source code in the user's space, not,
  // for example, Boost or system files.
  string target_directory =
      parameters["general::target_directory"].front();
  CompassAnalyses::NoRand::source_directory.assign(target_directory);

  // Use the pre-built ROSE AST
  SgProject* sageProject = Compass::projectPrerequisite.getProject();
  SgNode* root_node = (SgNode*) sageProject;

  // perform AST matching
  AstMatching matcher;

  MatchResult matches = matcher.performMatching("$r=SgFunctionRefExp",
                                                root_node);

  BOOST_FOREACH(SingleMatchVarBindings match, matches)
  {
    SgFunctionRefExp *function = (SgFunctionRefExp *)match["$r"];
    std::string fncName = function->get_symbol()->get_name().getString();

    if( fncName.find( "rand", 0, 4) != std::string::npos)
    {
      output->addOutput(
          new CompassAnalyses::NoRand::CheckerOutput(function));
    }
  }
Exemple #6
0
/////////////////////////////////////////////////////////////////////////////////// The CompassAnalyses::NoExitInMpiCode::Traversal::visit(SgNode* node)
/// function implements a simple AST traversal seeking out SgFunctionRefExp
/// nodes for function reference expressions corresponding to MPI Init and
/// Finalize and calls to exit() nested in those blocks; these are reported
/// as checker violations.
///
/// \param node is a SgNode*
////////////////////////////////////////////////////////////////////////////////
void CompassAnalyses::NoExitInMpiCode::Traversal::visit(SgNode* node)
{
  static bool usedMPI = false;

  SgFunctionRefExp *sgfrexp = isSgFunctionRefExp(node);

  if( sgfrexp != NULL )
  {
    std::string sgfrexpName = sgfrexp->get_symbol()->get_name().getString();

    if( sgfrexpName == "MPI_Init" )
    {
      usedMPI = true;
    } //if( sgfrexpNam == "MPI_Init" )

    if( sgfrexpName == "MPI_Finalize" )
    {
      usedMPI = false;
    } //if( sgfrexpName == "MPI_Finalize" )

//#ASR:07/07/10
//fixed object creation of CheckerOutput for Cxx standard
    if( usedMPI == true && sgfrexpName == "exit" )
    {
      output->addOutput( new CompassAnalyses::NoExitInMpiCode::CheckerOutput( node ) );       
      //output->addOutput( new CompassAnalyses::NoExitInMpiCode::CheckerOutput::CheckerOutput( node ) );

    } //if( usedMPI == true && sgfrexpName == "exit" )

  } //if( sgfrexp != NULL )

  return;
} //visit(SgNode *node)
Exemple #7
0
void specificationTraversal::visit(SgNode* n) {
	if (isSgFunctionCallExp(n) != NULL)
	{

		SgFunctionCallExp* funcCallExp = isSgFunctionCallExp(n);
		SgFunctionRefExp* funcRefExp = isSgFunctionRefExp(funcCallExp->get_function());
		string functionName = funcRefExp->get_symbol()->get_declaration()->get_name().getString();

#if DEBUG
		cout << " Found Function Name: " << functionName << endl;
#endif

		LayoutOptions::LayoutType type = LayoutOptions::getLayoutType(functionName);

		switch (type) {
		case LayoutOptions::InterleaveAcrossArrays:
			handleInterLeaveAcrossArrays(funcCallExp);
			break;

		case LayoutOptions::UnknownTransformation:
			break;

		default:
			cout << " Unknown layout type option. " << endl;
			ROSE_ABORT();
		}

	}
}
Exemple #8
0
 // Note: this now (11/7/2008) considers pointer derefs and array derefs safe,
 // which doesn't preserve invalid memory access behavior
 bool isSimpleInitializer(SgExpression* e) {
     if (isSgVarRefExp(e)) return true;
     if (isSgValueExp(e)) return true;
     if (isSgUnaryOp(e) && isSimpleInitializer(isSgUnaryOp(e)->get_operand())) {
         return isSgBitComplementOp(e) || isSgMinusOp(e) || isSgNotOp(e) || isSgUnaryAddOp(e) || isSgCastExp(e) || isSgPointerDerefExp(e);
     }
     if (isSgBinaryOp(e) && isSimpleInitializer(isSgBinaryOp(e)->get_lhs_operand()) && isSimpleInitializer(isSgBinaryOp(e)->get_rhs_operand())) {
         return isSgAddOp(e) || isSgAndOp(e) || isSgBitAndOp(e) || isSgBitOrOp(e) || isSgBitXorOp(e) || isSgCommaOpExp(e) || isSgDivideOp(e) || isSgEqualityOp(e) || isSgGreaterOrEqualOp(e) || isSgGreaterThanOp(e) || isSgLessOrEqualOp(e) || isSgLessThanOp(e) || isSgLshiftOp(e) || isSgModOp(e) || isSgMultiplyOp(e) || isSgNotEqualOp(e) || isSgOrOp(e) || isSgRshiftOp(e) || isSgSubtractOp(e) || isSgPntrArrRefExp(e);
     }
     if (isSgConditionalExp(e)) {
         SgConditionalExp* c = isSgConditionalExp(e);
         return isSimpleInitializer(c->get_conditional_exp()) && isSimpleInitializer(c->get_true_exp()) && isSimpleInitializer(c->get_false_exp());
     }
     if (isSgFunctionCallExp(e)) {
         SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
         if (!fr) return false;
         SgFunctionDeclaration* decl = fr->get_symbol()->get_declaration();
         if (safe_functions.find(decl) == safe_functions.end()) {
             return false;
         }
         const SgExpressionPtrList& args = isSgFunctionCallExp(e)->get_args()->get_expressions();
         for (size_t i = 0; i < args.size(); ++i) {
             if (!isSimpleInitializer(args[i])) return false;
         }
         return true;
     }
     return false;
 }
Exemple #9
0
static bool ContainsNonSimpleCall(SgStatement *stmt)
{
   static std::set< std::string > segDB ;
   bool containsUnknownCall = false ;

   if (segDB.empty())
   {
      char funcName[128] ;
      FILE *fp ;
      if ((fp = fopen("SegDB.txt", "r")) != NULL)
      {
         while(fgets(funcName, 128, fp))
         {
            funcName[strlen(funcName)-1] = 0 ;
            segDB.insert(funcName) ;
         }
         fclose(fp) ;
      } 
      else
      {
         printf("File SEGDB.txt is absent. Sequential segment results degraded.\n") ;
         segDB.insert("_____") ;
      }
   }
   /* check to see if this statement contains any function calls */
   Rose_STL_Container<SgNode*> calls =
       NodeQuery::querySubTree(stmt, V_SgFunctionCallExp) ;

   for (Rose_STL_Container<SgNode*>::iterator c_itr = calls.begin();
           c_itr != calls.end(); ++c_itr)
   {
      SgFunctionCallExp *stmt = isSgFunctionCallExp(*c_itr) ;
      ROSE_ASSERT(stmt);

      SgFunctionRefExp *func = isSgFunctionRefExp(stmt->get_function()) ;
      if (func != NULL)
      {
         SgFunctionSymbol *funcName = func->get_symbol() ;

         if (segDB.find(funcName->get_name().getString()) == segDB.end())
         {
            containsUnknownCall = true ;
            break ;
         }
      }
      else
      {
         /* Since I can't handle this case, assume the worst -- for now */
         containsUnknownCall = true ;
         break ;
      }
   }

   return containsUnknownCall ;
}
int main( int argc, char * argv[] )
   {
  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT(project != NULL);

  // Build a list of functions within the AST
     Rose_STL_Container<SgNode*> functionCallList = NodeQuery::querySubTree (project,V_SgFunctionCallExp);

     int functionCounter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionCallList.begin(); i != functionCallList.end(); i++)
        {
          SgExpression* functionExpression = isSgFunctionCallExp(*i)->get_function();
          ROSE_ASSERT(functionExpression != NULL);

          SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionExpression);

          SgFunctionSymbol* functionSymbol = NULL;
          if (functionRefExp != NULL)
             {
            // Case of non-member function
               functionSymbol = functionRefExp->get_symbol();
             }
            else
             {
            // Case of member function (hidden in rhs of binary dot operator expression)
               SgDotExp* dotExp = isSgDotExp(functionExpression);
               ROSE_ASSERT(dotExp != NULL);

               functionExpression = dotExp->get_rhs_operand();
               SgMemberFunctionRefExp* memberFunctionRefExp = isSgMemberFunctionRefExp(functionExpression);
               ROSE_ASSERT(memberFunctionRefExp != NULL);

               functionSymbol = memberFunctionRefExp->get_symbol();
             }
          
          ROSE_ASSERT(functionSymbol != NULL);

          SgFunctionDeclaration* functionDeclaration = functionSymbol->get_declaration();
          ROSE_ASSERT(functionDeclaration != NULL);
          
       // Output mapping of function calls to function declarations
          printf ("Location of function call #%d at line %d resolved by overloaded function declared at line %d \n",
               functionCounter++,
               isSgFunctionCallExp(*i)->get_file_info()->get_line(),
               functionDeclaration->get_file_info()->get_line());
        }

     return 0;
   }
void FortranAnalysis::visit(SgFunctionCallExp * fcall)
{
   SgFunctionRefExp  * fref  = isSgFunctionRefExp(fcall->get_function());

   if (fref != NULL) {
      SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin();
      std::string name = fref->get_symbol()->get_name().getString();

      if (name == "interior" && it != fcall->get_args()->get_expressions().end()) {
         SgVarRefExp * var = isSgVarRefExp(*it);
         SgSymbol * sym = var->get_symbol();
         sym->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR"));
         debug("SgFunctionCallExp: adding halo attribute to %s\n",
                sym->get_name().getString().c_str());
      }
   }
}
Exemple #12
0
Fichier : noRand.C Projet : 8l/rose
void
CompassAnalyses::NoRand::Traversal::
visit(SgNode* node)
   {
     const int STRING_LEN_RAND = 4;

     SgFunctionRefExp *sgFuncRef = isSgFunctionRefExp( node );

     if( sgFuncRef != NULL )
     {
       std::string fncName = sgFuncRef->get_symbol()->get_name().getString();

       if( fncName.find( "rand", 0, STRING_LEN_RAND ) != std::string::npos )
       {
         output->addOutput( new CheckerOutput( node ) );
       } //if( fncName.find("vfork", 0, STRING_LEN_RAND) != std::string::npos )
     } //if( sgFuncRef != NULL )

     return;
   } //End of the visit function.
bool FortranAnalysis::matchRegionAssignment(SgExprStatement * expr_stmt)
{
   SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression());
   if (bin_op == NULL) return false;

   SgFunctionCallExp * fcall = isSgFunctionCallExp(bin_op->get_rhs_operand());
   if (fcall == NULL) return false;

   SgFunctionRefExp * fref = isSgFunctionRefExp(fcall->get_function());
   if (fref == NULL) return false;

   SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin();
   std::string name = fref->get_symbol()->get_name().getString();
   if (name == "interior" && it != fcall->get_args()->get_expressions().end()) {
      SgVarRefExp * var = isSgVarRefExp(*it);
      if (var == NULL) return false;
      AstTextAttribute * attr = (AstTextAttribute *) var->get_symbol()->getAttribute("dummy_attr");
      if (attr == NULL) return false;
      if (attr->toString() != "DUMMY_ARRAY_ARG") return false;
   }
   return true;
}
int
main( int argc, char* argv[] )
   {
  // Initialize and check compatibility. See rose::initialize
     ROSE_INITIALIZE;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                         ROSE_ASSERT(bufferLengthExpression != NULL);

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

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

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

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

     return backend(project);
   }
Exemple #15
0
StencilEvaluation_InheritedAttribute
StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundPairShiftDoubleConstructor = false;

  // This is for stencil specifications using vectors of points to represent offsets (not finished).
  // bool foundVariableDeclarationForStencilInput = false;

     double stencilCoeficientValue = 0.0;

  // StencilOffsetFSM offset;
     StencilOffsetFSM* stencilOffsetFSM = NULL;

  // We want to interogate the SgAssignInitializer, but we need to generality in the refactored function to use any SgInitializer (e.g. SgConstructorInitializer, etc.).
     SgInitializedName* initializedName = detectVariableDeclarationOfSpecificType (astNode,"Point");

     if (initializedName != NULL)
        {
       // This is the code that is specific to the DSL (e.g. the semantics of getZeros() and getUnitv() functions).
       // So this may be the limit of what can be refactored to common DSL support code.
       // Or I can maybe do a second pass at atempting to refactor more code later.

          string name = initializedName->get_name();

          SgInitializer* initializer = initializedName->get_initptr();

          SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
          if (assignInitializer != NULL)
             {
               SgExpression* exp = assignInitializer->get_operand();
               ROSE_ASSERT(exp != NULL);
               SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(exp);
               if (functionCallExp != NULL)
                  {
                    SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function());
                    if (functionRefExp != NULL)
                       {
                         SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
                         ROSE_ASSERT(functionSymbol != NULL);
                         string functionName = functionSymbol->get_name();
#if 0
                         printf ("functionName = %s \n",functionName.c_str());
#endif
                         if (functionName == "getZeros")
                            {
                           // We leverage the semantics of known functions used to initialize "Point" objects ("getZeros" initialized the Point object to be all zeros).
                           // In a stencil this will be the center point from which all other points will have non-zero offsets.
                           // For a common centered difference discretization this will be the center point of the stencil.
#if 0
                              printf ("Identified and interpreting the semantics of getZeros() function \n");
#endif
                              stencilOffsetFSM = new StencilOffsetFSM(0,0,0);
                              ROSE_ASSERT(stencilOffsetFSM != NULL);
                            }

                         if (functionName == "getUnitv")
                            {
                           // We leverage the semantics of known functions used to initialize "Point" objects 
                           // ("getUnitv" initializes the Point object to be a unit vector for a specific input dimention).
                           // In a stencil this will be an ofset from the center point.
#if 0
                              printf ("Identified and interpreting the semantics of getUnitv() function \n");
#endif
                           // Need to get the dimention argument.
                              SgExprListExp* argumentList = functionCallExp->get_args();
                              ROSE_ASSERT(argumentList != NULL);
                           // This function has a single argument.
                              ROSE_ASSERT(argumentList->get_expressions().size() == 1);
                              SgExpression* functionArg = argumentList->get_expressions()[0];
                              ROSE_ASSERT(functionArg != NULL);
                              SgIntVal* intVal = isSgIntVal(functionArg);
                           // ROSE_ASSERT(intVal != NULL);
                              if (intVal != NULL)
                                 {
                                   int value = intVal->get_value();
#if 0
                                   printf ("value = %d \n",value);
#endif
                                   switch(value)
                                      {
                                        case 0: stencilOffsetFSM = new StencilOffsetFSM(1,0,0); break;
                                        case 1: stencilOffsetFSM = new StencilOffsetFSM(0,1,0); break;
                                        case 2: stencilOffsetFSM = new StencilOffsetFSM(0,0,1); break;

                                        default:
                                           {
                                             printf ("Error: default reached in switch: value = %d (for be value of 0, 1, or 2) \n",value);
                                             ROSE_ASSERT(false);
                                           }
                                      }

                                   ROSE_ASSERT(stencilOffsetFSM != NULL);

                                // End of test for intVal != NULL
                                 }
                                else
                                 {
#if 0
                                   printf ("functionArg = %p = %s \n",functionArg,functionArg->class_name().c_str());
#endif
                                 }
                            }

                          // ROSE_ASSERT(stencilOffsetFSM != NULL);
                       }
                  }
             }

           if (stencilOffsetFSM != NULL)
             {
            // Put the FSM into the map.
#if 0
               printf ("Put the stencilOffsetFSM = %p into the StencilOffsetMap using key = %s \n",stencilOffsetFSM,name.c_str());
#endif
               ROSE_ASSERT(StencilOffsetMap.find(name) == StencilOffsetMap.end());

            // We have a choice of syntax to add the element to the map.
            // StencilOffsetMap.insert(pair<string,StencilOffsetFSM*>(name,stencilOffsetFSM));
               StencilOffsetMap[name] = stencilOffsetFSM;
             }

       // new StencilOffsetFSM();
#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }

  // Recognize member function calls on "Point" objects so that we can trigger events on those associated finite state machines.
     bool isTemplateClass = false;
     bool isTemplateFunctionInstantiation = false;
     SgInitializedName* initializedNameUsedToCallMemberFunction = NULL;
     SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Point",isTemplateClass,"operator*=",isTemplateFunctionInstantiation);
     if (functionCallExp != NULL)
        {
       // This is the DSL specific part (capturing the semantics of operator*= with specific integer values).

       // The name of the variable off of which the member function is called (variable has type "Point").
          ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL);
          string name = initializedNameUsedToCallMemberFunction->get_name();

       // Need to get the dimention argument.
          SgExprListExp* argumentList = functionCallExp->get_args();
          ROSE_ASSERT(argumentList != NULL);
       // This function has a single argument.
          ROSE_ASSERT(argumentList->get_expressions().size() == 1);
          SgExpression* functionArg = argumentList->get_expressions()[0];
          ROSE_ASSERT(functionArg != NULL);
          SgIntVal* intVal = isSgIntVal(functionArg);

          bool usingUnaryMinus = false;
          if (intVal == NULL)
             {
               SgMinusOp* minusOp = isSgMinusOp(functionArg);
               if (minusOp != NULL)
                  {
#if 0
                    printf ("Using SgMinusOp on stencil constant \n");
#endif
                    usingUnaryMinus = true;
                    intVal = isSgIntVal(minusOp->get_operand());
                  }
             }

          ROSE_ASSERT(intVal != NULL);
          int value = intVal->get_value();

          if (usingUnaryMinus == true)
             {
               value *= -1;
             }
#if 0
          printf ("value = %d \n",value);
#endif
       // Look up the stencil offset finite state machine
          ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end());
          StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name];
          ROSE_ASSERT(stencilOffsetFSM != NULL);
#if 0
          printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str());
#endif
#if 0
          stencilOffsetFSM->display("before multiply event");
#endif
          if (value == -1)
             {
            // Execute the event on the finte state machine to accumulate the state.
               stencilOffsetFSM->operator*=(-1);
             }
            else
             {
               printf ("Error: constant value other than -1 are not supported \n");
               ROSE_ASSERT(false);
             }
#if 0
          stencilOffsetFSM->display("after multiply event");
#endif
        }

  // Detection of "pair<Shift,double>(xdir,ident)" defined as an event in the stencil finite machine model.
  // Actually, it is the Stencil that is create using the "pair<Shift,double>(xdir,ident)" that should be the 
  // event so we first detect the SgConstructorInitializer.  There is not other code similar to this which 
  // has to test for the template arguments, so this has not yet refactored into the dslSupport.C file.
  // I will do this later since this is general support that could be resused in other DSL compilers.
     SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode);
     if (constructorInitializer != NULL)
        {
       // DQ (10/20/2014): This can sometimes be NULL.
       // ROSE_ASSERT(constructorInitializer->get_class_decl() != NULL);
          SgClassDeclaration* classDeclaration = constructorInitializer->get_class_decl();
       // ROSE_ASSERT(classDeclaration != NULL);
          if (classDeclaration != NULL)
             {
#if 0
          printf ("constructorInitializer = %p class name    = %s \n",constructorInitializer,classDeclaration->get_name().str());
#endif
          SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classDeclaration);
       // ROSE_ASSERT(templateInstantiationDecl != NULL);
#if 0
          if (templateInstantiationDecl != NULL)
             {
               printf ("constructorInitializer = %p name = %s template name = %s \n",constructorInitializer,templateInstantiationDecl->get_name().str(),templateInstantiationDecl->get_templateName().str());
             }
#endif

       // if (classDeclaration->get_name() == "pair")
          if (templateInstantiationDecl != NULL && templateInstantiationDecl->get_templateName() == "pair")
             {
            // Look at the template parameters.
#if 0
               printf ("Found template instantiation for pair \n");
#endif
               SgTemplateArgumentPtrList & templateArgs = templateInstantiationDecl->get_templateArguments();
               if (templateArgs.size() == 2)
                  {
                 // Now look at the template arguments and check that they represent the pattern that we are looking for in the AST.
                 // It is not clear now flexible we should be, at present shift/coeficent pairs must be specified exactly one way.

                    SgType* type_0 = templateArgs[0]->get_type();
                    SgType* type_1 = templateArgs[1]->get_type();

                    if ( type_0 != NULL && type_1 != NULL)
                       {
                         SgClassType* classType_0 = isSgClassType(type_0);
                      // ROSE_ASSERT(classType_0 != NULL);
                         if (classType_0 != NULL)
                            {
                         SgClassDeclaration* classDeclarationType_0 = isSgClassDeclaration(classType_0->get_declaration());
                         ROSE_ASSERT(classDeclarationType_0 != NULL);
#if 0
                         printf ("templateArgs[0]->get_name() = %s \n",classDeclarationType_0->get_name().str());
                         printf ("templateArgs[1]->get_type()->class_name() = %s \n",type_1->class_name().c_str());
#endif
                         bool foundShiftExpression   = false;
                         bool foundStencilCoeficient = false;

                      // We might want to be more flexiable about the type of the 2nd parameter (allow SgTypeFloat, SgTypeComplex, etc.).
                         if (classDeclarationType_0->get_name() == "Shift" && type_1->variant() == V_SgTypeDouble)
                            {
                           // Found a pair<Shift,double> input for a stencil.
#if 0
                              printf ("##### Found a pair<Shift,double>() input for a stencil input \n");
#endif
                           // *****************************************************************************************************
                           // Look at the first parameter to the pair<Shift,double>() constructor.
                           // *****************************************************************************************************
                              SgExpression* stencilOffset = constructorInitializer->get_args()->get_expressions()[0];
                              ROSE_ASSERT(stencilOffset != NULL);
#if 0
                              printf ("stencilOffset = %p = %s \n",stencilOffset,stencilOffset->class_name().c_str());
#endif
                              SgConstructorInitializer* stencilOffsetConstructorInitializer = isSgConstructorInitializer(stencilOffset);
                              if (stencilOffsetConstructorInitializer != NULL)
                                 {
                                // This is the case of a Shift being constructed implicitly from a Point (doing so more directly would be easier to make sense of in the AST).
#if 0
                                   printf ("!!!!! Looking for the stencil offset \n");
#endif
                                   ROSE_ASSERT(stencilOffsetConstructorInitializer->get_class_decl() != NULL);
                                   SgClassDeclaration* stencilOffsetClassDeclaration = stencilOffsetConstructorInitializer->get_class_decl();
                                   ROSE_ASSERT(stencilOffsetClassDeclaration != NULL);
#if 0
                                   printf ("stencilOffsetConstructorInitializer = %p class name    = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration->get_name().str());
                                   printf ("stencilOffsetConstructorInitializer = %p class = %p = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration,stencilOffsetClassDeclaration->class_name().c_str());
#endif
                                // This should not be a template instantiation (the Shift is defined to be a noo-template class declaration, not a template class declaration).
                                   SgTemplateInstantiationDecl* stencilOffsetTemplateInstantiationDecl = isSgTemplateInstantiationDecl(stencilOffsetClassDeclaration);
                                   ROSE_ASSERT(stencilOffsetTemplateInstantiationDecl == NULL);

                                   if (stencilOffsetClassDeclaration != NULL && stencilOffsetClassDeclaration->get_name() == "Shift")
                                      {
                                     // Now we know that the type associated with the first template parameter is associated with the class "Shift".
                                     // But we need so also now what the first parametr is associate with the constructor initializer, since it will
                                     // be the name of the variable used to interprete the stencil offset (and the name of the variable will be the 
                                     // key into the map of finite machine models used to accumulate the state of the stencil offsets that we accumulate
                                     // to build the stencil.

                                     // Now we need the value of the input (computed using it's fine state machine).
                                        SgExpression* inputToShiftConstructor = stencilOffsetConstructorInitializer->get_args()->get_expressions()[0];
                                        ROSE_ASSERT(inputToShiftConstructor != NULL);
                                        SgConstructorInitializer* inputToShiftConstructorInitializer = isSgConstructorInitializer(inputToShiftConstructor);
                                        if (stencilOffsetConstructorInitializer != NULL)
                                           {
                                             SgExpression* inputToPointConstructor = inputToShiftConstructorInitializer->get_args()->get_expressions()[0];
                                             ROSE_ASSERT(inputToPointConstructor != NULL);

                                          // This should be a SgVarRefExp (if we strictly follow the stencil specification rules (which are not written down yet).
                                             SgVarRefExp* inputToPointVarRefExp = isSgVarRefExp(inputToPointConstructor);
                                             if (inputToPointVarRefExp != NULL)
                                                {
#if 0
                                                  printf ("Found varRefExp in bottom of chain of constructors \n");
#endif
                                                  SgVariableSymbol* variableSymbolForOffset = isSgVariableSymbol(inputToPointVarRefExp->get_symbol());
                                                  ROSE_ASSERT(variableSymbolForOffset != NULL);
                                                  SgInitializedName* initializedNameForOffset = variableSymbolForOffset->get_declaration();
                                                  ROSE_ASSERT(initializedNameForOffset != NULL);
                                                  SgInitializer* initializer = initializedNameForOffset->get_initptr();
                                                  ROSE_ASSERT(initializer != NULL);
#if 0
                                                  printf ("Found initializedName: name = %s in bottom of chain of constructors: initializer = %p = %s \n",initializedNameForOffset->get_name().str(),initializer,initializer->class_name().c_str());
#endif
                                               // Record the name to be used as a key into the map of "StencilOffset" finite state machines.

                                                  SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
                                                  ROSE_ASSERT(assignInitializer != NULL);

                                                  string name = initializedNameForOffset->get_name();
                                               // Look up the current state in the finite state machine for the "Point".

                                               // Check that this is a previously defined stencil offset.
                                                  ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end());
                                               // StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name];
                                                  stencilOffsetFSM = StencilOffsetMap[name];
                                                  ROSE_ASSERT(stencilOffsetFSM != NULL);
#if 0
                                                  printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str());
#endif
#if 0
                                                  printf ("Exiting as a test! \n");
                                                  ROSE_ASSERT(false);
#endif
                                                }
                                               else
                                                {
                                                  printf ("What is this expression: inputToPointConstructor = %p = %s \n",inputToPointConstructor,inputToPointConstructor->class_name().c_str());
                                                  ROSE_ASSERT(false);
                                                }
                                           }
#if 0
                                        printf ("Found Shift type \n");
#endif
                                        foundShiftExpression = true;
                                      }
#if 0
                                   printf ("Exiting as a test! \n");
                                   ROSE_ASSERT(false);
#endif
                                 }
                                else
                                 {
                                // This case for the specification of a Shift in the first argument is not yet supported (need an example of this).
                                   printf ("This case of using a shift is not a part of what is supported \n");
                                 }

                           // *****************************************************************************************************
                           // Look at the second parameter to the pair<Shift,double>(first_parameter,second_parameter) constructor.
                           // *****************************************************************************************************
                              SgExpression* stencilCoeficent = constructorInitializer->get_args()->get_expressions()[1];
                              ROSE_ASSERT(stencilCoeficent != NULL);

                              SgVarRefExp* stencilCoeficentVarRefExp = isSgVarRefExp(stencilCoeficent);
                              if (stencilCoeficentVarRefExp != NULL)
                                 {
                                // Handle the case where this is a constant SgVarRefExp and the value is available in the declaration.
                                   SgVariableSymbol* variableSymbolForConstant = isSgVariableSymbol(stencilCoeficentVarRefExp->get_symbol());
                                   ROSE_ASSERT(variableSymbolForConstant != NULL);
                                   SgInitializedName* initializedNameForConstant = variableSymbolForConstant->get_declaration();
                                   ROSE_ASSERT(initializedNameForConstant != NULL);
                                   SgInitializer* initializer = initializedNameForConstant->get_initptr();
                                   ROSE_ASSERT(initializer != NULL);
                                   SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
                                   ROSE_ASSERT(assignInitializer != NULL);

                                   SgValueExp* valueExp = isSgValueExp(assignInitializer->get_operand());

                                   bool usingUnaryMinus = false;
                                // ROSE_ASSERT(valueExp != NULL);
                                   if (valueExp == NULL)
                                      {
                                        SgExpression* operand = assignInitializer->get_operand();
                                        SgMinusOp* minusOp = isSgMinusOp(operand);
                                        if (minusOp != NULL)
                                           {
#if 0
                                             printf ("Using SgMinusOp on stencil constant \n");
#endif
                                             usingUnaryMinus = true;
                                             valueExp = isSgValueExp(minusOp->get_operand());
                                           }
                                      }

                                   SgDoubleVal* doubleVal = isSgDoubleVal(valueExp);
                                // ROSE_ASSERT(doubleVal != NULL);
                                   double value = 0.0;
                                   if (doubleVal == NULL)
                                      {
                                     // Call JP's function to evaluate the constant expression.
                                        ROSE_ASSERT(valueExp == NULL);
                                        ROSE_ASSERT(stencilCoeficent != NULL);
                                        DSL_Support::const_numeric_expr_t const_expression = DSL_Support::evaluateConstNumericExpression(stencilCoeficent);
                                        if (const_expression.hasValue_ == true)
                                           {
                                             ROSE_ASSERT(const_expression.isIntOnly_ == false);
                                             value = const_expression.value_;

                                             printf ("const expression evaluated to value = %4.2f \n",value);
                                           }
                                          else
                                           {
                                             printf ("constnat value expression could not be evaluated to a constant \n");
                                             ROSE_ASSERT(false);
                                           }
                                      }
                                     else
                                      {
#if 1
                                        printf ("SgDoubleVal value = %f \n",doubleVal->get_value());
#endif
                                        value = (usingUnaryMinus == false) ? doubleVal->get_value() : -(doubleVal->get_value());
                                      }
#if 1
                                   printf ("Stencil coeficient = %f \n",value);
#endif
                                   foundStencilCoeficient = true;

                                   stencilCoeficientValue = value;
                                 }
                                else
                                 {
                                // When we turn on constant folding in the frontend we eveluate directly to a SgDoubleVal.
                                   SgDoubleVal* doubleVal = isSgDoubleVal(stencilCoeficent);
                                   if (doubleVal != NULL)
                                      {
                                        ROSE_ASSERT(doubleVal != NULL);
#if 0
                                        printf ("SgDoubleVal value = %f \n",doubleVal->get_value());
#endif
                                        double value = doubleVal->get_value();
#if 0
                                        printf ("Stencil coeficient = %f \n",value);
#endif
                                        foundStencilCoeficient = true;

                                        stencilCoeficientValue = value;
                                      }
                                     else
                                      {
                                        printf ("Error: second parameter in pair for stencil is not a SgVarRefExp (might be explicit value not yet supported) \n");
                                        printf ("   --- stencilCoeficent = %p = %s \n",stencilCoeficent,stencilCoeficent->class_name().c_str());
                                        ROSE_ASSERT(false);
                                      }
                                 }
                            }
#if 0
                         printf ("foundShiftExpression   = %s \n",foundShiftExpression   ? "true" : "false");
                         printf ("foundStencilCoeficient = %s \n",foundStencilCoeficient ? "true" : "false");
#endif
                         if (foundShiftExpression == true && foundStencilCoeficient == true)
                            {
#if 0
                              printf ("Found pair<Shift,double>() constructor expression! \n");
#endif
                              foundPairShiftDoubleConstructor = true;
                            }

                         // End of test for classType_0 != NULL
                            }
                       }
                  }
             }
            else
             {
#if 0
               printf ("This is not a SgConstructorInitializer for the pair templated class \n");
#endif
             }

          // End of test for classDeclaration != NULL
             }
        }

#if 0
     printf ("foundPairShiftDoubleConstructor = %s \n",foundPairShiftDoubleConstructor ? "true" : "false");
#endif

     if (foundPairShiftDoubleConstructor == true)
        {
       // This is the recognition of an event for one of the finite state machines we implement to evaluate the stencil at compile time.
#if 0
          printf ("In evaluateInheritedAttribute(): found pair<Shift,double>() constructor expression! \n");
          printf ("   --- stencilOffsetFSM       = %p \n",stencilOffsetFSM);
          printf ("   --- stencilCoeficientValue = %f \n",stencilCoeficientValue);
#endif
          ROSE_ASSERT(stencilOffsetFSM != NULL);

          inheritedAttribute.stencilOffsetFSM       = stencilOffsetFSM;
          inheritedAttribute.stencilCoeficientValue = stencilCoeficientValue;

#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }

  // Construct the return attribute from the modified input attribute.
     return StencilEvaluation_InheritedAttribute(inheritedAttribute);
   }
void SimpleInstrumentation::visit ( SgNode* astNode )
   {
     switch(astNode->variantT()) 
        {
          case V_SgFunctionCallExp:
             {
               SgFunctionCallExp *functionCallExp = isSgFunctionCallExp(astNode);
               SgExpression *function = functionCallExp->get_function();
               ROSE_ASSERT(function);
               switch (function->variantT())
                  {
                    case V_SgFunctionRefExp:
                       {
                         SgFunctionRefExp *functionRefExp = isSgFunctionRefExp(function);
                         SgFunctionSymbol *symbol = functionRefExp->get_symbol();
                         ROSE_ASSERT(symbol != NULL);
                         SgFunctionDeclaration *functionDeclaration = symbol->get_declaration();
                         ROSE_ASSERT(functionDeclaration != NULL);
                         if (symbol == functionSymbol)
                            {
                           // Now we know that we have found the correct function call 
                           // (even in the presence of overloading or other forms of hidding)
                           // Now fixup the symbol and type of the SgFunctionRefExp object to 
                           // reflect the new function to be called (after this we still have to 
                           // fixup the argument list in the SgFunctionCallExp.

                           // We only want to build the decalration once (and insert it into the global scope)
                           // after that we save the symbol and reuse it.
                              if (newFunctionSymbol == NULL)
                                 {
                                   SgFunctionType* originalFunctionType = isSgFunctionType(functionSymbol->get_type());
                                   ROSE_ASSERT(originalFunctionType != NULL);
                                   newFunctionSymbol = buildNewFunctionDeclaration (TransformationSupport::getStatement(astNode),originalFunctionType);
                                 }

                              ROSE_ASSERT(newFunctionSymbol != NULL);
                              ROSE_ASSERT(newFunctionSymbol->get_type() != NULL);

                              functionRefExp->set_symbol(newFunctionSymbol);
                            }

                         break;
                       }
                    default:
                         cerr<<"warning: unrecognized variant: "<<function->class_name();
                  }
               break;
             }

          case V_SgFunctionDeclaration:
             {
               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(astNode);
               string functionName = functionDeclaration->get_name().str();
               if (functionName == "send")
                  {
                    SgFunctionType *functionType = functionDeclaration->get_type();
                    ROSE_ASSERT(functionType != NULL);
                    bool foundFunction = false;
                    if (functionType->get_return_type()->unparseToString() == "ssize_t")
                       {
                         SgTypePtrList & argumentList = functionType->get_arguments();
                         SgTypePtrList::iterator i = argumentList.begin();
                         if ( (*i++)->unparseToString() == "int" )
                              if ( (*i++)->unparseToString() == "const void *" )
                                   if ( (*i++)->unparseToString() == "size_t" )
                                        if ( (*i++)->unparseToString() == "int" )
                                             foundFunction = true;
                       }

                    if (foundFunction == true)
                       {
                      // Now get the sysmbol using functionType
                         SgScopeStatement *scope = functionDeclaration->get_scope();
                         ROSE_ASSERT(scope != NULL);
                         functionSymbol = scope->lookup_function_symbol (functionName,functionType);
                       }
                  }
               break;
             }
          default:
             {
            // No other special cases
             }
        }
   }
void ControlDependenceGraph::_buildInterprocedural()
{


    // Go through the SGNODE dependence nodes and create the appropriate
    // call site nodes, entry nodes etc.

    SgFunctionDefinition *func = isSgFunctionDefinition(_head);

    ROSE_ASSERT(func != NULL);

    // First create the entry node for the procedure
    _interprocedural->procedureEntry.entry =
        new DependenceNode(DependenceNode::ENTRY, func->get_declaration());
    DependenceNode *entry = createNode(_interprocedural->procedureEntry.entry);

    // Link the entry node up with all the nodes in the CDG which do not have
    // predecessors
    for (set < SimpleDirectedGraphNode * >::iterator i = _nodes.begin(); i != _nodes.end(); i++)
    {
        DependenceNode *node = dynamic_cast < DependenceNode * >(*i);

        if ((node->numPredecessors() == 0) && (node != entry))
        {
            establishEdge(entry, node);
        }
    }

    // create a formal out return argument, control dependent on the entry
    // node
    string return_name = func->get_declaration()->get_name().str();

    return_name = return_name + " return";
    _interprocedural->procedureEntry.formal_return =
        new DependenceNode(DependenceNode::FORMALOUT, return_name);
    DependenceNode *formal_return = createNode(_interprocedural->procedureEntry.formal_return);

    establishEdge(entry, formal_return);

    // for each of the arguments in the function parameter list, add a
    // formal-in and formal-out node
    SgFunctionParameterList *paramlist = func->get_declaration()->get_parameterList();
    SgInitializedNamePtrList params = paramlist->get_args();

    for (SgInitializedNamePtrList::iterator i = params.begin(); i != params.end(); i++)
    {
        SgInitializedName *name = *i;
        DependenceNode *formal_in = new DependenceNode(DependenceNode::FORMALIN,
                                                       name->get_name().str());
        DependenceNode *formal_out = new DependenceNode(DependenceNode::FORMALOUT,
                                                        name->get_name().str());

        establishEdge(entry, createNode(formal_in));
        establishEdge(entry, createNode(formal_out));
        _interprocedural->procedureEntry.formal_in[name] = formal_in;
        _interprocedural->procedureEntry.formal_out[name] = formal_out;

        // To preserve the order of arguments, we insert them into arg_order
        _interprocedural->procedureEntry.arg_order.push_back(name);
    }

    // Now we go through each of the SgNodes in our CDG. If any of them
    // contain a function call, we want to build a call site node for them.
    map < SgNode *, DependenceNode * >::iterator sgnode_iterator;
    for (sgnode_iterator = _sgnode_map.begin();
         sgnode_iterator != _sgnode_map.end(); sgnode_iterator++)
    {
        SgNode *currnode = sgnode_iterator->first;

        list < SgFunctionCallExp * >calls = InterproceduralInfo::extractFunctionCalls(currnode);
        if (calls.empty())
            continue;

        for (list < SgFunctionCallExp * >::iterator i = calls.begin(); i != calls.end(); i++)
        {
            SgFunctionCallExp *call = *i;

            // This needs to be replaced with some call graph analysis
            SgFunctionRefExp *func = isSgFunctionRefExp(call->get_function());

            ROSE_ASSERT(func != NULL);
            SgName func_name = func->get_symbol()->get_name();

            InterproceduralInfo::CallSiteStructure callstructure;
            callstructure.callsite = new DependenceNode(DependenceNode::CALLSITE, call);
            // the call site is control dependent on the statement (i.e. for
            // the call site to happen, the statement must be executed)
            DependenceNode *callsite = createNode(callstructure.callsite);

            // addLink(callsite, getNode(currnode));
            establishEdge(getNode(currnode), callsite);

            // create an actual out node for the return value, control
            // dependent on callsite
            string return_name = func_name.str();

            return_name = return_name + " return";
            callstructure.actual_return =
                new DependenceNode(DependenceNode::ACTUALOUT, return_name);
            DependenceNode *actual_return = createNode(callstructure.actual_return);

            establishEdge(callsite, actual_return);

            // For each argument in the function call, build an actual_in and
            // actual_out, control dependent on callsite
            SgExpressionPtrList args = call->get_args()->get_expressions();

            for (SgExpressionPtrList::iterator j = args.begin(); j != args.end(); j++)
            {
                SgExpression *arg = *j;
                DependenceNode *actual_in = new DependenceNode(DependenceNode::ACTUALIN, arg);
                DependenceNode *actual_out = new DependenceNode(DependenceNode::ACTUALOUT, arg);

                establishEdge(callsite, createNode(actual_in));
                establishEdge(callsite, createNode(actual_out));
                callstructure.actual_in[arg] = actual_in;
                callstructure.actual_out[arg] = actual_out;

                // To preserve the order of expressions in the parameter list, 
                // 
                // we insert them into expr_order
                callstructure.expr_order.push_back(arg);
            }

            // add the callstructure to interprocedural info
            _interprocedural->callsite_map[call] = callstructure;
        }
    }
}
set<SgInitializedName*> computeLiveVars(SgStatement* stmt, const X86CTranslationPolicy& conv, map<SgLabelStatement*, set<SgInitializedName*> >& liveVarsForLabels, set<SgInitializedName*> currentLiveVars, bool actuallyRemove) {
  switch (stmt->variantT()) {
    case V_SgBasicBlock: {
      const SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements();
      for (size_t i = stmts.size(); i > 0; --i) {
        currentLiveVars = computeLiveVars(stmts[i - 1], conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      }
      return currentLiveVars;
    }
    case V_SgPragmaDeclaration: return currentLiveVars;
    case V_SgDefaultOptionStmt: return currentLiveVars;
    case V_SgCaseOptionStmt: {
      return computeLiveVars(isSgCaseOptionStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
    }
    case V_SgLabelStatement: {
      liveVarsForLabels[isSgLabelStatement(stmt)] = currentLiveVars;
      return currentLiveVars;
    }
    case V_SgGotoStatement: {
      return liveVarsForLabels[isSgGotoStatement(stmt)->get_label()];
    }
    case V_SgSwitchStatement: {
      SgSwitchStatement* s = isSgSwitchStatement(stmt);
      SgBasicBlock* swBody = isSgBasicBlock(s->get_body());
      ROSE_ASSERT (swBody);
      const SgStatementPtrList& bodyStmts = swBody->get_statements();
      set<SgInitializedName*> liveForBody; // Assumes any statement in the body is possible
      for (size_t i = 0; i < bodyStmts.size(); ++i) {
        setUnionInplace(liveForBody, computeLiveVars(bodyStmts[i], conv, liveVarsForLabels, currentLiveVars, actuallyRemove));
      }
      return computeLiveVars(s->get_item_selector(), conv, liveVarsForLabels, liveForBody, actuallyRemove);
    }
    case V_SgContinueStmt: {
      return makeAllPossibleVars(conv);
    }
    case V_SgIfStmt: {
      set<SgInitializedName*> liveForBranches = computeLiveVars(isSgIfStmt(stmt)->get_true_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      setUnionInplace(liveForBranches, (isSgIfStmt(stmt)->get_false_body() != NULL ? computeLiveVars(isSgIfStmt(stmt)->get_false_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove) : set<SgInitializedName*>()));
      return computeLiveVars(isSgIfStmt(stmt)->get_conditional(), conv, liveVarsForLabels, liveForBranches, actuallyRemove);
    }
    case V_SgWhileStmt: {
      while (true) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, false);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, false);
        setUnionInplace(currentLiveVars, liveVarsSave);
        if (liveVarsSave == currentLiveVars) break;
      }
      if (actuallyRemove) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, true);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, true);
        setUnionInplace(currentLiveVars, liveVarsSave);
      }
      return currentLiveVars;
    }
    case V_SgBreakStmt: return set<SgInitializedName*>();
    case V_SgExprStatement: {
      SgExpression* e = isSgExprStatement(stmt)->get_expression();
      switch (e->variantT()) {
        case V_SgAssignOp: {
          SgVarRefExp* lhs = isSgVarRefExp(isSgAssignOp(e)->get_lhs_operand());
          ROSE_ASSERT (lhs);
          SgInitializedName* in = lhs->get_symbol()->get_declaration();
          if (currentLiveVars.find(in) == currentLiveVars.end()) {
            if (actuallyRemove) {
              // cerr << "Removing assignment " << e->unparseToString() << endl;
              isSgStatement(stmt->get_parent())->remove_statement(stmt);
            }
            return currentLiveVars;
          } else {
            currentLiveVars.erase(in);
            getUsedVariables(isSgAssignOp(e)->get_rhs_operand(), currentLiveVars);
            return currentLiveVars;
          }
        }
        case V_SgFunctionCallExp: {
          getUsedVariables(e, currentLiveVars);
          SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
          ROSE_ASSERT (fr);
          if (fr->get_symbol()->get_declaration() == conv.interruptSym->get_declaration()) {
            setUnionInplace(currentLiveVars, makeAllPossibleVars(conv));
            return currentLiveVars;
          } else {
            return currentLiveVars;
          }
        }
        default: {
          getUsedVariables(e, currentLiveVars);
          return currentLiveVars;
        }
      }
    }
    case V_SgVariableDeclaration: {
      ROSE_ASSERT (isSgVariableDeclaration(stmt)->get_variables().size() == 1);
      SgInitializedName* in = isSgVariableDeclaration(stmt)->get_variables()[0];
      bool isConst = isConstType(in->get_type());
      if (currentLiveVars.find(in) == currentLiveVars.end() && isConst) {
        if (actuallyRemove) {
          // cerr << "Removing decl " << stmt->unparseToString() << endl;
          isSgStatement(stmt->get_parent())->remove_statement(stmt);
        }
        return currentLiveVars;
      } else {
        currentLiveVars.erase(in);
        if (in->get_initializer()) {
          getUsedVariables(in->get_initializer(), currentLiveVars);
        }
        return currentLiveVars;
      }
    }
    default: cerr << "computeLiveVars: " << stmt->class_name() << endl; abort();
  }
}
Exemple #19
0
Fichier : mlm.cpp Projet : 8l/rose
void mlmTransform::transformCallExp(SgCallExpression* callExp)
{
    ROSE_ASSERT(callExp);
    SgFunctionRefExp* funcName = isSgFunctionRefExp(callExp->get_function());
    if(!funcName) 
      return;
    SgExprListExp* funcArgList = callExp->get_args();
    SgExpressionPtrList argList = funcArgList->get_expressions();
    SgScopeStatement* scope = getScope(callExp);         
    //cout << funcName->get_symbol()->get_name() << endl;

    /** if it is malloc, search for the mlm attribute and append the memory level **/
    if(strncmp("malloc",funcName->get_symbol()->get_name().str(),6) == 0)
    {
      if(argList.size() != 1)  return;
      SgExprListExp* funcArgList = callExp->get_args();

      // check if LHS of malloc has an attribute assigned
      SgNode* parentNode = callExp->get_parent();
      // parent node can be a casting expression
      if(isSgCastExp(parentNode))
      {
        parentNode = parentNode->get_parent();
      }
      // the mlm attribute
      AstAttribute* attr = NULL;
      // So far we spot two candidates for parentNode that we need to transform
      if(isSgAssignOp(parentNode))
      {
        SgAssignOp* assignOp = isSgAssignOp(parentNode);
        SgExpression* lhs = isSgExpression(assignOp->get_lhs_operand());
        if(!isSgVarRefExp(lhs))
        {
          //cout << "lhs:" << assignOp->get_lhs_operand()->class_name() << endl;

          // if pointer is packaged inside a struct, then we need to look down in lhs.
          if(isSgDotExp(lhs))
          {
            lhs = isSgDotExp(lhs)->get_rhs_operand();
          }
        }
        SgVarRefExp* lhsVarRef = isSgVarRefExp(lhs);
        ROSE_ASSERT(lhsVarRef);
        SgSymbol* symbol = lhsVarRef->get_symbol();
        ROSE_ASSERT(symbol);
        //retrieve the attribute from symbol
        attr = symbol->getAttribute("mlmAttribute");
        //cout << "LHS symbol name: " << symbol->get_name() << endl;
      }
      else if(isSgAssignInitializer(parentNode))
      {
        SgInitializedName* initName = isSgInitializedName(parentNode->get_parent());
        ROSE_ASSERT(initName);
        SgSymbol* symbol = initName->get_symbol_from_symbol_table();
        if(!symbol) return;
        ROSE_ASSERT(symbol);
        //retrieve the attribute from symbol
        attr = symbol->getAttribute("mlmAttribute");
        //cout << "Initialized symbol name: " << symbol->get_name() << endl;
      }
      else
      {
        // do nothing because no attribute assigned or we always set to default
      }
      // if there is a mlm attribute attached to the symbol, then create new malloc
      if(attr)
      {
        mlmAttribute* mlmAttr = dynamic_cast<mlmAttribute*> (attr);
        SgExprListExp* funcArgList = callExp->get_args();
        funcArgList->append_expression(buildIntVal(mlmAttr->getMemType()));
        replaceExpression(callExp, buildFunctionCallExp("mlm_malloc",deepCopy(callExp->get_type()),deepCopy(funcArgList),getScope(callExp)));
      }
    }
    else if(strncmp("memcpy",funcName->get_symbol()->get_name().str(),6) == 0)
    {
//      cout << "replacing memcpy" << endl;
      if(argList.size() != 3)  return;
      Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(funcArgList, V_SgVarRefExp);
      SgVarRefExp* dst = isSgVarRefExp(varList[0]);
      SgVarRefExp* src = isSgVarRefExp(varList[1]);
      AstAttribute* attrDst = dst->get_symbol()->getAttribute("mlmAttribute");
      AstAttribute* attrSrc = src->get_symbol()->getAttribute("mlmAttribute");
      mlmAttribute* mlmAttrDst =  dynamic_cast<mlmAttribute*>(attrDst);
      mlmAttribute* mlmAttrSrc =  dynamic_cast<mlmAttribute*>(attrSrc);
//      if((mlmAttrDst && !mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() < mlmAttrDst->getMemType())))
//      {
//        replaceExpression(callExp, buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),true);
//        DeletepragmasList2.push_back(callExp);
//      }
//
//      else if((!mlmAttrDst && mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() > mlmAttrDst->getMemType())))

// 09/30/14 Following Simon's suggestion, we always insert wait for the mlm_memcpy
//      {
         string tagName = generateUniqueVariableName(scope,"copy_tag");
         SgVariableDeclaration* newDecl = buildVariableDeclaration(tagName,
                                          buildOpaqueType("mlm_Tag",getGlobalScope(callExp)), 
                                          buildAssignInitializer(buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope)));
         SgExprStatement* waitStmt = buildFunctionCallStmt("mlm_waitComplete",
                                                           buildVoidType(),
                                                           buildExprListExp(buildVarRefExp(tagName,scope)),
                                                           scope); 
         insertStatement(getEnclosingStatement(callExp),newDecl,true);
         insertStatement(getEnclosingStatement(callExp),waitStmt,true);
         removeStatement(getEnclosingStatement(callExp));
//      }
    }
    else if(strncmp("free",funcName->get_symbol()->get_name().str(),4) == 0)
    {
//      cout << "replacing free" << endl;
      if(argList.size() != 1)  return;
      SgExpression* varExp = isSgExpression(argList[0]);
//cout << "exp:" << varExp->class_name() << endl;
      if(!isSgVarRefExp(varExp))
      {
        if(isSgCastExp(varExp))
        {
          varExp = isSgCastExp(varExp)->get_operand_i();
        }
        // if pointer is packaged inside a struct, then we need to look down in lhs.
        if(isSgDotExp(varExp))
        {
          varExp = isSgDotExp(varExp)->get_rhs_operand();
        }
      }
      SgVarRefExp* varRef = isSgVarRefExp(varExp);
      ROSE_ASSERT(varRef);
      AstAttribute* attr = varRef->get_symbol()->getAttribute("mlmAttribute");
      if(attr)
      {
        replaceExpression(callExp, buildFunctionCallExp("mlm_free",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),false);
      }
    }

}