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 #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 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();
		}

	}
}
    bool findCallsWithFuncArgs2(SgNode *node, string &str) {		
	SgExprStatement *statement;
	if (statement = isSgExprStatement(node)) {
	    SgFunctionCallExp *call_exp;	
            if (call_exp = isSgFunctionCallExp(statement->get_the_expr())) {
                m_nodes.clear(); m_nodes.insert(call_exp);
                m_domain.expand(&m_nodes, QRQueryDomain::all_children);
                m_domain.getNodes()->erase(call_exp);
                NodeQuery::VariantVector vector (V_SgFunctionCallExp);
                QRQueryOpVariant op(vector);
                op.performQuery(&m_domain, &m_range);
                unsigned hits = m_range.countRange();
                if (hits) {
                    set<SgNode *> *rnodes = m_range.getNodes();
                    for (set<SgNode *>::iterator iter = rnodes->begin();
                         iter != rnodes->end(); )
                    {
                        SgFunctionCallExp *exp = (SgFunctionCallExp *) *iter; iter++;
                        SgExpression *funcexpr = exp->get_function();
                        str += funcexpr->unparseToString();
                        if (iter != rnodes->end()) {
                            str += ", ";
                        } 
                    }
                    return true;
                }
            }
	}
	
	return false;
    }
Exemple #5
0
void
CompassAnalyses::DiscardAssignment::Traversal::
visit(SgNode* node)
   { 
     if (isSgAssignOp(node))
     {
       // simple case: the parent of a "real" assignment op must be an
       // expression statement
       if (!isSgExprStatement(node->get_parent()))
       {
         output->addOutput(new CheckerOutput(node));
       }
       else
       {
         // not so simple case: the parent is an expression statement, but if
         // that statement is an if/loop condition, we still want to complain
         SgNode *assignment = node->get_parent();
         SgNode *p = assignment->get_parent();
         SgDoWhileStmt *dws;
         SgForStatement *fs;
         SgIfStmt *is;
         SgSwitchStatement *ss;
         SgWhileStmt *ws;

         if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
       }
     }
     else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node))
     {
       // not so simple case: call to operator= member function that is not an
       // expression statement by itself
       SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent());
       if (call && !isSgExprStatement(call->get_parent())
        && mf->get_parent() == call->get_function()
        && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0)
       {
         output->addOutput(new CheckerOutput(call));
       }
     }
   } //End of the visit function.
Exemple #6
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 ;
}
/*
 *  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);
      }
    }
  }
}
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;
}
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.
void
FunctionCallNormalization::visit( SgNode *astNode )
   {
     SgStatement *stm = isSgStatement( astNode );

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

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

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

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

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

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

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

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

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

                 bool pointerTypeNeeded = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

             // for ForStatements, replace expressions in condition and increment expressions,
             // not in the body, since those get replace later
             if ( forStm )
               {
         // SgExpressionRoot *testExp = forStm->get_test_expr_root(), *incrExp = forStm->get_increment_expr_root();
            SgExpression *testExp = forStm->get_test_expr(), *incrExp = forStm->get_increment();
            replaceFunctionCallsInExpression( incrExp, fct2Var );
            replaceFunctionCallsInExpression( testExp, fct2Var );
               }
             else
               if ( swStm )
             {
            // DQ (11/23/2005): Fixed SgSwitch to permit use of declaration for conditional
            // replaceFunctionCallsInExpression( swStm->get_item_selector_root(), fct2Var );
               replaceFunctionCallsInExpression( swStm->get_item_selector(), fct2Var );
             }
               else
             replaceFunctionCallsInExpression( stm, fct2Var );
           }
       } // end if isSgStatement block
   }
Exemple #11
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);
   }
Exemple #12
0
InheritedAttribute
visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute)
   {
    Sg_File_Info* s = n->get_startOfConstruct();
    Sg_File_Info* e = n->get_endOfConstruct();
    Sg_File_Info* f = n->get_file_info();
    for(int x=0; x < inheritedAttribute.depth; ++x) {
        printf(" ");
    }
    if(s != NULL && e != NULL && !isSgLabelStatement(n)) { 
        printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(),  verbose ? n->unparseToString().c_str() : "" );
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
        SgExprStatement * exprStmt = isSgExprStatement(n);
        if(exprStmt != NULL) {
            printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name());           
            SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression());
            if(fcall != NULL) {
               SgExpression * funcExpr = fcall->get_function();
               if(funcExpr != NULL) {
                    printf(" [function expr: %s]", funcExpr->class_name().c_str());
               }
               SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration();
               if(fdecl != NULL) {
                    printf(" [called function: %s]", fdecl->get_name().str());
               }
            }
        }
        if(isSgFunctionDeclaration(n)) {
            printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str());
        }
        SgStatement * sgStmt = isSgStatement(n);
        if(sgStmt != NULL) {
            printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope());
        }
        //SgLabelStatement * lblStmt = isSgLabelStatement(n);
        //if(lblStmt != NULL) {
        //    SgStatement * lblStmt2 = lblStmt->get_statement();
        //}
    } else if (f != NULL) {
		SgInitializedName * iname = isSgInitializedName(n);
		if(iname != NULL) {
            SgType* inameType = iname->get_type();
			printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str());
			SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent());
			if(ds != NULL) {
				if(ds->get_declarationModifier().get_storageModifier().isStatic()) {
					printf(" static");
				}
			}
			
			SgArrayType * art = isSgArrayType(iname->get_type());
			if(art != NULL) {
				printf(" %d", art->get_rank());
			}
			
			printf("]");
            if(isSgAsmDwarfConstruct(n)) {
                printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
            }
            } else {
        	printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : "");
		}
    } else {
        printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : "");
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
    }
    printf(" succ# %lu", n->get_numberOfTraversalSuccessors());
	printf("\n");
     return InheritedAttribute(inheritedAttribute.depth+1);
   }
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;
        }
    }
}
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
             }
        }
   }
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);
   }