Example #1
0
void CudaOptimizer::applyRegisterOpt(SgFunctionDeclaration* kernel,
				     std::set<SgInitializedName*> readOnlyVars,
				     const MintArrFreqPairList_t& candidateVarsShared,
				     const MintArrFreqPairList_t& candidateVarsReg,
				     const bool optUnrollZ) 
{
  //perform register optimizations, go through each element in the candidate list
  //the list is in decending order based on the number of references
  
  bool optShared = MintOptions::GetInstance()->isSharedOpt();

  MintArrFreqPairList_t::const_iterator it;   
  for(it = candidateVarsReg.begin(); it != candidateVarsReg.end(); it++)
    {
      MintArrFreqPair_t apair = (*it); 
      
      SgInitializedName* array = apair.first;
      ROSE_ASSERT(array);
      
      int freq = apair.second; 
      
      MintArrFreqPairList_t::const_iterator it2; 

      bool alsoShared = false;

      for(it2 = candidateVarsShared.begin(); it2 != candidateVarsShared.end(); it2++){
	  SgInitializedName* name = (*it2).first;

	  if(name == array){
	    alsoShared = true; break;
	  }
	}

      //if we slide the planes, we perform the register opt to that variable later
      //but if shared is ON, unroll is false, then we still perform register opt first
      //TODO: Check if that includes the shared memory opt only ? Yes, shared should be ON to skip this opt      
       if( optShared && alsoShared  && optUnrollZ ){
	continue;
      }

      //TODO: should I put a limit about how many variables should be put into the registers?
      if(freq > 0 ) //should I set it to 1?
	{
	  cout << "  INFO:Mint: Candidate variable for register opt ("<< array->get_name().str() << ")";
	  cout << " with # of refs : "<< freq<< endl ; 	      
	  cout << "  INFO:Mint: Applying register optimization to array ("<< array->get_name().str() << ")"<< endl;
	  OnChipMemoryOpt::registerOptimizer(readOnlyVars, kernel, array);
	}

      //We want to put that variable in register, if we apply shared memory optimization
      else if(alsoShared && optShared )
	{
	  cout << "  INFO:Mint: Candidate variable for register opt ("<< array->get_name().str() << ")";
	  cout << " with # of refs : "<< freq<< endl ; 	      
	  cout << "  INFO:Mint: Applying register optimization to array ("<< array->get_name().str() << ")"<< endl;
	  OnChipMemoryOpt::registerOptimizer(readOnlyVars, kernel, array, NULL, true);
	}

    }//end of for 
}
Example #2
0
File: DCL.C Project: 8l/rose
/**
 * Use visually distinct identifiers 
 *
 * \note also checks DCL31-C
 */
bool DCL02_C( const SgNode *node ) {
	static std::map<const SgScopeStatement *, std::set<std::string> > scopeMap;
	static std::map<std::string, const SgInitializedName *> strVarMap;

	const SgScopeStatement *scope = isSgScopeStatement(node);
	if (!scope)
		return false;

	bool violation = false;

	if (isSgGlobal(scope)) {
		std::set<std::string> externNames;

		/** populate scopeMap */
		FOREACH_SUBNODE(scope, nodes, i, V_SgInitializedName) {
			SgInitializedName *var = isSgInitializedName(*i);
			assert(var);
			if (isCompilerGeneratedNode(var)
			|| !isSgDeclarationStatement(var->get_parent())
			|| findParentOfType(var, SgCtorInitializerList)
			|| findParentOfType(var, SgClassDeclaration) // Might be too strong
			|| var->get_name().getString().empty()
			|| (var->get_name().getString().substr(0,2) == "__"))
				continue;

			/** Ignore function prototypes */
			const SgFunctionDeclaration * fnDecl = findParentOfType(var, SgFunctionDeclaration);
			if (fnDecl && !fnDecl->get_definition())
				continue;

			if (isExternVar(var)) {
				if (externNames.find(var->get_name().getString()) != externNames.end())
					continue;

				externNames.insert(var->get_name().getString());
			}

			const SgScopeStatement *varScope = var->get_scope();
			std::string str (normalize_string(var->get_name().str(), isExternVar(var)));
			if (scopeMap[varScope].find(str) != scopeMap[varScope].end()) {
				DCL02_report_error(var);
				violation = true;
			} else {
				scopeMap[varScope].insert(str);
				strVarMap[str] = var;
			}
		}
		return false;
	}
Example #3
0
void visitorTraversal::visit(SgNode* n)
   {
  // There are three types ir IR nodes that can be queried for scope:
  //   - SgStatement, and 
  //   - SgInitializedName
     SgStatement* statement = isSgStatement(n);
     if (statement != NULL)
        {
          SgScopeStatement* scope = statement->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgStatement       = %12p = %30s has scope = %12p = %s (total number = %d) \n",
               statement,statement->class_name().c_str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }

     SgInitializedName* initializedName = isSgInitializedName(n);
     if (initializedName != NULL)
        {
          SgScopeStatement* scope = initializedName->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgInitializedName = %12p = %30s has scope = %12p = %s (total number = %d)\n",
               initializedName,initializedName->get_name().str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }
   }
// Check if this is an A++ Array Reference
bool isAPPArray(SgNode *astNode) {

	SgVarRefExp* varRefExp = isSgVarRefExp(astNode);

	if (varRefExp == NULL)
		return false;

	SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
	ROSE_ASSERT(variableSymbol != NULL);
	SgInitializedName* initializedName = variableSymbol->get_declaration();
	ROSE_ASSERT(initializedName != NULL);
	SgName variableName = initializedName->get_name();

	// Now compute the offset to the index objects (form a special query for this???)

	SgType* type = variableSymbol->get_type();
	ROSE_ASSERT(type != NULL);

	string typeName = TransformationSupport::getTypeName(type);
	ROSE_ASSERT(typeName.c_str() != NULL);

	// Recognize only these types at present
	if (typeName == "intArray" || typeName == "floatArray" || typeName == "doubleArray") {
		return true;
	}

	return false;
}
/*
 *  Fix OP function calls and inject debug names
 */
void OPSource::fixOpStructs(SgNode *n)
{
  SgInitializedName* initname = isSgInitializedName(n);
  if(initname)
  {
    string var_name = initname->get_name().getString();
    SgConstructorInitializer *initer = isSgConstructorInitializer(initname->get_initializer());
    if(initer)
    {
      string class_name = initer->get_class_decl()->get_name().getString();
      if(class_name.find("op_dat") != string::npos
          || class_name.find("op_dat_gbl") != string::npos
          || class_name.compare("_op_ptr") == 0 
          || class_name.compare("_op_set") == 0 
          || class_name.compare("_op_dat_const") == 0)
      {
        cout << "---Injecting Debug Name: " << var_name << "---" << endl;
        SgExprListExp* list = initer->get_args();
        SgExpressionPtrList &exprs = list->get_expressions();
        if( isSgStringVal(exprs.back()) == NULL )
        {
          list->append_expression(buildStringVal(var_name));
        }
      }
    }
  }
}
Example #6
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameUnionFieldNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

// SgNode *sageReturnNode = NULL;

  SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode);

  if (sageClassDefinition != NULL)
    {
      ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL);
      if (sageClassDefinition->get_declaration ()->get_class_type () ==
          SgClassDeclaration::e_struct)
        {
          SgDeclarationStatementPtrList declarationStatementPtrList =
            sageClassDefinition->get_members ();

        typedef SgDeclarationStatementPtrList::iterator LI;

        for (LI i = declarationStatementPtrList.begin ();
             i != declarationStatementPtrList.end (); ++i)
          {
            SgNode *listElement = *i;

            SgVariableDeclaration *sageVariableDeclaration =
              isSgVariableDeclaration (listElement);

            if (sageVariableDeclaration != NULL)
              {


                typedef SgInitializedNamePtrList::iterator INITLI;

                SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables ();

                for (INITLI i = sageInitializedNameList.begin ();
                     i != sageInitializedNameList.end (); ++i)
                  {
                    SgInitializedName* initializedListElement = *i;
                    ROSE_ASSERT (isSgInitializedName (initializedListElement) != NULL);

                    returnNameList.push_back (initializedListElement->get_name().str());

                  }             /* End iteration over declarationStatementPtrList */

              }                 /* End iteration over declarationStatementPtrList */
          }

        }
    }

  return returnNameList;

}                               /* End function queryUnionFieldNames() */
void BasicProgmemTransform::convertVarDeclToProgmemDecl(SgVariableDeclaration *varDecl) {
	printf("converting %s\n", varDecl->unparseToString().c_str());
	std::string dec = "const char ";
	SgInitializedName *initName = varDecl->get_variables()[0];
	std::string literal = isSgAssignInitializer(initName->get_initializer())->get_operand()->unparseToString();
	dec += initName->get_name().getString() + "[] PROGMEM =" + literal + ";";
	insertPreprocessingInfo(dec);
	SageInterface::removeStatement(varDecl, true);
}
int main(int argc, char** argv) {

   SgProject* proj = frontend(argc, argv);

  // Set up the struct layout chain
  initUpcSizes(); 
  CustomizedPrimitiveTypeLayoutGenerator gen1_upc(NULL,&upc_sizes);
  NonpackedTypeLayoutGenerator gen_upc(&gen1_upc);

  // Process every type used in a variable or parameter declaration
  vector<SgNode*> initNames = NodeQuery::querySubTree(proj, V_SgInitializedName);
  for (size_t i = 0; i < initNames.size(); ++i) {
    SgInitializedName* in = isSgInitializedName(initNames[i]);
    SgType* t = in->get_type();
    if (isSgTypeEllipse(t)) continue;
    cout << in->get_name().getString() << " has type " << t->unparseToString() << ":\n";
    cout << "For a customized UPC platform:\n";
    cout << gen_upc.layoutType(t) << "\n";
    size_t size = gen_upc.layoutType(t).size;
    size_t element_size=size;
    if (isSgArrayType(t)) 
      element_size = gen_upc.layoutType(
                SageInterface::getArrayElementType(isSgArrayType(t))).size;

#if 0
    if (isSgArrayType(t))
    {
      cout<<"Found an array, output its element type info."<<endl;
      cout<< gen_upc.layoutType(SageInterface::getArrayElementType(isSgArrayType(t)))<<endl;
      // Array of shared UPC elements

    }
#endif    
    if (isUpcSharedType(t))
    { 
      size_t block_bytes = SageInterface::getUpcSharedBlockSize(t);
      if (!isSgArrayType(t) || block_bytes == 0)
        { block_bytes = size; }
      else
        {block_bytes = min (block_bytes*element_size, size);}
      size_t num_blocks = (size % block_bytes==0)?(size/block_bytes):size/block_bytes +1;
      int hasThreads=0;
      if (isSgArrayType(t))
        if (isUpcArrayWithThreads(isSgArrayType(t)))
          hasThreads =1;

      cout<<"Found a shared UPC type: block bytes="<<block_bytes
          <<" Number of block="<<num_blocks
          <<" Multiply by THREADS="<<hasThreads
          <<" Element size="<<element_size
          <<endl;
    } // UPC shared types

  } // end for
  return 0;
}
Example #9
0
File: RoseToTerm.C Project: 8l/rose
/**
 * class: SgVarRefExp
 * term: var_ref_exp_annotation(tpe,name,static,scope)
 * arg tpe: type
 * arg name: name
 * arg static: wether the declaration was static
 * arg scope: scope name (either from a namespace, a class or "null")
 */
PrologCompTerm* 
RoseToTerm::getVarRefExpSpecific(SgVarRefExp* vr) {
  SgInitializedName* n = vr->get_symbol()->get_declaration();
  /* type: in general, this can be taken "as is" from the ROSE AST. However,
   * ROSE (up to 0.9.4a-8xxx at least) gets a detail wrong: a declaration
   * like "int arr[]" as a function parameter declares a *pointer*, not an
   * array. Thus we check whether the variable might be of this sort, and if
   * yes, we must make a pointer type for it. */
  PrologTerm* typeSpecific = NULL;
  SgInitializedName* vardecl = vr->get_symbol()->get_declaration();
  SgType* t = vr->get_type()->stripType(SgType::STRIP_MODIFIER_TYPE
                                      | SgType::STRIP_REFERENCE_TYPE
                                      | SgType::STRIP_TYPEDEF_TYPE);
  if (isSgFunctionParameterList(vardecl->get_parent()) && isSgArrayType(t)) {
    SgType* baseType = isSgArrayType(t)->get_base_type();
    PrologTerm* baseTypeSpecific = getTypeSpecific(baseType);
    typeSpecific = new PrologCompTerm("pointer_type", /*1,*/ baseTypeSpecific);
  } else {
    typeSpecific = getTypeSpecific(n->get_typeptr());
  }
  /* static? (relevant for unparsing if scope is a class)*/
  PrologTerm *isStatic;
  SgDeclarationStatement* vdec = n->get_declaration();
  if (vdec != NULL) {
    isStatic = 
      getEnum(vdec->get_declarationModifier().get_storageModifier().isStatic(),
	      re.static_flags);
  } else {
    isStatic = getEnum(0, re.static_flags);
  }
  PrologTerm* scope;
  if (vdec != NULL) {
    /* named scope or irrelevant?*/
    if (SgNamespaceDefinitionStatement* scn = 
	isSgNamespaceDefinitionStatement(vdec->get_parent())) {
      scope = getNamespaceScopeName(scn);
    } else if (SgClassDefinition* scn = 
	       isSgClassDefinition(vdec->get_parent())) {
      scope = getClassScopeName(scn);
    } else {
      scope = new PrologAtom("null");
    }
  } else {
    scope = new PrologAtom("null");
  }

  return new PrologCompTerm
    ("var_ref_exp_annotation", //5,
     typeSpecific,
     /* name*/ new PrologAtom(n->get_name().getString()),
     isStatic,
     scope,
     PPI(vr));
}
Example #10
0
void CudaOptimizer::applyRegisterOpt(SgFunctionDeclaration* kernel,
				     DefUseAnalysis* defuse, 
				     std::set<SgInitializedName*> readOnlyVars,
				     MintInitNameMapExpList_t arrRefList,
				     SgInitializedName* candidateVar4Shared, 
				     SgInitializedName* sec_candidateVar4Shared, 
				     bool optUnrollZ) 
{
    MintInitNameMapExpList_t::iterator it; 
 
   //perform register optimizations 
    for(it = arrRefList.begin(); it != arrRefList.end(); it++)
     {
       SgInitializedName* array = it->first;
       ROSE_ASSERT(array);
       std::vector<SgExpression*> expList = it->second;       
       int countNonStencil = getNonStencilArrayRefCount(expList);
              
	//TODO: should I put a limit about how many variables 
	//should be put into the registers?
       if(countNonStencil > 0 )
	 {
	   string arrName = array->get_name().str ();
	   string arrName_sh = (candidateVar4Shared != NULL) ? candidateVar4Shared->get_name().str() : " ";  
	   string arrName_sh_sec = (sec_candidateVar4Shared != NULL) ? sec_candidateVar4Shared->get_name().str() : " ";  

	   //if we slide the planes, we perform the register opt to that variable later
	   //TODO: Check if that includes the shared memory opt only ? Yes, shared should be on to skip this opt
	   if((arrName == arrName_sh || arrName == arrName_sh_sec) && optUnrollZ ){
	     continue;
	   }
	   else
	    {
	      cout << "  INFO:Mint: Candidate variable for register opt ("<< array->get_name().str() << ")";
	      cout << " with # of refs : "<< countNonStencil<< endl ; 	      
	      cout << "  INFO:Mint: Applying register optimization to array ("<< arrName << ")"<< endl;
	      OnChipMemoryOpt::registerOptimizer(readOnlyVars, kernel, array);
	    }
	 }
     }
}
void
Traversal::processNode(SgNode* n, SynthesizedAttribute& synthesizedAttribute )
  {
    // Look for names of functions
    SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(n);
    if (functionDeclaration != NULL)
    {
        string name = functionDeclaration->get_name().str();

        #if DEBUG > 3
          SgFunctionDefinition* functionDefinition =
              functionDeclaration->get_definition();
          if (functionDefinition != NULL)
              printf ("SgFunctionDefinition: %s \n",name.c_str());
          else
              printf ("SgFunctionDeclaration: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }

    SgInitializedName* initializedName = isSgInitializedName(n);
    if (initializedName != NULL)
    {
        string name = initializedName->get_name().str();

        #if DEBUG > 3
          printf ("SgInitializedName: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }

    SgNamespaceDeclarationStatement* namespaceDeclaration = isSgNamespaceDeclarationStatement(n);
    if (namespaceDeclaration != NULL)
    {
        string name = namespaceDeclaration->get_name().str();

        #if DEBUG > 3
          printf ("SgNamespaceDeclaration: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }
  }
Example #12
0
void CudaOptimizer::findCandidateVarForSharedMem(MintInitNameMapExpList_t arrRefList,
						 SgInitializedName* &candidateVar, 
						 SgInitializedName* prevCandidate, 
						 int &countMaxStencilRef,int &countNonStencilRef )
{
  countMaxStencilRef = 0;
  countNonStencilRef = 0;
  
  MintInitNameMapExpList_t::iterator it; 
  //find the candidate for shared memory 
  //go through all the array list to find the candidates

  //arrRefList contains the (array, expList)
  //ex: A -> A[i][j], A[i+1][j], A[i][j-1] ...

  for(it = arrRefList.begin(); it != arrRefList.end(); it++)
    {
      SgInitializedName* array = it->first;
      ROSE_ASSERT(array);
      
      std::vector<SgExpression*> expList = it->second;
      
      //TODO: we need a better mechanism to find the count of stencil references 
      //it is not enough to say that every non-[i][j] reference is stencil
      int countNonStencil = getNonStencilArrayRefCount(expList);
      int countStencilRef = expList.size() - countNonStencil;

      //need to check if candidate is the same as prevCandidate
      //because we may be looking for the second candidate 
      if(prevCandidate == NULL || prevCandidate->get_name().str() != array->get_name().str())
	{
	  //TODO: we need to make more roboust function for isStencilArray
	  if(MintArrayInterface::isStencilArray(expList))
	    {	
	      //these ones are canditates for shared memory
	      if(countMaxStencilRef < countStencilRef)
		{
		  candidateVar = array;
		  countMaxStencilRef = countStencilRef;
		  countNonStencilRef = countNonStencil ; //do we need this?
		}
	    }	
	}
    }

  if(candidateVar != NULL)
    cout << "  INFO:Mint: Candidate variable for shared memory opt: ("<< candidateVar->get_name().str() << ")"<< endl;
}
void BasicProgmemTransform::shiftVarDeclsToProgmem() {
	std::string flashHelper = "#define FS(x)(__FlashStringHelper*)(x)";
	insertPreprocessingInfo(flashHelper);
	printf("shifting var decls...\n");
	for(auto& varDecl : varDeclsToShift) {
		convertVarDeclToProgmemDecl(varDecl);
	}
	printf("shifting additional progmem strings...\n");
	for(auto &item: additionalProgmemStrings) {
		SgInitializedName *initName = item.second->get_variables()[0];
		std::string dec = "const char " + initName->get_name().getString() + "[] PROGMEM = \"" + item.first + "\";";
		insertPreprocessingInfo(dec);
//		convertVarDeclToProgmemDecl(varDecl, false);
	}
	printf("ok here\n");
}
Example #14
0
bool
TaintAnalysis::magic_tainted(SgNode *node, FiniteVarsExprsProductLattice *prodLat) {
    if (isSgInitializedName(node)) {
        SgInitializedName *iname = isSgInitializedName(node);
        std::string vname = iname->get_name().getString();
        TaintLattice *tlat = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(varID(iname)));
        if (tlat && 0==vname.compare(0, 7, "TAINTED")) {
            bool modified = tlat->set_vertex(TaintLattice::VERTEX_TAINTED);
            if (debug) {
                *debug <<"TaintAnalysis::magic_tainted: lattice is magically " <<tlat->to_string()
                       <<(modified?" (modified)":" (not modified)") <<"\n";
            }
            return modified;
        }
    } else if (isSgVarRefExp(node)) {
        SgVarRefExp *vref = isSgVarRefExp(node);
        std::string vname = vref->get_symbol()->get_name().getString();
        TaintLattice *tlat = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(varID(vref)));
        if (tlat && 0==vname.compare(0, 7, "TAINTED")) {
            bool modified = tlat->set_vertex(TaintLattice::VERTEX_TAINTED);
            if (debug) {
                *debug <<"TaintAnalysis::magic_tainted: lattice is magically " <<tlat->to_string()
                       <<(modified?" (modified)":" (not modified)") <<"\n";
            }
            return modified;
        }
    } else if (isSgVariableDeclaration(node)) {
        SgVariableDeclaration *vdecl = isSgVariableDeclaration(node);
        const SgInitializedNamePtrList &inames = vdecl->get_variables();
        for (size_t i=0; i<inames.size(); ++i) {
            std::string vname = inames[i]->get_name().getString();
            TaintLattice *tlat = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(varID(inames[i])));
            if (tlat && 0==vname.compare(0, 7, "TAINTED")) {
                bool modified = tlat->set_vertex(TaintLattice::VERTEX_TAINTED);
                if (debug) {
                    *debug <<"TaintAnalysis::magic_tainted: lattice is magically " <<tlat->to_string()
                           <<(modified?" (modified)":" (not modified)") <<"\n";
                }
                return modified;
            }
        }
    }

    return false;
}
void BasicProgmemTransform::transformCharArrayInitialization(SgFunctionDeclaration *func) {
	/* *
	 * Translates statements of the form:
	 * char arr[n] = "some string"; to:
	 * char arr[n];
	 * strcpy_P(arr, <progmem placeholder>);
	 * */
	Rose_STL_Container<SgNode *> initNames = NodeQuery::querySubTree(func, V_SgInitializedName);
	for(auto &item: initNames) {
		SgInitializedName *initName = isSgInitializedName(item);
		if(initName->get_initializer() == NULL) {
			continue;
		}
		SgVariableDeclaration * varDecl = isSgVariableDeclaration(initName->get_declaration());
		if(varDecl == NULL) {
			continue;
		}
		SgAssignInitializer *assignInit = isSgAssignInitializer(initName->get_initializer());
		if(assignInit == NULL) {
			continue;
		}
		SgType *type = initName->get_type();
		SgType *eleType = SageInterface::getElementType(type);
		if(isSgArrayType(type) && eleType != NULL && isSgTypeChar(eleType)) {
			SgStringVal* strVal = isSgStringVal(assignInit->get_operand());
			std::string str = strVal->get_value();
			int arrSize = getDeclaredArraySize(isSgArrayType(type));
			if(arrSize == 0) {
				//char arr[] = "something";
				int size = str.length() + 1;
				SgArrayType *type = SageBuilder::buildArrayType(SageBuilder::buildCharType(), SageBuilder::buildIntVal(size));
				initName->set_type(type);
			}
			varDecl->reset_initializer(NULL);
			SgVariableDeclaration *placeholder = getVariableDeclPlaceholderForString(str);
			SgVarRefExp *ref = SageBuilder::buildVarRefExp(placeholder);
			std::stringstream instr;
			instr << "\n strcpy_P(" << initName->get_name().getString();
			instr <<  ", " << ref->get_symbol()->get_name().getString() << ");\n";
			SageInterface::attachComment(varDecl, instr.str(), PreprocessingInfo::after);
			printf("transformed %s\n", initName->unparseToString().c_str());
		}

	}
}
Example #16
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameArgumentNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

  SgFunctionDeclaration *sageFunctionDeclaration =
    isSgFunctionDeclaration (astNode);

  if (sageFunctionDeclaration != NULL)
    {

      typedef SgInitializedNamePtrList::iterator argumentIterator;
      SgInitializedNamePtrList sageNameList = sageFunctionDeclaration->get_args ();
      int countArguments = 0;
      for (argumentIterator i = sageNameList.begin();
           i != sageNameList.end(); ++i)
        {
          SgInitializedName* elementNode = *i;
          ROSE_ASSERT (elementNode != NULL);

          string sageArgument(elementNode->get_name().str());

          returnNameList.push_back(sageArgument.c_str());

          countArguments += 1;
        }
#if DEBUG_NAMEQUERY
      printf ("\nHere is a function declaration :Line = %d Columns = %d \n",
              ROSE::getLineNumber (isSgLocatedNode (astNode)),
              ROSE::getColumnNumber (isSgLocatedNode (astNode)));
      cout << "The filename is:" << ROSE::
        getFileName (isSgLocatedNode (astNode)) << endl;
      cout << "The count of arguments is: " << countArguments << endl;
#endif
    }

  return returnNameList;
}                               /* End function queryNameArgumentNames() */
Example #17
0
Rose_STL_Container<SgNode*> NodeQuery::queryNodeVariableDeclarationFromName(SgNode* astNode, SgNode* nameNode){
  ROSE_ASSERT( nameNode != NULL );
  ROSE_ASSERT( astNode  != NULL );


  Rose_STL_Container<SgNode*> returnList;

  if(astNode->variantT() == V_SgVariableDeclaration){

    SgName* sageName = isSgName(nameNode);
    ROSE_ASSERT( sageName != NULL );
    std::string nameToMatch = sageName->str();
    ROSE_ASSERT( nameToMatch.length() > 0 );

    SgVariableDeclaration* sageVariableDeclaration = isSgVariableDeclaration(astNode);
    ROSE_ASSERT(sageVariableDeclaration != NULL);
    ROSE_ASSERT( sageVariableDeclaration->get_definition() != NULL );

    SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables ();

    //see if this variable declaration fits the criteria
    typedef SgInitializedNamePtrList::iterator variableIterator;

    for (variableIterator k = sageInitializedNameList.begin ();
        k != sageInitializedNameList.end(); ++k)
    {
      SgInitializedName* elmVar = *k;
      std::string name = elmVar->get_name().str();
      if(name == nameToMatch)
        returnList.push_back(astNode);

    }

  }

  return returnList;

}; /* End function: queryNodeVariableDeclarationFromName */
Example #18
0
void testOMPForSensitiveInsertion()
{
        annotateAllOmpFors(project);
        
        Rose_STL_Container<SgNode*> iteratorUses = NodeQuery::querySubTree(project, V_SgInitializedName);       
        OMPcfgRWTransaction trans;
        //VirtualCFG::cfgRWTransaction trans;
        trans.beginTransaction();
        for(Rose_STL_Container<SgNode*>::iterator it = iteratorUses.begin(); it!=iteratorUses.end(); it++)
        {
                SgInitializedName *initName = isSgInitializedName(*it); ROSE_ASSERT(initName);
                //printf("initialized Name <%s | %s>\n", initName->get_parent()->unparseToString().c_str(), initName->get_parent()->class_name().c_str());
                
                if(initName->get_name().getString() == "iterator")
                {
                        //printf("   inserting1 at spot <%s | %s>\n", initName->get_parent()->unparseToString().c_str(), initName->get_parent()->class_name().c_str());
                        trans.insertBefore(initName, fooCallCreate());
                        trans.insertAfter(initName, fooCallCreate());
                }
        }
        
        iteratorUses = NodeQuery::querySubTree(project, V_SgVarRefExp); 
        for(Rose_STL_Container<SgNode*>::iterator it = iteratorUses.begin(); it!=iteratorUses.end(); it++)
        {
                SgVarRefExp *varRef = isSgVarRefExp(*it); ROSE_ASSERT(varRef);
                
                if(varRef->get_symbol()->get_name().getString() == "iterator")
                {
                        //printf("   inserting2 at spot <%s | %s>\n", varRef->get_parent()->unparseToString().c_str(), varRef->get_parent()->class_name().c_str());
                        trans.insertBefore(varRef->get_parent(), fooCallCreate());
                        trans.insertAfter(varRef->get_parent(), fooCallCreate());
                }
        }
        
        trans.commitTransaction();
}
Example #19
0
File: Nodes.cpp Project: 8l/rose
ForLoop::ForLoop( SgForStatement * l ) 
: BasicNode(LOOPHEAD), myLoop(l), myLoopType(UNDEFINED), start(NULL), end(NULL),
body(NULL), back_edge(NULL), out(NULL), Iter(false)
{
	/* STEP 1 : Get initialization expression and symbol */
	SgStatementPtrList stmList = myLoop->get_init_stmt();
	if ( stmList.size() != 1 ) {
		report_error("Too many init statements",l);
	} else if ( isSgVariableDeclaration(stmList[0]) ) {
		
		SgInitializedNamePtrList initList = isSgVariableDeclaration(stmList[0])->get_variables();
		if ( initList.size() != 1 ) {
			report_error("To many induction variables",l);
		} else {
			SgInitializedName * initName = initList[0];
			if ( isSgAssignInitializer(initName->get_initializer()) ) {
				symbol = initName->get_name().getString();
				start = isSgAssignInitializer(initName->get_initializer())->get_operand();
			} else {
				report_error("Loop initializer is too complecated",initName);
			}
		}
		
	} else if ( isSgExprStatement(stmList[0]) ) {
		SgExpression * exp = isSgExprStatement(stmList[0])->get_expression();
		if ( isSgAssignOp(exp) ) {
			SgExpression * lhs = isSgAssignOp(exp)->get_lhs_operand();
			SgExpression * rhs = isSgAssignOp(exp)->get_rhs_operand();
			if ( isSgVarRefExp(lhs) ) {
				symbol = isSgVarRefExp(lhs)->get_symbol()->get_name().getString();
				start = rhs;
			} else {
				report_error("LHS of expression must be a single variable",exp);
			}
		} else {
			report_error("Init expression must be an Assign operation",exp);
		}
	} else {
		report_error("Loop initialization is not recognized",l);
	}
	
	/* STEP 2 : Get the test expression */
	SgExprStatement * expStm = isSgExprStatement(myLoop->get_test());
	if ( expStm ) {
		SgExpression * exp = expStm->get_expression();
		if ( isSgLessOrEqualOp(exp) ) {
			SgBinaryOp * binOp = isSgBinaryOp(exp);
			string name = isSgVarRefExp(isSgBinaryOp(exp)->get_lhs_operand())->get_symbol()->get_name().getString();
			
			if ( name != symbol )
				report_error("Loop init and test variable miss-match",exp);
			
			end = binOp->get_rhs_operand();
			
		} else if ( isSgLessThanOp(exp) ) {
			
			SgBinaryOp * binOp = isSgBinaryOp(exp);
			string name = isSgVarRefExp(binOp->get_lhs_operand())->get_symbol()->get_name().getString();
			
			if ( name != symbol )
				report_error("Loop init and test variable miss-match",exp);
			
			SgExpression * tempExp = SageInterface::copyExpression(binOp->get_rhs_operand());
			end = buildSubtractOp( tempExp, buildIntVal(1) );
			end->set_need_paren(true);
			tempExp = buildLessOrEqualOp( SageInterface::copyExpression(binOp->get_lhs_operand()), end );
			
			SageInterface::replaceExpression(exp, tempExp, false);
			
		} else {
			report_error("Test expression is not recognized. Re-write the loop or normilize it accordingly",exp);
		}
	} else {
		report_error("Test expression is not recognized. Sorry !", l);
	}
	
	/* STEP 3 : Check the stride */
	if ( !isSgPlusPlusOp(l->get_increment()) )
		report_error("Increment expression is not recognized. Re-write the loop or normilize it accordingly. Note: Only \"++\" operator supported.",l);
	
	/* STEP 4 : Link with Loop Tail node */
	back_edge = new ForLoop(start,end,symbol,l,this,this,LOOPTAIL);
	body = back_edge;
}
Example #20
0
StencilEvaluation_SynthesizedAttribute
StencilEvaluationTraversal::evaluateSynthesizedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     StencilEvaluation_SynthesizedAttribute return_synthesizedAttribute;

#if 0
     printf ("In StencilEvaluationTraversal::evaluateSynthesizedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundStencilOffsetFSM = false;
     SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode);
     if (constructorInitializer != NULL && inheritedAttribute.stencilOffsetFSM != NULL)
        {
#if 0
          printf ("Found pair<Shift,double>(x,y): set then in the synthesizedAttribute: astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif
          return_synthesizedAttribute.stencilOffsetFSM       = inheritedAttribute.stencilOffsetFSM;
          return_synthesizedAttribute.stencilCoeficientValue = inheritedAttribute.stencilCoeficientValue;
#if 0
          printf ("return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif
          foundStencilOffsetFSM = true;
        }

  // There should only be a single child set with a pair<Shift,double>(x,y) object.
     for (size_t i = 0; i < synthesizedAttributeList.size(); i++)
        {
          if (synthesizedAttributeList[i].stencilOffsetFSM != NULL)
             {
            // Check that the return_synthesizedAttribute.stencilOffsetFSM has not already been set.
            // This could happend if we allows nesting of pair<Shift,double>(x,y) within itself (not allowed).
#if 0
               printf ("synthesizedAttributeList[i].stencilOffsetFSM != NULL \n");
#endif
            // ROSE_ASSERT(foundStencilOffsetFSM == false);
               if (foundStencilOffsetFSM == false)
                  {
#if 0
                    printf ("foundStencilOffsetFSM == false \n");
#endif
                 // ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM == NULL);
                    if (return_synthesizedAttribute.stencilOffsetFSM == NULL)
                       {
#if 0
                         printf ("return_synthesizedAttribute.stencilOffsetFSM != NULL \n");
#endif
                         return_synthesizedAttribute.stencilOffsetFSM = synthesizedAttributeList[i].stencilOffsetFSM;
                         return_synthesizedAttribute.stencilCoeficientValue = synthesizedAttributeList[i].stencilCoeficientValue;
                       }

                    foundStencilOffsetFSM = true;
                  }
             }
        }

  // This allows us to find the variables of type vector<Point> and vector<double> used as an alternative way
  // to specify a stencil (using the Stencil constructor that takes these variables as input arguments).
  // It relies upon a previous traversal to have identified the inputs to Stencil constructor.
  // This support is incomplete while I focus on the alternative approach to the specification of the stencil
  // using intremental union of a stencil with a pair<Shift,double>() template instantiation.
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode);
     if (variableDeclaration != NULL)
        {
       // Get the SgInitializedName from the SgVariableDeclaration.
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);
#if 0
          printf ("In evaluateInheritedAttribute(): case SgInitializedName from variable declaration: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
#endif
          bool foundStencilDeclaration = false;
          if (find(stencilInputInitializedNameList.begin(),stencilInputInitializedNameList.end(),initializedName) != stencilInputInitializedNameList.end())
             {
#if 0
               printf ("Found declaration associated with stencil input: initializedName = %p = %s name = %s \n",initializedName,initializedName->class_name().c_str(),initializedName->get_name().str());
#endif
            // Build the finite state machine for the stencil and add it to the map using the name (in SgInitializedName) as a key.
            // For now we assume that the stencil specification is using the default construction.
               if (initializedName->get_initptr() != NULL)
                  {
                    printf ("FIXME: This declaration of a stencil appears to have constrcutor arguments (this not the default constuctor as interprest below). \n");
#if 0
                    ROSE_ASSERT(false);
#endif
                  }

               foundStencilDeclaration = true;
             }
            else
             {
            // Verify that this is a Stencil declaration.
               SgClassType* classType = isSgClassType(initializedName->get_type());
               if (classType != NULL)
                  {
                 // Check if this is associated with a template instantiation.
                    SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration());
                    if (templateInstantiationDecl != NULL)
                       {
#if 0
                         printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str());
                         printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str());
#endif
                         if (templateInstantiationDecl->get_templateName() == "Stencil")
                            {
#if 0
                              printf ("This is verified to be associated with the Stencil template class \n");
#endif
                              foundStencilDeclaration = true;
                            }
                       }
                  }
             }

          if (foundStencilDeclaration == true)
             {
               string name = initializedName->get_name();
               ROSE_ASSERT(stencilMap.find(name) == stencilMap.end());
            // stencilMap[name] = new StencilFSM();
               StencilFSM* stencilFSM = new StencilFSM();
               ROSE_ASSERT(stencilFSM != NULL);
               stencilMap[name] = stencilFSM;
               ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
#if 0
               printf ("Added StencilFSM to stencilMap using name = %s \n",name.c_str());
#endif
#if 0
               printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
               printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
               if (return_synthesizedAttribute.stencilOffsetFSM != NULL)
                  {
                 // Trigger the event to add the stencil offset to the stencil.
                 // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
                    StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

                 // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
                 // in the stencil specification. but this permits use to accumulate the state at compile time.
                    stencilFSM->operator+(stencil_rhs);

                 // We have now used these values so avoid letting then be used again.
                    return_synthesizedAttribute.stencilOffsetFSM       = NULL;
                    return_synthesizedAttribute.stencilCoeficientValue = 0.0;
                  }
#if 0
               stencilFSM->display("after FSM stencil default construction plus union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
#if 0
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
#endif
             }
        }

  // Recognize member function calls on "Stencil" objects so that we can trigger events on those associated finite state machines.
     bool isTemplateClass = true;
     bool isTemplateFunctionInstantiation = true;
     SgInitializedName* initializedNameUsedToCallMemberFunction = NULL;
     SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Stencil",isTemplateClass,"operator+",isTemplateFunctionInstantiation);
     if (return_synthesizedAttribute.stencilOffsetFSM != NULL && functionCallExp != NULL)
        {
       // This is the DSL specific part of the synthesized attribute evaluation.

          ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL);
          string name = initializedNameUsedToCallMemberFunction->get_name();
#if 0
          printf ("This is verified to be the operator+ member function of the Stencil templated class (so this corresponds to an event in the Stencil finite state machine) \n");
          printf ("   --- stencil object name = %s \n",name.c_str());
#endif
       // Lookup the stencil FSM in the map of stencil FSMs using the name as the key.
          ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
          StencilFSM* stencilFSM = stencilMap[name];
          ROSE_ASSERT(stencilFSM != NULL);
#if 0
          printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
          printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
       // Make sure we have the input parameter for the stencil's finite state machine.
          ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM != NULL);

       // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
          StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

       // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
       // in the stencil specification. but this permits use to accumulate the state at compile time.
          stencilFSM->operator+(stencil_rhs);

       // We have now used these values so avoid letting then be used again.
          return_synthesizedAttribute.stencilOffsetFSM       = NULL;
          return_synthesizedAttribute.stencilCoeficientValue = 0.0;
#if 0
          stencilFSM->display("after FSM stencil union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
        }

#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif

     return return_synthesizedAttribute;
   }
Example #21
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
   {
#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

     SgExpression* funname = funcall->get_function();
     SgExpression* funname2 = isSgFunctionRefExp(funname);
     SgDotExp* dotexp = isSgDotExp(funname);
     SgArrowExp* arrowexp = isSgArrowExp(funname);
     SgExpression* thisptr = 0;
     if (dotexp || arrowexp)
        {
          funname2 = isSgBinaryOp(funname)->get_rhs_operand();
          if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
              SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
              ROSE_ASSERT (isSgInitializer(ai->get_operand()));
#if 1
              printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false");
#endif
              SgInitializedName* in = isSgInitializedName(ai->get_parent());
              ROSE_ASSERT (in);
              removeRedundantCopyInConstruction(in);
              lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
          } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
          } else {
            assert (false);
          }
        }

     if (!funname2)
        {
       // std::cout << "Inline failed: not a call to a named function" << std::endl;
          return false; // Probably a call through a fun ptr
        }

     SgFunctionSymbol* funsym = 0;
     if (isSgFunctionRefExp(funname2))
          funsym = isSgFunctionRefExp(funname2)->get_symbol();
       else
          if (isSgMemberFunctionRefExp(funname2))
               funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
            else
               assert (false);

     assert (funsym);
     if (isSgMemberFunctionSymbol(funsym) &&
         isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
        {
       // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
          return false;
        }

     SgFunctionDeclaration* fundecl = funsym->get_declaration();
     fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL;

     SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL;
     if (!fundef)
        {
       // std::cout << "Inline failed: no definition is visible" << std::endl;
          return false; // No definition of the function is visible
        }
     if (!allowRecursion)
        {
          SgNode* my_fundef = funcall;
          while (my_fundef && !isSgFunctionDefinition(my_fundef))
             {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
               my_fundef = my_fundef->get_parent();
               ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
             }
       // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
          assert (isSgFunctionDefinition(my_fundef));
          if (isSgFunctionDefinition(my_fundef) == fundef)
             {
               std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
               return false;
             }
        }

     SgVariableDeclaration* thisdecl = 0;
     SgName thisname("this__");
     thisname << ++gensym_counter;
     SgInitializedName* thisinitname = 0;
     if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
        {
          assert (thisptr != NULL);
          SgType* thisptrtype = thisptr->get_type();
          const SgSpecialFunctionModifier& specialMod = 
            funsym->get_declaration()->get_specialFunctionModifier();
          if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
          }
          SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
       // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
          thisptrtype = new SgModifierType(thisptrtype);
          isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
       // }
       // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
          SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
          assignInitializer->set_endOfConstruct(SgNULL_FILE);
#if 1
          printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
#if 1
          printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl->set_endOfConstruct(SgNULL_FILE);
          thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
          thisdecl->set_definingDeclaration(thisdecl);

          thisinitname = (thisdecl->get_variables()).back();
          //thisinitname = lastElementOfContainer(thisdecl->get_variables());
          // thisinitname->set_endOfConstruct(SgNULL_FILE);
          assignInitializer->set_parent(thisinitname);
          markAsTransformation(assignInitializer);

       // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

       // DQ (6/23/2006): New test
          ROSE_ASSERT(assignInitializer->get_parent() != NULL);
        }

     // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local
     // variables in the inlined code.  We need to detach the actual arguments from the AST here since we'll be reattaching
     // them below (otherwise we would violate the invariant that the AST is a tree).
     SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);
     SgExpressionPtrList funargs = funcall->get_args()->get_expressions();
     funcall->get_args()->get_expressions().clear();
     BOOST_FOREACH (SgExpression *actual, funargs)
         actual->set_parent(NULL);

     // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original.
     SgBasicBlock* funbody_raw = fundef->get_body();
     SgInitializedNamePtrList& params = fundecl->get_args();
     std::vector<SgInitializedName*> inits;
     SgTreeCopy tc;
     SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
     ROSE_ASSERT (function_copy);
     SgBasicBlock* funbody_copy = function_copy->get_body();

     renameLabels(funbody_copy, targetFunction);
     ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size());

     // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function
     // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body
     // because we need them below.
     if (function_copy->get_declaration()) {
         ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy);
         function_copy->get_declaration()->set_parent(NULL);
         function_copy->set_declaration(NULL);
     }
     if (function_copy->get_body()) {
         ASSERT_require(function_copy->get_body()->get_parent() == function_copy);
         function_copy->get_body()->set_parent(NULL);
         function_copy->set_body(NULL);
     }
     delete function_copy;
     function_copy = NULL;
#if 0
     SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
     pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaBegin->set_parent(pragmaBeginDecl);
     pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
     funbody_copy->prepend_statement(pragmaBeginDecl);
     pragmaBeginDecl->set_parent(funbody_copy);
#endif

     // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal
     // argument and having the same type as the formal argument. Initialize those new local variables with the actual
     // arguments.  Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local
     // variable (SgVariableSymbol).
     ReplaceParameterUseVisitor::paramMapType paramMap;
     SgInitializedNamePtrList::iterator formalIter = params.begin();
     SgExpressionPtrList::iterator actualIter = funargs.begin();
     for (size_t argNumber=0;
          formalIter != params.end() && actualIter != funargs.end();
          ++argNumber, ++formalIter, ++actualIter) {
         SgInitializedName *formalArg = *formalIter;
         SgExpression *actualArg = *actualIter;

         // Build the new local variable.
         // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name
         SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type());
         ASSERT_not_null(initializer);
         initializer->set_endOfConstruct(SgNULL_FILE);
#if 1
         printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false");
#endif
         SgName shadow_name(formalArg->get_name());
         shadow_name << "__" << ++gensym_counter;
         SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer);
         vardecl->set_definingDeclaration(vardecl);
         vardecl->set_endOfConstruct(SgNULL_FILE);
         vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
         vardecl->set_parent(funbody_copy);

         // Insert the new local variable into the (near) beginning of the to-be-inserted function body.  We insert them in the
         // order their corresponding actuals/formals appear, although the C++ standard does not require this order of
         // evaluation.
         SgInitializedName* init = vardecl->get_variables().back();
         inits.push_back(init);
         initializer->set_parent(init);
         init->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl);
         SgVariableSymbol* sym = new SgVariableSymbol(init);
         paramMap[formalArg] = sym;
         funbody_copy->insert_symbol(shadow_name, sym);
         sym->set_parent(funbody_copy->get_symbol_table());
     }

     // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the
     // caller's "this".
     if (thisdecl) {
         thisdecl->set_parent(funbody_copy);
         thisinitname->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
         SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
         funbody_copy->insert_symbol(thisname, thisSym);
         thisSym->set_parent(funbody_copy->get_symbol_table());
         ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
     }
     ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

     SgName end_of_inline_name = "rose_inline_end__";
     end_of_inline_name << ++gensym_counter;
     SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
     end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
     printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

  // Need to set the parent of funbody_copy to avoid error.
     funbody_copy->set_parent(funbody_raw->get_parent());

     printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

     printf ("funbody_raw->get_statements().size()  = %" PRIuPTR " \n",funbody_raw->get_statements().size());
     printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size());

     printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
     printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

     printf ("Output the symbol table for funbody_raw \n");
     funbody_raw->get_symbol_table()->print("debugging copy problem");

  // printf ("Output the symbol table for funbody_copy \n");
  // funbody_copy->get_symbol_table()->print("debugging copy problem");

     SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
     ROSE_ASSERT(project_copy != NULL);

     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
     generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

     funbody_copy->append_statement(end_of_inline_label);
     end_of_inline_label->set_scope(targetFunction);
     SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
     end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
     targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);

     // To ensure that there is some statement after the label
     SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
     dummyStatement->set_endOfConstruct(SgNULL_FILE);
     funbody_copy->append_statement(dummyStatement);
     dummyStatement->set_parent(funbody_copy);
#if 0
     SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
     pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaEnd->set_parent(pragmaEndDecl);
     pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
     funbody_copy->append_statement(pragmaEndDecl);
     pragmaEndDecl->set_parent(funbody_copy);
#endif

     ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
     replaceExpressionWithStatement(funcall, &previsitor);

     // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the
     // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other
     // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the
     // operators where they were inserted.
     markLhsValues(targetFunction);
#ifdef NDEBUG
     AstTests::runAllTests(SageInterface::getProject());
#endif

#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

  // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think.
  // Mark the things we insert as being transformations so they get inserted into the output by backend()
     markAsTransformation(funbody_copy);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          string stencilName = stencilInitializedName->get_name();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

               lastStatement = destinationDataPointerVariableDeclaration;
             }

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

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

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

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

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

               ROSE_ASSERT(stencilSubTree != NULL);

               stencilSubTreeArray.push_back(stencilSubTree);
             }

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

       // Assemble the stencilSubTreeArray into a single expression.
          SgExprStatement* stencilStatement = assembleStencilSubTreeArray(stencil_lhs,stencilSubTreeArray,stencilDimension,destinationVariableSymbol);
          SageInterface::appendStatement(stencilStatement,innerLoopBody);
        }
   }
Example #23
0
DOTSynthesizedAttribute
AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l)
   {
     SubTreeSynthesizedAttributes::iterator iter;
     ROSE_ASSERT(node);

  // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str());

  // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute
     if (ia.skipSubTree == true)
        {
       // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute
       // Figured this out: if we return a valid pointer then we get a node in the DOT graph 
       // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute 
       // with a NUL pointer then the node will NOT appear in the DOT graph.
       // return DOTSynthesizedAttribute(node);
          return DOTSynthesizedAttribute(NULL);
        }

     string nodeoption;
     if(AstTests::isProblematic(node))
        {
       // cout << "problematic node found." << endl;
          nodeoption="color=\"orange\" ";
        }
     string nodelabel=string("\\n")+node->class_name();

  // DQ (1/24/2009): Added support for output of isForward flag in the dot graph.
     SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node);
     if (genericDeclaration != NULL)
        {
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
          string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward";
          ROSE_ASSERT(name.empty() == false);

       // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST.
          SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration);
          if (classDeclaration != NULL)
             {
               nodelabel += string("\\n") + classDeclaration->get_name();
             }

       // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration);
          if (functionDeclaration != NULL)
             {
               nodelabel += string("\\n") + functionDeclaration->get_name();
             }

          nodelabel += string("\\n") + name;
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgInitializedName* initializedName = isSgInitializedName(node);
     if (initializedName != NULL)
        {
          nodelabel += string("\\n") + initializedName->get_name();
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgIntVal* intValue = isSgIntVal(node);
     if (intValue != NULL)
        {
          nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value());
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgVarRefExp* varRefExp = isSgVarRefExp(node);
     if (varRefExp != NULL)
        {
          SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
          ROSE_ASSERT(variableSymbol != NULL);
          string name = variableSymbol->get_name();
          nodelabel += string("\\n name = ") + name;
        }

  // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph.
     SgAsmInstruction* genericInstruction = isSgAsmInstruction(node);
     if (genericInstruction != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
#if 1
          string unparsedInstruction = unparseInstruction(genericInstruction);
          string addressString       = StringUtility::numberToString( (void*) genericInstruction->get_address() );
       // string name = genericInstruction->get_mnemonic();
          string name = unparsedInstruction + "\\n address: " + addressString;
#else
          string name = unparsedInstruction + "\\n" + addressString;
#endif
          ROSE_ASSERT(name.empty() == false);

          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

     SgAsmExpression* genericExpression = isSgAsmExpression(node);
     if (genericExpression != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
          string name = unparseExpression(genericExpression, NULL, NULL);
          ROSE_ASSERT(name.empty() == false);
          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes.
  // In generall there are long list of these IR nodes in the binary and this helps make some sense of 
  // the lists (sections, symbols, etc.).
     SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node);
     if (binaryFileFormatNode != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // The case of binary file format IR nodes can be especially confusing so we want the 
       // default to output some more specific information for some IR nodes (e.g. sections).
          string name;

          SgAsmGenericSection* genericSection = isSgAsmGenericSection(node);
          if (genericSection != NULL)
             {
               SgAsmGenericString* genericString = genericSection->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node);
          if (genericSymbol != NULL)
             {
               SgAsmGenericString* genericString = genericSymbol->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();

               if (name.empty() == true)
                    name = "no_name_for_symbol";
             }

          SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node);
          if (genericDLL != NULL)
             {
               SgAsmGenericString* genericString = genericDLL->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node);
          if (peImportItem != NULL)
             {
               SgAsmGenericString* genericString = peImportItem->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node);
          if (asmDwarfLine != NULL)
             {
               char buffer[100];

            // It does not work to embed the "\n" into the single sprintf parameter.
            // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column());

               sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address());
               name = buffer;
               sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column());
               name += string("\\n") + buffer;
             }

          SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node);
          if (asmDwarfConstruct != NULL)
             {
               name = asmDwarfConstruct->get_name();
             }

#if 0
       // This might not be the best way to implement this, since we want to detect common base classes of IR nodes.
          switch (node->variantT())
             {
               case V_SgAsmElfSection:
                  {
                    SgAsmElfSection* n = isSgAsmElfSection(node);
                    name = n->get_name();
                    break;
                  }

               default:
                  {
                 // No additional information is suggested for the default case!
                  }
             }
#endif

          if (name.empty() == false)
               nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (11/29/2008): Output the directives in the label of the IR node.
     SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node);
     if (preprocessorDirective != NULL)
        {
          string s = preprocessorDirective->get_directiveString();

       // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables.
          while (s.find("\"") != string::npos)
             {
               s.replace(s.find("\""),1,"\'");
             }

          if (s.empty() == false)
               nodelabel += string("\\n") + s;
        }

     nodelabel += additionalNodeInfo(node);

  // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.)
  // nodeoption += additionalNodeOptions(node);
     string additionalOptions = additionalNodeOptions(node);
  // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size());
  // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size());

     string x;
     string y;
     x += additionalOptions;

     nodeoption += additionalOptions;

     DOTSynthesizedAttribute d(0);

  // DQ (7/27/2008): Added mechanism to support pruning of AST
     bool commentoutNode = commentOutNodeInGraph(node);
     if (commentoutNode == true)
        {
       // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option.
       // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file.
          if (SgProject::get_verbose() > 0)
             {
               printf ("Skipping the use of this IR node in the DOT Graph \n");
             }
        }
       else
        {

// **************************

     switch(traversal)
        {
          case TOPDOWNBOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption);
               break;
          case PREORDER:
          case TOPDOWN:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
               break;
          case POSTORDER:
          case BOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption);
               break;
          default:
               assert(false);
        }
  
     ++tdbuTrace;
     ++buTrace;

  // add edges or null values
     int testnum=0;
     for (iter = l.begin(); iter != l.end(); iter++)
        {
          string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]);
          string toErasePrefix = "p_";

          if (AstTests::isPrefix(toErasePrefix,edgelabel))
             {
               edgelabel.erase(0, toErasePrefix.size());
             }

          if ( iter->node == NULL)
             {
            // SgNode* snode=node->get_traversalSuccessorContainer()[testnum];
               AstSuccessorsSelectors::SuccessorsContainer c;
               AstSuccessorsSelectors::selectDefaultSuccessors(node,c);
               SgNode* snode=c[testnum];

            // isDefault shows that the default constructor for synth attribute was used
               if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) )
                  {
                 // handle bugs in SAGE
                    dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red ");
                  }
                 else
                  {
                    if (snode == NULL)
                       {
                         dotrep.addNullValue(node,"",edgelabel,"");
                       }
                  }
             }
            else
             {
            // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.)
               string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel);

               switch(traversal)
                  {
                    case TOPDOWNBOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both");
                         break;
                    case PREORDER:
                    case TOPDOWN:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward");
                         break;
                    case POSTORDER:
                    case BOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back");
                         break;
                    default:
                         assert(false);
                  }
             }

          testnum++;
        }

// **************************
        }



  // DQ (7/4/2008): Support for edges specified in AST attributes
     AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism();
     if (astAttributeContainer != NULL)
        {
       // Loop over all the attributes at this IR node
          for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++)
             {
            // std::string name = i->first;
               AstAttribute* attribute = i->second;
               ROSE_ASSERT(attribute != NULL);

            // This can return a non-empty list in user-defined attributes (derived from AstAttribute).
            // printf ("Calling attribute->additionalNodeInfo() \n");
               std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo();
            // printf ("nodeList.size() = %lu \n",nodeList.size());

               for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++)
                  {
                    SgNode* nodePtr   = i_node->nodePtr;
                    string nodelabel  = i_node->label;
                    string nodeoption = i_node->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str());
                 // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
                    dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption );
                  }

            // printf ("Calling attribute->additionalEdgeInfo() \n");
               std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo();
            // printf ("edgeList.size() = %lu \n",edgeList.size());
               for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++)
                  {
                    string edgelabel  = i_edge->label;
                    string edgeoption = i_edge->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str());
                    dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward");
                  }
             }
        }



     switch(node->variantT())
        {
       // DQ (9/1/2008): Added case for output of SgProject rooted DOT file.
       // This allows source code and binary files to be combined into the same DOT file.
          case V_SgProject: 
             {
               SgProject* project = dynamic_cast<SgProject*>(node);
               ROSE_ASSERT(project != NULL);

               string generatedProjectName = SageInterface::generateProjectName( project );
            // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
               if (generatedProjectName.length() > 40)
                  {
                 // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
                    generatedProjectName = "aggregatedFileNameTooLong";
                    printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str());
                  }

               string filename = string("./") + generatedProjectName + ".dot";

            // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str());
               if ( SgProject::get_verbose() >= 1 )
                    printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str());

               dotrep.writeToFileAsGraph(filename);
               break;
             }

       // case V_SgFile: 
          case V_SgSourceFile: 
          case V_SgBinaryComposite: 
             {
               SgFile* file = dynamic_cast<SgFile*>(node);
               ROSE_ASSERT(file != NULL);

               string original_filename = file->getFileName();

            // DQ (7/4/2008): Fix filenamePostfix to go before the "."
            // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot";
               string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot";

            // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent());

            // printf ("file->get_parent() = %p \n",file->get_parent());
            // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... ";

            // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified 
            // on the command line.  A SgProject is still built even when a single file is specificed 
            // on the command line, however there are cases where a SgFile can be built without a 
            // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files.
            // If there is a SgProject then output the dot file from there, else output as a SgFile.
               if (file->get_parent() == NULL)
                  {
                 // If there is no SgProject then output the file now!
                    if ( SgProject::get_verbose() >= 1 )
                         printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n");

                    dotrep.writeToFileAsGraph(filename);
                  }
                 else
                  {
                 // There is a SgProject IR node, but if we will be traversing it we want to output the 
                 // graph then (so that the graph will include the SgProject IR nodes and connect multiple 
                 // files (SgSourceFile or SgBinaryComposite IR nodes).
                    if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() )
                       {
                      // This SgProject node was not input as part of the traversal, 
                      // so we will not be traversing the SgProject IR nodes and we 
                      // have to output the graph now!

                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n");

                         dotrep.writeToFileAsGraph(filename);
                       }
                      else
                       {
                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n");
                       }
                  }
               
            // cout << "done." << endl;
               break;
             }

       // DQ (7/23/2005): Implemented default case to avoid g++ warnings 
       // about enum values not handled by this switch
          default: 
             {
            // nothing to do here
               break;
             }
        }

     d.node = node;
     return d;
   }
Example #24
0
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.
Example #25
0
int main( int argc, char *argv[] )
{
	if( argc < 2 ) {
		cout << "./amos: no input files                               " << endl;
		cout << "                                                     " << endl;
		cout << "Hi, this is Amos!                                    " << endl;
		cout << "It's my pleasure to serve you.                       " << endl;
		cout << "                                                     " << endl;
		cout << "Please type option '--help' to see guide             " << endl;
		cout << "                                                     " << endl;

		return 0;
	}

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

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

	command_processing( argvList );

	if( !parse_OmpTask( argvList ) ) {

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

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

	t_start = usecs(); 
	// for time counter

	transform_Task2Loop( argvList );

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

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

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

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

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

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

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

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

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

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

			SgBasicBlock *body = defn->get_body();

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

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

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

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

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

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

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

				if( invarname != NULL ) {

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

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

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

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

						TaskValidation( current_loop );

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

				}

			}// end for loops

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

	}//end loop for each source file

	release_analysis();

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

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

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

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

	return 0;
}
Example #26
0
void CudaOptimizer::applyLoopAggregationOpt(SgFunctionDeclaration* kernel,				     
					    const std::set<SgInitializedName*> readOnlyVars,
					    const MintArrFreqPairList_t& candidateVarsShared,
					    const MintArrFreqPairList_t& candidateVarsReg,
					    const MintForClauses_t& clauseList)
{
  //perform shared memory optimizations, go through each element in the candidate list
  //the list is in decending order based on the number of references
  //the list contains array name and how many planes it needs

  SgBasicBlock* kernel_body = kernel->get_definition()->get_body();

  int common_order =0 ; 

  //find the common order otherwise, we need to declare separate idx and idy, that's not good.
  MintArrFreqPairList_t::const_iterator it;

  for(it = candidateVarsShared.begin(); it != candidateVarsShared.end(); it++)
    {
      MintArrFreqPair_t apair = (*it); 
      
      SgInitializedName* candidate = apair.first;
      ROSE_ASSERT(candidate);

      //we already computed, how many planes we will need 
      int num_planes = apair.second; 

      int dimension = MintArrayInterface::getDimension(candidate);

      if(dimension > 3 || dimension < 2)
	continue;

      int order = StencilAnalysis::performHigherOrderAnalysis(kernel_body, candidate, num_planes);

      //TODO: should we return if the order is 0 or too high ?                                                
      //what do you think? Yes, we should use registers if the order is 0, because there is no sharing.                
                                                                                            
      if(order == 0){
	cout << "  INFO:Mint: Order of this array is " << order ;
	cout << ". No sharing, no need to use shared memory " << endl;
	continue ;
      }

      common_order = order > common_order ? order : common_order ;
    }

  common_order = common_order > MAX_ORDER ? MAX_ORDER : common_order ;
  cout << "  INFO:Mint: Common order of this kernel " << common_order << endl ;

  bool first = true; 
  for(it = candidateVarsShared.begin(); it != candidateVarsShared.end(); it++)
    {
      MintArrFreqPair_t apair = (*it); 
      
      SgInitializedName* candidate = apair.first;
      ROSE_ASSERT(candidate);
      
      //we already computed, how many planes we will need 
      int num_planes = apair.second; 

      int dimension = MintArrayInterface::getDimension(candidate);

      if(dimension > 3 || dimension < 2)
	continue;
      
      //TODO <--check this if it should be true or false? when only -opt:shared is set (not register)
      //bool regSharedSame = true; //refCountMaxRg > 0 ? true : false; we already inserted the register 

      cout << "  INFO:Mint: Applying Loop Aggregation optimization to array ("<<candidate->get_name().str();
      cout << " using " << num_planes << " planes )" << endl; 
      slidingRowOptimizer(kernel, readOnlyVars, candidate, clauseList, num_planes, common_order, first);
      first = false; 

    }//end of for 

  if(candidateVarsShared.size () > 0)
    OnChipMemoryOpt::insertSynchPoints(kernel);

}
Example #27
0
void createGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body,
				      MintInitNameMapExpList_t refList, 
				      SgDeclarationStatement* src_location)
{
  //we need to exclude the ones for shared memory
  //step 4 create an index expression for each distinct array 
  //e.g. _gidx + _gidy * widthUnew  in 2D
  //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D

  ROSE_ASSERT(src_location);

  SgScopeStatement* indexScope= src_location->get_scope();

  SgVariableSymbol* gidz_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDZ);
  SgVariableSymbol* gidy_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDY);

  MintInitNameMapExpList_t::iterator arr; 

  //for each array, create an index expression
  for(arr= refList.begin(); arr!= refList.end(); arr++)
    {
      SgInitializedName* iname = arr->first;

      int dim = MintArrayInterface::getDimension(iname);

      ROSE_ASSERT(dim <= 3);

      if(dim == 3 && gidz_sym == NULL)
	continue; //must be a boundary condition, we don't use index opt. optimization for those

      if(dim == 2 && gidy_sym == NULL)
	continue; //must be a boundary condition, we don't use index opt. optimization for those

      string arrStr = iname->get_name().str();

      //_gidx + _gidy * widthUnew  in 2D
      //_gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D
      SgExpression* indexExp = NULL;
      indexExp = buildVarRefExp(GIDX, indexScope); 

      if(dim >= 2)
	indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), 
							buildVarRefExp("width"+arrStr, kernel_body)));
      if(dim == 3 ){
	indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDZ, indexScope), 
							buildVarRefExp("slice"+arrStr, kernel_body)));
      }
      SgAssignInitializer* initIndex = buildAssignInitializer(indexExp);

      SgVariableDeclaration* index = buildVariableDeclaration("index" + arrStr, 
							      buildIntType(), initIndex, indexScope);

      //step 5 insert index expression in the kernel
      ROSE_ASSERT(index);
      insertStatementAfter(src_location, index );

      //step 6 check if there is a loop, if there is we need to update the index 
      //but we only update if the loop makes changes in the array reference 
      std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement);
      
      if(loopNest.size() > 0)
	{
	  SgForStatement* loop = *(loopNest.begin());
	  SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body());
	  SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp);
	  ROSE_ASSERT(update_stmt);
	  prependStatement(update_stmt, loop_body);
	}      
    }
} 
Example #28
0
void createOneGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body,
					 MintInitNameMapExpList_t refList, 
					 SgDeclarationStatement* src_location)
{
  //We declare one index variable for all arrays: one for 1D, one for 2D, one for 3D
  //Need a compiler flag for this

  //e.g. _gidx + _gidy * widthUnew  in 2D
  //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D

  ROSE_ASSERT(src_location);

  bool threeD = false; 
  bool twoD = false; 
  bool oneD = false;

  SgScopeStatement* indexScope= src_location->get_scope();

  SgVariableSymbol* gidz_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDZ);
  SgVariableSymbol* gidy_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDY);
  SgVariableSymbol* gidx_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDX);

  MintInitNameMapExpList_t::iterator arr; 

  //for each array, we don't create an index expression
  for(arr= refList.begin(); arr!= refList.end(); arr++)
    {
      SgInitializedName* iname = arr->first;

      int dim = MintArrayInterface::getDimension(iname);

      ROSE_ASSERT(dim <= 3);

      if(dim == 3 && (gidz_sym == NULL || threeD == true))
	continue; //must be a boundary condition, we don't use index opt. optimization for those

      if(dim == 2 && (gidy_sym == NULL || twoD == true))
	continue; //must be a boundary condition, we don't use index opt. optimization for those

      if(dim == 1 && (gidx_sym == NULL || oneD == true))
	continue; //must be a boundary condition, we don't use index opt. optimization for those

      string arrStr = iname->get_name().str();

      //_gidx + _gidy * widthUnew  in 2D
      //_gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D
      SgExpression* indexExp = NULL;
      indexExp = buildVarRefExp(GIDX, indexScope); 

      string index_str = "index";

      if(dim ==1){
	  index_str = "_" +index_str + "1D";
	  oneD = true; 
	}
      else if(dim == 2){
	index_str = "_" + index_str + "2D";
	twoD = true; 
	indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), 
							buildVarRefExp("_width", kernel_body)));
      }
      else if(dim == 3 ){
	indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), 
							buildVarRefExp("_width", kernel_body)));
	indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDZ, indexScope), 
							buildVarRefExp("_slice", kernel_body)));
	index_str = "_"+index_str + "3D";
	threeD = true;
      }
      SgAssignInitializer* initIndex = buildAssignInitializer(indexExp);

      SgVariableDeclaration* index = buildVariableDeclaration(index_str,
							      buildIntType(), initIndex, indexScope);

      //step 5 insert index expression in the kernel
      ROSE_ASSERT(index);
      insertStatementAfter(src_location, index );

      //step 6 check if there is a loop, if there is we need to update the index 
      //but we only update if the loop makes changes in the array reference 
      std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement);
      
      if(loopNest.size() > 0)
	{
	  SgForStatement* loop = *(loopNest.begin());
	  SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body());
	  SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp);
	  ROSE_ASSERT(update_stmt);
	  prependStatement(update_stmt, loop_body);
	}      
    }
} 
Example #29
0
	bool
checkIfNodeMaps(token_type tok, SgNode* node)
{
	bool nodeMaps = false;

	using namespace boost::wave;

        //By definition a compiler generated node can
        //not map to the token stream
        SgLocatedNode* compilerGeneratedNode = isSgLocatedNode(node);
        if( compilerGeneratedNode != NULL  )
          if(compilerGeneratedNode->get_file_info()->isCompilerGenerated() == true)
            return false;

//	     std::cout << get_token_name(tok) << " " << std::string(tok.get_value().c_str()) << " " << node->class_name() << " " << node->get_file_info()->get_line() << std::endl;
	//Mapping literal token id's
	switch(token_id(tok)){
		case T_PP_NUMBER:{

					 if(isSgValueExp(node)!=NULL)
						 nodeMaps=true;
					 break;
				 }
		case T_CHARLIT:{
				       if( ( isSgCharVal(node) != NULL ) |
						       ( isSgUnsignedCharVal(node) != NULL )
					 )
					       nodeMaps = true;
				       break;
			       }
		case T_FLOATLIT:{
					if( isSgFloatVal(node) != NULL )
						nodeMaps = true;

					break;
				}
		case T_INTLIT:{
				      if( ( isSgIntVal(node) != NULL ) || 
						      ( isSgUnsignedIntVal(node) != NULL ) 	       
					)
					      nodeMaps = true;
				      break;
			      }
		case T_LONGINTLIT:
			      {
				      if( ( isSgLongIntVal(node) != NULL ) |
						      ( isSgLongLongIntVal(node) != NULL ) |
						      ( isSgUnsignedLongLongIntVal(node) != NULL )

					)
					      nodeMaps = true;
				      break;
			      }
		case T_STRINGLIT:
			      {
				      if( isSgStringVal(node) != NULL )
					      nodeMaps = true;
				      break;
			      }
                case T_QUESTION_MARK:
                              {
                   		      if( isSgConditionalExp(node) != NULL )
                                        nodeMaps = true;
                                      break;
                              }
		case T_FALSE:
		case T_TRUE:
			      if( isSgBoolValExp(node) != NULL  )
				      nodeMaps = true;
			      break;
		default:
			      break;
	}

	//map keyword token id's
	switch(token_id(tok)){

		case T_ASM:
			if( isSgAsmStmt(node) != NULL  )
				nodeMaps = true;
			break;

		case T_AUTO: //auto
			//dont know
			break;
			/*case T_BOOL:
			//dont think this can be mapped
			break;*/
		case T_BREAK:
			if( isSgBreakStmt(node) != NULL  )
				nodeMaps = true;
			break;

		case T_CASE:
			if( isSgCaseOptionStmt(node) != NULL  )
				nodeMaps = true;
			break;

		case T_CATCH:
			if( isSgCatchOptionStmt(node) != NULL )
				nodeMaps = true;
			break;
			/*
			   case T_CHAR:
			//dont know
			break;
			*/	    

		case boost::wave::T_CLASS:
			if( isSgClassDeclaration(node) != NULL )
				nodeMaps = true;
			break;

		case T_CONST:
			// is it SgConstVolatileModifier?
			//dont know
			break;
		case T_CONTINUE:
			if( isSgContinueStmt(node) != NULL )
				nodeMaps = true;
			break;

			//case T_DEFAULT:
			//Dont know
			//  break;


		case T_DELETE:
			if( isSgDeleteExp(node) != NULL  )
				nodeMaps = true;
			break;

		case T_DO:
			if( isSgDoWhileStmt(node) != NULL  )
				nodeMaps = true;
			break;

		case T_ELSE:
			//dont know
			break;

		case T_EXPLICIT:
			//dont know
			break;
		case T_EXPORT:
		case T_EXTERN:
			break;
		case T_FOR:

			if( isSgForStatement(node) != NULL  )
				nodeMaps = true;
			break;
		case T_FRIEND:
			//dont know
			break;
		case T_GOTO:

			if( isSgGotoStatement(node) != NULL  )
				nodeMaps = true;
			break;

		case T_IF:
			//dont know how to handle this because if if-else
			break;
		case T_INLINE:
			//dont know
			break;
		case T_MUTABLE:
			//dont know
			break;
		case T_NAMESPACE:

			if( ( isSgNamespaceAliasDeclarationStatement(node) != NULL  ) |
					(isSgNamespaceDeclarationStatement(node) != NULL )
			  )
				nodeMaps = true;
			break;
		case T_NEW:

			if( isSgNewExp(node) != NULL  )
				nodeMaps = true;
			break;
		case T_OPERATOR:
		case T_PRIVATE:
		case T_PROTECTED:
		case T_PUBLIC:
		case T_REGISTER:
		case T_REINTERPRETCAST:
			//dont know
			break;

		case T_RETURN:
			if( isSgReturnStmt(node) != NULL  )
				nodeMaps = true;
			break;

		case T_SIZEOF:
			if( isSgSizeOfOp(node) != NULL  )
				nodeMaps = true;
			break;
		case T_STATIC:
		case T_STATICCAST:
			//dont know
			break;
		case T_STRUCT:
			if( isSgClassDeclaration(node) != NULL  )
				nodeMaps = true;
			break;
		case T_SWITCH:
			if( isSgSwitchStatement(node) != NULL  )
				nodeMaps = true;
			break;
			//case T_TEMPLATE:
			//dont know
			//   break;
		case T_THIS:

			if( isSgThisExp(node) != NULL  )
				nodeMaps = true;

			break;
		case T_THROW:

			if( isSgThrowOp(node) != NULL  )
				nodeMaps = true;

			break;
		case T_TRY:

			if( isSgTryStmt(node) != NULL  )
				nodeMaps = true;

			break;
		case boost::wave::T_TYPEDEF:

			if( isSgTypedefDeclaration(node) != NULL  )
				nodeMaps = true;

			break;

		case T_TYPEID:
			if( isSgTypeIdOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_TYPENAME:
			//dont know
			break;
		case T_UNION:
			if( isSgClassDeclaration(node) != NULL  )
				nodeMaps = true;

			break;
		case T_USING:
			if( isSgUsingDeclarationStatement(node) != NULL  )
				nodeMaps = true;

			break;
		case T_VIRTUAL:
			//dont know
			break;
		case T_VOLATILE:

			//is it SgConstVolatileModifier ?
			break;

		case T_WHILE:
			if( isSgWhileStmt(node) != NULL  )
				nodeMaps = true;

			break;

		default:
			break;

	}


	//map operator token id's
	switch(token_id(tok)){
		case T_AND:
          	case T_ANDAND:
			if( isSgAndOp(node) != NULL | isSgBitAndOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_ASSIGN:
			if ( isSgAssignOp(node) != NULL | isSgAssignInitializer(node) != NULL )
				nodeMaps = true;
			break;
		case T_ANDASSIGN:
			//do not know
			break;
		case T_OR:
			if ( isSgBitOrOp(node) != NULL || isSgOrOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_ORASSIGN:
			//do not know
			break;
		case T_XOR:
			if ( isSgBitXorOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_XORASSIGN:
			if ( isSgXorAssignOp(node) != NULL )
				nodeMaps = true;
			break;	
		case T_COMMA:
			if ( isSgCommaOpExp(node) != NULL )
				nodeMaps = true;
			break;
		case T_COLON:
			//dont know
			break;

		case T_DIVIDE:
			if ( isSgDivideOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_DIVIDEASSIGN:
			if ( isSgDivAssignOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_DOT:
			if ( isSgDotExp(node) != NULL )
				nodeMaps = true;
			break;


		case T_DOTSTAR:
			if ( isSgDotExp(node) != NULL )
				nodeMaps = true;
			break;


		case T_ELLIPSIS:
			//Dont know
			break;
		case T_EQUAL:
			if ( isSgEqualityOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_GREATER:
			if ( isSgGreaterThanOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_GREATEREQUAL:
			if ( isSgGreaterOrEqualOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_LEFTBRACE:
			//Dont know
			break;
		case T_LESS:
			if ( isSgLessThanOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_LESSEQUAL:
			if ( isSgLessOrEqualOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_LEFTPAREN:
			//Dont know
			break;

		case T_LEFTBRACKET:
		case T_RIGHTBRACKET:
			if ( isSgPntrArrRefExp(node) != NULL ) 
                             nodeMaps = true;
			break;
		case T_MINUS:
			if ( ( isSgSubtractOp(node) != NULL ) |
					( isSgMinusOp(node) != NULL ) )
				nodeMaps = true;
			break;

		case T_MINUSASSIGN:
			if ( isSgMinusAssignOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_MINUSMINUS:
			if ( isSgMinusMinusOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_PERCENT:
			if ( isSgModOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_PERCENTASSIGN:
			if ( isSgModAssignOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_NOT:
			if ( isSgNotOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_NOTEQUAL:
			if ( isSgNotEqualOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_OROR:
			if ( isSgOrOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_PLUS:
			if ( isSgAddOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_PLUSASSIGN:
			if ( isSgPlusAssignOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_PLUSPLUS:
			if ( isSgPlusPlusOp(node) != NULL )
				nodeMaps = true;
			break;


		case T_ARROW:
			if ( isSgArrowExp(node) != NULL )
				nodeMaps = true;
			break;

		case T_ARROWSTAR:
			if ( isSgArrowStarOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_QUESTION_MARK:
			//dont know
			break;

		case T_RIGHTBRACE:
		case T_RIGHTPAREN:
		case T_COLON_COLON:
		case T_SEMICOLON:
			//dont know
			break;
		case T_SHIFTLEFT:
			if ( isSgLshiftOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_SHIFTLEFTASSIGN:
			if ( isSgLshiftAssignOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_SHIFTRIGHT:
			if ( isSgRshiftOp(node) != NULL )
				nodeMaps = true;
			break;
		case T_SHIFTRIGHTASSIGN:
			if ( isSgRshiftAssignOp(node) != NULL )
				nodeMaps = true;
			break;

		case T_STAR:
			//dont know
                        if ( isSgMultiplyOp(node) != NULL || isSgPointerType(node) )
                          nodeMaps = true;
			break;
		case T_COMPL://~

                        if( isSgBitComplementOp(node)  != NULL  )
                          nodeMaps = true;
			//Dont know
			break;
		case T_STARASSIGN:
			if ( isSgMultAssignOp(node) != NULL )
				nodeMaps = true;

			break;
		case T_POUND_POUND:
		case T_POUND:
			//dont know
			break;

		case T_AND_ALT:
		case T_ANDASSIGN_ALT:
		case T_OR_ALT:
		case T_ORASSIGN_ALT:
		case T_XOR_ALT:
		case T_XORASSIGN_ALT:
		case T_LEFTBRACE_ALT:
		case T_LEFTBRACKET_ALT:
		case T_NOT_ALT:
		case T_NOTEQUAL_ALT:
		case T_RIGHTBRACE_ALT:
		case T_RIGHTBRACKET_ALT:
		case T_COMPL_ALT:
		case T_POUND_POUND_ALT:
		case T_POUND_ALT:
		case T_OR_TRIGRAPH:
		case T_XOR_TRIGRAPH:
		case T_LEFTBRACE_TRIGRAPH:
		case T_LEFTBRACKET_TRIGRAPH:
		case T_RIGHTBRACE_TRIGRAPH:
		case T_RIGHTBRACKET_TRIGRAPH:
		case T_COMPL_TRIGRAPH:
		case T_POUND_POUND_TRIGRAPH:
		case T_POUND_TRIGRAPH:
			//dont know
			break;
		default:
			break;
	}

	switch(token_id(tok)){
		case T_FALSE:
		case T_TRUE:
			break;
		case T_CHARLIT:
			if(SgProject::get_verbose() >= 1)
				std::cout << "char " << std::string(tok.get_value().c_str()) << std::endl;

			if( isSgCharVal(node) != NULL ){
				SgCharVal* charVal = isSgCharVal(node);
				if(SgProject::get_verbose() >= 1)
					std::cout << std::string(tok.get_value().c_str()) << std::endl;
				char tmp = charVal->get_value();
				if(SgProject::get_verbose() >= 1)
					std::cout << "From charlit: " << tmp << std::endl;

				if(("\""+std::string(&tmp)+"\"") == std::string(tok.get_value().c_str()) )
					nodeMaps = true;


			}
			break;
		case T_STRINGLIT:
			{
				if(SgProject::get_verbose() >= 1)
					std::cout << "string " <<std::string(tok.get_value().c_str()) << std::endl;

				if( isSgStringVal(node) != NULL ){
					SgStringVal* stringVal = isSgStringVal(node);
					if(SgProject::get_verbose() >= 1){
						std::cout << std::string(tok.get_value().c_str()) << std::endl;
						std::cout << "stringlit: " << stringVal->get_value() << std::endl;
					}
					if(("\""+stringVal->get_value()+"\"") == std::string(tok.get_value().c_str()) )
						nodeMaps = true;


				}
				break;
			}
			/*case V_SgWcharVal:

			  if( isSgWcharVal(node) != NULL )
			  if( std::string(isSgWcharVal(node)->get_value()) == std::string(tok.get_value().c_str()) )
			  nodeMaps = true;

			  break;*/
		default:
			break; 

	}

	if( token_id(tok) == T_IDENTIFIER ){
		if( isSgInitializedName(node) != NULL ){

			std::cout << "Identifier" << std::endl;
			SgInitializedName* initName = isSgInitializedName(node);
			std::cout <<  initName->get_name().getString() << " " << std::string(tok.get_value().c_str()) << std::endl;
			if( initName->get_name().getString() == std::string(tok.get_value().c_str()) ){
				nodeMaps = true;
			}
		}else if( isSgVarRefExp(node) != NULL ){
			SgVariableSymbol* varSymbol = isSgVarRefExp(node)->get_symbol();
			SgInitializedName* initName = varSymbol->get_declaration();
			if( initName->get_name().getString() == std::string(tok.get_value().c_str()) ){
				nodeMaps = true;
                                std::cout << "Maps:" << initName->get_name().getString() << " " << std::string(tok.get_value().c_str()) 
                                          << std::endl; 
                        }else
                          std::cout << "DONT Map:" << initName->get_name().getString() << " " << std::string(tok.get_value().c_str()) 
                                          << std::endl; 

		}else if( isSgFunctionRefExp(node) != NULL){
			SgFunctionRefExp* funcRef = isSgFunctionRefExp(node);
			SgFunctionSymbol* funcSymbol = funcRef->get_symbol_i();
			if( funcSymbol->get_declaration()->get_name().getString() == std::string(tok.get_value().c_str()) )
				nodeMaps = true;

		}else if( isSgMemberFunctionRefExp(node) != NULL){
			SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(node);
			SgMemberFunctionSymbol* funcSymbol = funcRef->get_symbol();
			if( funcSymbol->get_declaration()->get_name().getString() == std::string(tok.get_value().c_str()) )
				nodeMaps = true;

		}

	}

        //Exceptions to the general rule

		switch(token_id(tok)){
                  case T_CHARLIT:
                    {
                      switch(node->variantT())
                      {
                        case V_SgCharVal:
                        case V_SgComplexVal:
                        case V_SgDoubleVal:
                        case V_SgEnumVal:
                        case V_SgFloatVal:
                        case V_SgIntVal:
                        case V_SgLongDoubleVal:
                        case V_SgLongIntVal:
                        case V_SgLongLongIntVal:
                        case V_SgShortVal:
                        case V_SgStringVal:
                        case V_SgUnsignedCharVal:
                        case V_SgUnsignedIntVal:
                        case V_SgUnsignedLongLongIntVal:
                        case V_SgUnsignedLongVal:
                        case V_SgUnsignedShortVal:
                        case V_SgWcharVal: 
                          {
                            nodeMaps=true;
                            break;
                          }
                        default:
                          break;

                      };

                      break;
                    };
                }
	switch(boost::wave::token_id(tok)){
		case boost::wave::T_CHAR:
                  {
                  if(isSgTypeChar(node) != NULL)
                    nodeMaps=true;
                  break;
                  }
		case boost::wave::T_CONST:
                  break;
		case boost::wave::T_DOUBLE: 		
                  if(isSgTypeDouble(node) != NULL)
                    nodeMaps=true;
                  break;

		case boost::wave::T_INT:
                  if(isSgTypeInt(node) != NULL)
                    nodeMaps=true;
                  break;

		case boost::wave::T_LONG:
                  if(isSgTypeLong(node) != NULL)
                    nodeMaps=true;
                  break;

		case boost::wave::T_SHORT:
                 if(isSgTypeShort(node) != NULL)
                    nodeMaps=true;
                  break;

		case boost::wave::T_SIGNED:
		case boost::wave::T_UNSIGNED:
		case boost::wave::T_VOID:
                  if(isSgTypeVoid(node) != NULL)
                    nodeMaps=true;
                  break;
		default:
			break;

	};

	return nodeMaps;
}
Example #30
0
  // Count the load and store bytes for the 
  // I think we can only return expressions to calculate the value, not the actual values,
  // since sizeof(type) is machine dependent
  //   Consider both scalar and  array accesses by default. Consider both floating point and integer types by default.
  // return a pair of expressions:  
  //       load_byte_exp, and 
  //       store_byte_exp
  // Algorithm: 
  //    1.  Call side effect analysis to find read/write variables, some reference may trigger both read and write accesses
  //        Accesses to the same array/scalar variable are grouped into one read (or write) access
  //         e.g. array[i][j],  array[i][j+1],  array[i][j-1], etc are counted a single access
  //    2.  Group accesses based on the types (same type?  increment the same counter to shorten expression length)
  //    4.  Iterate on the results to generate expression like  2*sizeof(float) + 5* sizeof(double)
  // As an approximate, we use simple analysis here assuming no function calls.
  std::pair <SgExpression*, SgExpression*> CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars /* = true */, bool includeIntType /* = true */)
  {
    std::pair <SgExpression*, SgExpression*> result; 
    assert (input != NULL);
   // the input is essentially the loop body, a scope statement
    SgScopeStatement* scope = isSgScopeStatement(input);

    // We need to record the associated loop info.
    //SgStatement* loop= NULL;
    SgForStatement* forloop = isSgForStatement(scope->get_scope());
    SgFortranDo* doloop = isSgFortranDo(scope->get_scope());

    if (forloop)
    {
      //loop = forloop;
    }
    else if (doloop)
    {  
      //loop = doloop;
    }
    else
    {
      cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< input->class_name()<<endl;
      assert(false);
    }

    //Plan A: use and extend Qing's side effect analysis
    std::set<SgInitializedName*> readVars;
    std::set<SgInitializedName*> writeVars;

    bool success = SageInterface::collectReadWriteVariables (isSgStatement(input), readVars, writeVars);
    if (success!= true)
    {
       cout<<"Warning: CountLoadStoreBytes(): failed to collect load/store, mostly due to existence of function calls inside of loop body @ "<<input->get_file_info()->get_line()<<endl;
    }

    std::set<SgInitializedName*>::iterator it;
    if (debug)
      cout<<"debug: found read variables (SgInitializedName) count = "<<readVars.size()<<endl;
    for (it=readVars.begin(); it!=readVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array (iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }

    if (!includeScalars )
      readVars =  filterVariables (readVars);
    if (debug)
      cout<<"debug: found write variables (SgInitializedName) count = "<<writeVars.size()<<endl;
    for (it=writeVars.begin(); it!=writeVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array(iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }
    if (!includeScalars )
      writeVars =  filterVariables (writeVars);
    result.first =  calculateBytes (readVars, scope, true);
    result.second =  calculateBytes (writeVars, scope, false);
    return result;
  }