コード例 #1
0
ファイル: specificationTraversal.C プロジェクト: 8l/rose
/*
 * Case to handle interleaveArrayOption
 * C = interleaveAcrossArrays(A,B);
 * i/p = A,B ; o/p = C ; operation = interleaveAcrossArrays
 */
void specificationTraversal::handleInterLeaveAcrossArrays(SgFunctionCallExp* funcCallExp) {
	ROSE_ASSERT(isSgFunctionCallExp(funcCallExp) != NULL);

	SgExpressionPtrList& args = funcCallExp->get_args()->get_expressions();

	vector < string > inputArgs;
	vector < string > outputArgs;

	// Extract the argument and put it into the input list
	for (SgExpressionPtrList::iterator expr = args.begin(); expr != args.end(); expr++) {
		SgVarRefExp* varRefExp = isSgVarRefExp(*expr);
		ROSE_ASSERT(varRefExp != NULL);

		string argName = varRefExp->get_symbol()->get_declaration()->get_name().getString();
		inputArgs.push_back(argName);

#if DEBUG
		cout << " Input Arg: " << argName << endl;
#endif
	}

	// Extract the output
	SgAssignOp* assignOp = isSgAssignOp(funcCallExp->get_parent());
	SgVarRefExp* outputVarRefExp = isSgVarRefExp(assignOp->get_lhs_operand());
	ROSE_ASSERT(outputVarRefExp != NULL);
	string outputName = outputVarRefExp->get_symbol()->get_declaration()->get_name().getString();
	outputArgs.push_back(outputName);

#if DEBUG
	cout << " Output Arg: " << outputName << endl;
#endif

	// Add to worklist
	transformationWorklist.addToWorklist(LayoutOptions::InterleaveAcrossArrays, inputArgs, outputArgs);
}
コード例 #2
0
InheritedAttribute
BugSeeding::evaluateInheritedAttribute (
     SgNode* astNode,
     InheritedAttribute inheritedAttribute )
   {
  // Use this if we only want to seed bugs in loops
     bool isLoop = inheritedAttribute.isLoop           ||
                   (isSgForStatement(astNode) != NULL) ||
                   (isSgWhileStmt(astNode) != NULL)    ||
                   (isSgDoWhileStmt(astNode) != NULL);
  // Add Fortran support
     isLoop = isLoop || (isSgFortranDo(astNode) != NULL);

  // Mark future noes in this subtree as being part of a loop
     inheritedAttribute.isLoop = isLoop;

  // To test this on simple codes, optionally allow it to be applied everywhere
     bool applyEveryWhere = true;

     if (isLoop == true || applyEveryWhere == true)
        {
       // The inherited attribute is true iff we are inside a loop and this is a SgPntrArrRefExp.
          SgPntrArrRefExp *arrayReference = isSgPntrArrRefExp(astNode);
          if (arrayReference != NULL)
             {
            // Mark as a vulnerability
               inheritedAttribute.isVulnerability = true;

            // Now change the array index (to seed the buffer overflow bug)
               SgVarRefExp* arrayVarRef = isSgVarRefExp(arrayReference->get_lhs_operand());
               ROSE_ASSERT(arrayVarRef != NULL);
               ROSE_ASSERT(arrayVarRef->get_symbol() != NULL);
               SgInitializedName* arrayName = isSgInitializedName(arrayVarRef->get_symbol()->get_declaration());
               ROSE_ASSERT(arrayName != NULL);
               SgArrayType* arrayType = isSgArrayType(arrayName->get_type());
               ROSE_ASSERT(arrayType != NULL);
               SgExpression* arraySize = arrayType->get_index();

               SgTreeCopy copyHelp;
            // Make a copy of the expression used to hold the array size in the array declaration.
               SgExpression* arraySizeCopy = isSgExpression(arraySize->copy(copyHelp));
               ROSE_ASSERT(arraySizeCopy != NULL);

            // This is the existing index expression
               SgExpression* indexExpression = arrayReference->get_rhs_operand();
               ROSE_ASSERT(indexExpression != NULL);

            // Build a new expression: "array[n]" --> "array[n+arraySizeCopy]", where the arraySizeCopy is a size of "array"
               SgExpression* newIndexExpression = buildAddOp(indexExpression,arraySizeCopy);

            // Substitute the new expression for the old expression
               arrayReference->set_rhs_operand(newIndexExpression);
             }
        }

     return inheritedAttribute;
   }
コード例 #3
0
ファイル: inlinerSupport.C プロジェクト: jukoepke/edg4x-rose
 virtual void visit(SgNode* n) {
     if (isSgVarRefExp(n)) {
         SgVarRefExp* vr = isSgVarRefExp(n);
         assert (vr->get_symbol());
         if (vr->get_symbol()->get_declaration() == initname) {
             if (inSimpleContext(vr) || !needSimpleContext) {
                 SgTreeCopy tc;
                 isSgExpression(n->get_parent())->replace_expression(
                     vr, isSgExpression(initexpr->copy(tc)));
             }
         }
     }
 }
コード例 #4
0
/**
 * Matches assignment statements (including pointer association)
 */
void FortranAnalysis::visit(SgExprStatement * expr_stmt)
{
   if (matchRegionAssignment(expr_stmt)) {
      SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression());
      SgVarRefExp * var = isSgVarRefExp(bin_op->get_lhs_operand());
      if (var == NULL) return;
      var->get_symbol()->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR"));
      printf("FortranAnalysis:: adding halo attr to %s\n",
             var->get_symbol()->get_name().getString().c_str());
   }
   else if (HaloRefSearch::findHaloRef(expr_stmt)) {
      expr_stmt->setAttribute("halo_ref", new AstTextAttribute("HAS_HALO_REF"));
      printf("FortranAnalysis:: adding halo attr to statement\n");
   }
}
コード例 #5
0
int
main(int argc, char* argv[])
   {
     SgProject* project = frontend(argc, argv);

     std::vector<SgIfStmt*> ifs = SageInterface::querySubTree<SgIfStmt>(project, V_SgIfStmt);
     BOOST_FOREACH(SgIfStmt* if_stmt, ifs)
        {
          if (SgExpression *se = isSgExprStatement(if_stmt->get_conditional())->get_expression())
             {
               cout << "--->" << se->unparseToString() << "<---" << endl;

               Rose_STL_Container<SgNode*> variableList = NodeQuery::querySubTree(se, V_SgVarRefExp);
               for (Rose_STL_Container<SgNode*>::iterator i = variableList.begin(), end = variableList.end(); i != end; i++)
                  {
                    SgVarRefExp *varRef = isSgVarRefExp(*i);
                    SgVariableSymbol *currSym = varRef->get_symbol();
                    cout << "Looking at: --|" << currSym->get_name().str() << "|--" << endl;

                    SgDeclarationStatement *decl = currSym->get_declaration()->get_declaration();

                    cout << "declaration: " << decl->unparseToString() << endl;

                    SgConstVolatileModifier cvm = decl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
                    bool constness = cvm.isConst();

                    cout << "constness via isConst(): " << constness << endl;
                    cout << cvm.displayString() << endl;
                  }
             }
        }

     return 0;
   }
コード例 #6
0
int BasicProgmemTransform::getBuffersizeNeededForFunction(SgFunctionDeclaration *func) {
	int maxSize = 0;
	Rose_STL_Container<SgNode *> funcCalls = NodeQuery::querySubTree(func, V_SgFunctionCallExp);
	for(auto &funcCall: funcCalls) {
		SgFunctionCallExp *fcall = isSgFunctionCallExp(funcCall);
		Function callee(fcall);
//		printf("function called: %s\n", callee.get_name().str());
		if(isArduinoProgmemSafeFunction(callee)) {
			continue;
		}
		param_pos_list ignoredPositions = getPositionsToIgnore(callee.get_name().getString());
		SgExpressionPtrList params = fcall->get_args()->get_expressions();
		int size = 0;
		for(int pos = 0; pos < params.size(); pos++) {
			if(ignoredPositions.find(pos) != ignoredPositions.end()) {
				continue;
			}
			SgVarRefExp* var = isSgVarRefExp(params[pos]);
			if(var) {
				SgInitializedName *initName = var->get_symbol()->get_declaration();
				if(isVarDeclToRemove(initName)) {
					SgExpression *rhs = getRHSOfVarDecl(initName);
					if(rhs && isSgStringVal(rhs)) {
						size += isSgStringVal(rhs)->get_value().size() + 1;
					}
				}
			}
		}
		if(size > maxSize) {
			maxSize = size;
		}
	}
	return maxSize;
}
コード例 #7
0
/*
 *  Fix op structure calls and inject debug names
 */
void OPSource::fixOpFunctions(SgNode *n)
{
  SgName var_name;
  SgFunctionCallExp *fn = isSgFunctionCallExp(n);
  if(fn != NULL)
  {
    string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString();
    if(fn_name.compare("op_decl_const")==0) 
    {
      SgExprListExp* exprList = fn->get_args();
      SgExpressionPtrList &exprs = exprList->get_expressions();
      if( isSgStringVal(exprs.back()) == NULL )
      {
        SgVarRefExp* varExp = isSgVarRefExp(exprs[1]);
        if(!varExp)
        {
          varExp = isSgVarRefExp(isSgAddressOfOp(exprs[1])->get_operand_i());
        }

        if(varExp)
        {
          var_name = varExp->get_symbol()->get_name();
        }
        cout << "---Injecting Debug Name for const: " << var_name.getString() << "---" << endl;
        exprList->append_expression(buildStringVal(var_name));
      }
    }
  }
}
コード例 #8
0
CPPImperialOpConstDefinition::CPPImperialOpConstDefinition (
    SgExprListExp * parameters)
{
  using boost::lexical_cast;
  using std::string;

  dimension
      = isSgIntVal (parameters->get_expressions ()[indexDimenson])->get_value ();

  SgAddressOfOp * addressOfOperator = isSgAddressOfOp (
      parameters->get_expressions ()[indexData]);

  if (addressOfOperator != NULL)
  {
    SgVarRefExp * operandExpression = isSgVarRefExp (
        addressOfOperator->get_operand ());

    ROSE_ASSERT (operandExpression != NULL);

    variableName = operandExpression->get_symbol ()->get_name ().getString ();
  }
  else
  {
    variableName
        = isSgVarRefExp (parameters->get_expressions ()[indexData])->get_symbol ()->get_name ().getString ();
  }

  ROSE_ASSERT (dimension > 0);
  ROSE_ASSERT (variableName.empty () == false);

  Debug::getInstance ()->debugMessage ("Found an OP_CONST declaration: '"
      + variableName + "' Its dimension is "
      + lexical_cast <string> (dimension), Debug::FUNCTION_LEVEL, __FILE__,
      __LINE__);
}
コード例 #9
0
// 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;
}
コード例 #10
0
ファイル: inliner.C プロジェクト: alexjohn1362/rose
 virtual void visit(SgNode* n) {
   SgVarRefExp* vr = isSgVarRefExp(n);
   if (!vr) return;
   SgInitializedName* in = vr->get_symbol()->get_declaration();
   paramMapType::const_iterator iter = paramMap.find(in);
   if (iter == paramMap.end()) return; // This is not a parameter use
   vr->set_symbol(iter->second);
 }
コード例 #11
0
ファイル: inlinerSupport.C プロジェクト: jukoepke/edg4x-rose
    virtual void visit(SgNode* n) {
        if (isSgBasicBlock(n)) {
            SgBasicBlock* bb = isSgBasicBlock(n);
            SgStatementPtrList& stmts = bb->get_statements();
            size_t initi;
            for (size_t decli = 0; decli < stmts.size(); ++decli) {
                if (isSgVariableDeclaration(stmts[decli])) {
                    SgVariableDeclaration* decl = isSgVariableDeclaration(stmts[decli]);
                    SgInitializedNamePtrList& vars = decl->get_variables();
                    for (size_t vari = 0; vari != vars.size(); ++vari) {
                        SgInitializedName* in = vars[vari];
                        if (in->get_initializer() == 0) {
                            bool used = false;
                            for (initi = decli + 1; initi < stmts.size();
                                    used |= containsVariableReference(stmts[initi], in),
                                    ++initi) {
                                SgExprStatement* initExprStmt = isSgExprStatement(stmts[initi]);
                                if (initExprStmt) {
                                    SgExpression* top = initExprStmt->get_expression();
                                    if (isSgAssignOp(top)) {
                                        SgVarRefExp* vr = isSgVarRefExp(isSgAssignOp(top)->get_lhs_operand());
                                        ROSE_ASSERT(isSgAssignOp(top) != NULL);
                                        SgExpression* newinit = isSgAssignOp(top)->get_rhs_operand();
                                        if (!used && vr && vr->get_symbol()->get_declaration() == in) {
                                            ROSE_ASSERT(newinit != NULL);
                                            // printf ("MoveDeclarationsToFirstUseVisitor::visit(): newinit = %p = %s \n",newinit,newinit->class_name().c_str());
                                            ROSE_ASSERT(newinit->get_type() != NULL);
                                            SgAssignInitializer* i = new SgAssignInitializer(SgNULL_FILE,newinit,newinit->get_type());
                                            i->set_endOfConstruct(SgNULL_FILE);
                                            // printf ("Built a SgAssignInitializer #1 \n");
                                            vars[vari]->set_initializer(i);
                                            stmts[initi] = decl;
                                            newinit->set_parent(i);

                                            // DQ (6/23/2006): Set the parent and file_info pointers
                                            // printf ("Setting parent of i = %p = %s to parent = %p = %s \n",i,i->class_name().c_str(),in,in->class_name().c_str());
                                            i->set_parent(in);
                                            ROSE_ASSERT(i->get_parent() != NULL);

                                            i->set_file_info(new Sg_File_Info(*(newinit->get_file_info())));
                                            ROSE_ASSERT(i->get_file_info() != NULL);

                                            // Assumes only one var per declaration FIXME
                                            ROSE_ASSERT (vars.size() == 1);
                                            stmts.erase(stmts.begin() + decli);
                                            --decli; // To counteract ++decli in loop header
                                            break; // To get out of initi loop
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
コード例 #12
0
// Propagate definitions of a variable to its uses.
// Assumptions: var is only assigned at the top level of body
//              nothing var depends on is assigned within body
// Very simple algorithm designed to only handle simplest cases
void simpleUndoFiniteDifferencingOne(SgBasicBlock* body, SgExpression* var)
   {
     SgExpression* value = 0;
     SgStatementPtrList& stmts = body->get_statements();
     vector<SgStatement*> stmts_to_remove;

     for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
        {
       // cout << "Next statement: value = " << (value ? value->unparseToString() : "(null)") << endl;
       // cout << (*i)->unparseToString() << endl;
          if (isSgExprStatement(*i) && isSgAssignOp(isSgExprStatement(*i)->get_expression()))
             {
               SgAssignOp* assignment = isSgAssignOp(isSgExprStatement(*i)->get_expression());
            // cout << "In assignment statement " << assignment->unparseToString() << endl;
               if (value)
                    replaceCopiesOfExpression(var, value, assignment->get_rhs_operand());
               if (isSgVarRefExp(assignment->get_lhs_operand()) && isSgVarRefExp(var))
                  {
                    SgVarRefExp* vr = isSgVarRefExp(assignment->get_lhs_operand());
                    if (vr->get_symbol()->get_declaration() == isSgVarRefExp(var)->get_symbol()->get_declaration())
                       {
                         value = assignment->get_rhs_operand();
                         stmts_to_remove.push_back(*i);
                       }
                  }
             }
            else
             {
               if (value)
                    replaceCopiesOfExpression(var, value, *i);
             }
        }

     for (vector<SgStatement*>::iterator i = stmts_to_remove.begin(); i != stmts_to_remove.end(); ++i) {
          stmts.erase(std::find(stmts.begin(), stmts.end(), *i));
     }

     if (value)
        {
       // DQ (12/17/2006): Separate out the construction of the SgAssignOp from the SgExprStatement to support debugging and testing.
       // stmts.push_back(new SgExprStatement(SgNULL_FILE, new SgAssignOp(SgNULL_FILE, var, value)));
          var->set_lvalue(true);
          SgAssignOp* assignmentOperator = new SgAssignOp(SgNULL_FILE, var, value);
          var->set_parent(assignmentOperator);
          value->set_parent(assignmentOperator);

          printf ("In simpleUndoFiniteDifferencingOne(): assignmentOperator = %p \n",assignmentOperator);

       // DQ: Note that the parent of the SgExprStatement will be set in AST post-processing (or it should be).
          SgExprStatement* es = new SgExprStatement(SgNULL_FILE, assignmentOperator);
          assignmentOperator->set_parent(es);
          stmts.push_back(es);
          es->set_parent(body);
        }
   }
コード例 #13
0
void HaloRefSearch::visit(SgNode * node)
{
   switch (node->variantT()) {
   case V_SgVarRefExp:
      SgVarRefExp * var = isSgVarRefExp(node);
      if (var->get_symbol()->getAttribute("halo_attr") != NULL) {
         found = true;
      }
      break;
   }
}
コード例 #14
0
	foreach(SgAssignOp* op, assigns)
	{
		SgVarRefExp* var = isSgVarRefExp(op->get_lhs_operand());
		SgInitializedName* decl = var->get_symbol()->get_declaration();
		std::cout << "Found assignment to " << var->get_symbol()->get_name().str();
		if (decl->get_protected_declaration())
		{
			std::cout << ", which is protected.";
		}
		std::cout << "\t\t" << op->unparseToString();
		std::cout << std::endl;
		SgNode* assign_scope = SageInterface::getScope(op);
		SgNode* var_scope = decl->get_scope();
		if (SageInterface::isAncestor(var_scope, assign_scope))
		{
			std::cout << "\tAnd both are in the same scope.\n";
		}
		else
		{
			std::cout << "\tIn different scopes.\n";
		}
	}
コード例 #15
0
FortranOpSetDefinition::FortranOpSetDefinition (SgExprListExp * parameters)
{
  /*
   * ======================================================
   * Get name of OP_SET dimension variable
   * ======================================================
   */

  if (isSgPntrArrRefExp (
      parameters->get_expressions ()[index_setCardinalityName]) != NULL)
  {
    dimensionName
        = isSgPntrArrRefExp (
            parameters->get_expressions ()[index_setCardinalityName])->unparseToString ();
  }
  else
  {
    dimensionName
        = isSgVarRefExp (
            parameters->get_expressions ()[index_setCardinalityName])->get_symbol ()->get_name ().getString ();
  }

  /*
   * ======================================================
   * Get name of OP_SET
   * ======================================================
   */

  SgVarRefExp * opSetVariableReference;

  if (isSgDotExp (parameters->get_expressions ()[index_OpSetName]) != NULL)
  {
    opSetVariableReference = isSgVarRefExp (isSgDotExp (
        parameters->get_expressions ()[index_OpSetName])->get_rhs_operand ());
  }
  else
  {
    opSetVariableReference = isSgVarRefExp (
        parameters->get_expressions ()[index_OpSetName]);
  }

  variableName
      = opSetVariableReference->get_symbol ()->get_name ().getString ();

  ROSE_ASSERT (dimensionName.empty () == false);
  ROSE_ASSERT (variableName.empty () == false);

  Debug::getInstance ()->debugMessage ("Found an OP_SET definition: '"
      + variableName + "'. Its dimension is contained in '" + dimensionName
      + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__);
}
コード例 #16
0
/*
 * Create LHS of a loop dependent statement
 */
void createFirstLoop(SgExprStatement* exprStatement,
		ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData,
		OperandDataBaseType & operandDataBase) {
	//transformArrayRefAPP(exprStatement, arrayAssignmentStatementQueryInheritedData, operandDataBase);

	// Change the LHS, it will the first PntrArrayRef
	SgScopeStatement* scope = exprStatement->get_scope();

	// Figure out the dimensionality of the statement globally
	vector<SgExpression*> parameters;
	int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays
	ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE);
	if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) {
		// The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData
		maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension;
	}

	// Then we want the minimum of all the dimensions accesses (or is it the maximum?)
	for (int n = 0; n < maxNumberOfIndexOffsets; n++) {
		parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope));
	}

	vector<SgVarRefExp*> varRefList = querySubTree<SgVarRefExp> (exprStatement, V_SgVarRefExp);

	ROSE_ASSERT(varRefList.size() > 0);

	SgVarRefExp* lhsVarRefExp = (*varRefList.begin()); // LHS should be the first ref

	SgExpression* replaceExp;
	if(isFunctionParenthesisOperator(isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent())))
	{
		replaceExp = isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent());
	}
	else
	{
		replaceExp = lhsVarRefExp;
	}


	SgVarRefExp* newVarRefExp = buildVarRefExp("__T_pointer", scope);
	string functionName = "SC_"+lhsVarRefExp->get_symbol()->get_declaration()->get_name();
	SgFunctionCallExp* functionCallExp = buildFunctionCallExp(functionName, buildIntType(),
			buildExprListExp(parameters), scope);
	SgPntrArrRefExp* pntrArrRefExp2 = buildPntrArrRefExp(newVarRefExp, functionCallExp);

	ROSE_ASSERT(replaceExp != NULL);
	replaceExpression(replaceExp, pntrArrRefExp2);

	return;
}
コード例 #17
0
Rose_STL_Container<SgVarRefExp*>
buildListOfVariableReferenceExpressionsUsingGlobalVariables ( SgNode* node )
   {
  // This function builds a list of "uses" of variables (SgVarRefExp IR nodes) within the AST.

  // return variable
     Rose_STL_Container<SgVarRefExp*> globalVariableUseList;

  // list of all variables (then select out the global variables by testing the scope)
     Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree ( node, V_SgVarRefExp );

     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
     while(i != nodeList.end())
        {
          SgVarRefExp *variableReferenceExpression = isSgVarRefExp(*i);
          assert(variableReferenceExpression != NULL);

          assert(variableReferenceExpression->get_symbol() != NULL);
          assert(variableReferenceExpression->get_symbol()->get_declaration() != NULL);
          assert(variableReferenceExpression->get_symbol()->get_declaration()->get_scope() != NULL);

       // Note that variableReferenceExpression->get_symbol()->get_declaration() returns the 
       // SgInitializedName (not the SgVariableDeclaration where it was declared)!
          SgInitializedName* variable = variableReferenceExpression->get_symbol()->get_declaration();

          SgScopeStatement* variableScope = variable->get_scope();

       // Check if this is a variable declared in global scope, if so, then save it
          if (isSgGlobal(variableScope) != NULL)
             {
               globalVariableUseList.push_back(variableReferenceExpression);
             }
          i++;
        }

     return globalVariableUseList;
   }
コード例 #18
0
/**********************************************************
 *  get the InitName for a sgNode
 *********************************************************/
std::string DefUseAnalysis::getInitName(SgNode* sgNode){
  SgInitializedName* initName = NULL;
  string name = "none";
  if (isSgVarRefExp(sgNode)) {
    SgVarRefExp* varRefExp = isSgVarRefExp(sgNode);
    initName = varRefExp->get_symbol()->get_declaration();
    name = initName->get_qualified_name().str();
  }
  else if (isSgInitializedName(sgNode)) {
    initName =isSgInitializedName(sgNode);
    name = initName->get_qualified_name().str();
  }  
  else {
    name = sgNode->class_name();
  }
  return name;
}
コード例 #19
0
void FortranAnalysis::visit(SgFunctionCallExp * fcall)
{
   SgFunctionRefExp  * fref  = isSgFunctionRefExp(fcall->get_function());

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

      if (name == "interior" && it != fcall->get_args()->get_expressions().end()) {
         SgVarRefExp * var = isSgVarRefExp(*it);
         SgSymbol * sym = var->get_symbol();
         sym->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR"));
         debug("SgFunctionCallExp: adding halo attribute to %s\n",
                sym->get_name().getString().c_str());
      }
   }
}
コード例 #20
0
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());
		}

	}
}
コード例 #21
0
ファイル: taintAnalysis.C プロジェクト: LindaLovelace/rose
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;
}
コード例 #22
0
std::set<varID> BasicProgmemTransform::getVarsBoundToNonPlaceholderPointers() {
	std::set<varID> results;
	Rose_STL_Container<SgNode *> varRefs = NodeQuery::querySubTree(project, V_SgVarRefExp);
	for(auto &ref: varRefs) {
		SgVarRefExp *var = isSgVarRefExp(ref);
		if(isFromLibrary(var->get_symbol()->get_declaration())){
			continue;
		}
		varID varRef = SgExpr2Var(var);
		if(varRef.str().find(STRING_LITERAL_PREFIX) == std::string::npos) {
			std::set<varID> aliases = aliasAnalysis->getAliasesForVariableAtNode(var, varRef);
			if(aliases.size() == 0) {
				aliases.insert(varRef);
			}
			results.insert(aliases.begin(), aliases.end());
		}
	}
	return results;
}
コード例 #23
0
bool FortranAnalysis::matchRegionAssignment(SgExprStatement * expr_stmt)
{
   SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression());
   if (bin_op == NULL) return false;

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

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

   SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin();
   std::string name = fref->get_symbol()->get_name().getString();
   if (name == "interior" && it != fcall->get_args()->get_expressions().end()) {
      SgVarRefExp * var = isSgVarRefExp(*it);
      if (var == NULL) return false;
      AstTextAttribute * attr = (AstTextAttribute *) var->get_symbol()->getAttribute("dummy_attr");
      if (attr == NULL) return false;
      if (attr->toString() != "DUMMY_ARRAY_ARG") return false;
   }
   return true;
}
コード例 #24
0
ファイル: register_pointers.cpp プロジェクト: ssrg-vt/aira
/*
 * Constructor for registering an expression.
 */
RegisterPointers::RegisterPointers(SgExpression* p_expression) :
	expression(p_expression),
	varName(NULL),
	varSymbol(NULL),
	isGlobal(false),
	definedInSystemHeader(false),
	compilerGenerated(false),
	addrUsedInIO(false)
{
	//TODO maybe need to do a while loop until we get a var ref?
	ROSE_ASSERT(isSgPointerType(expression->get_type()));
	SgAddressOfOp* addrOf = isSgAddressOfOp(expression);
	if(addrOf)
	{
		//Check to make sure we don't register vars the compiler added
		SgVarRefExp* varRef = isSgVarRefExp(addrOf->get_operand());
		if(varRef)
		{
			varSymbol = varRef->get_symbol();
			compilerGenerated = isCompilerGenerated(varSymbol);
			addrUsedInIO = isAddrTakenInIrrelevantFunc(varRef);
		}
	}
}
コード例 #25
0
ファイル: selfTest.C プロジェクト: Federico2014/edg4x-rose
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();
}
コード例 #26
0
DataDependenceGraph::DataDependenceGraph(SgNode * head,EDefUse * du, InterproceduralInfo * ii):_head(isSgFunctionDefinition
                                                                                                     (head))
{
  defuse=du;
#else
  DataDependenceGraph::DataDependenceGraph(SgNode * head, InterproceduralInfo * ii):_head(isSgFunctionDefinition
                                                                                          (head))
    {
      _buildDefUseChains(_head);
#endif
        _interprocedural = ii;
      functionDef=isSgFunctionDefinition(head);
      functionDecl=functionDef->get_declaration();
      buildDDG();
    }

    void outputNodeInfo(std::ostream & os,SgNode* defSgNode)
    {
      if (isSgInitializedName(defSgNode)!=NULL) {
          os <<"\""<<isSgInitializedName(defSgNode)->get_qualified_name().getString()<<"\" of class "<<defSgNode->class_name();
      }
      else {
        os <<"\""<<defSgNode->unparseToString()<<"\" of class "<<defSgNode->class_name();
      }
    }
    










    //construct the data dependence graph
    void DataDependenceGraph::buildDDG()
    {

         //for debugging purposes, print out the def and use maps
         //defuse->printDefUse();


      //iterate over all variable references in the function
      DependenceNode *defDepNode=NULL;
      DependenceNode *useDepNode=NULL;

      // this graph is intersted of all ueses of variables, up so far NO POINTER analysis is done...
      Rose_STL_Container< SgNode * > varUse=NodeQuery::querySubTree(_head,V_SgVarRefExp);

      for (Rose_STL_Container< SgNode * >::iterator i = varUse.begin();i!=varUse.end();i++) {
        // if the variable is a global, special treatmen
    
        SgVarRefExp * varRef = isSgVarRefExp(*i);
        SgNode * varDef;
        SgNode * interestingUseParent,
          * interestingDefParent;
        
        
        // get the correct interesting node for the use
        // uw-mist TODO: rewrite the getnextparent
        interestingUseParent=getNextParentInterstingNode(varRef);


        //Now, grab the proper use node in the system dependence graph, or create it if it doesn't exist
        //uw-mist replaced the call
        //if (isSgFunctionCallExp(getNextParentInterstingNode(interestingUseParent->get_parent()))) 
        if (isSgFunctionCallExp(interestingUseParent)) {
          // check if the variable is used as argument in a function call (special case in system dependence graph)
          useDepNode=getNode(DependenceNode::ACTUALIN,varRef);

        } else if (isSgFunctionDefinition(interestingUseParent)) {
          continue;
        } else {
          useDepNode=getNode(interestingUseParent);
        }


        // the current node is defined, next get the defining nodes
        
        //Jim: What's the point of jumping straight to the decleration here?
        //We should want the def. from the defuse chains...
        std::vector< SgNode* > defPlaces,usePlaces;
        SgInitializedName *initName=varRef->get_symbol()->get_declaration();
        //VERBOSE_DEBUG_STMT(std::string varName=initName->get_name().getString();)
        

        // handle global variable definition
        if (defuse->isNodeGlobalVariable(initName)) {
          //            initName->get_declaration (); 
          // the variable is a global variable, now connect the statement with the global def
          if (DUVariableAnalysisExt::isIDef(varRef) || DUVariableAnalysisExt::isDef(varRef)) {
            // create a ade from the ref to the globalInitialisation
            establishEdge(useDepNode,getNode(initName->get_declaration()),GLOBALVAR_HELPER);                
          }
          if (DUVariableAnalysisExt::isIUse(varRef) || DUVariableAnalysisExt::isUse(varRef)) {
            // create a ade from the ref to the globalInitialisation
            establishEdge(getNode(initName->get_declaration()),useDepNode,GLOBALVAR_HELPER);
          }
        }
        


        //Main Case: Variable Use
        //    if the current use of the variable is a use
        if (DUVariableAnalysisExt::isUse(varRef) || DUVariableAnalysisExt::isIUse(varRef))
        {
          //Jim: Debug lines, just uncommented
          //cout <<"initname: 2: intersetingUseParent for "<< initName->get_name().getString() << 
          //  " is "<<interestingUseParent->unparseToString()<<" and is of type "<<interestingUseParent->class_name()<<endl;
          //VERBOSE_DEBUG_BLOCK(std::cout<<"\tUSE"<<endl;)
          // get definition places for the interesting node
          //Jim: this appears to be dead code
          //defPlaces=defuse->getDefFor(interestingUseParent,initName);
          
          //Does the below not over write the above?  Curious.  Removing the below creates a false self-ref link on x+=5;
          defPlaces=defuse->getDefFor(varRef,initName);
          // for all possible definition places
          for (unsigned int j=0;j<defPlaces.size();j++) {
            // get the def, so we don't have to use the array all the time
            varDef=defPlaces[j];
            // make sure it is the interesting def parent
            interestingDefParent=getNextParentInterstingNode(varDef);



            
            defDepNode=NULL;

            // if the next interesting node is a function call, this definition comes from a ACTUAL_OUT
            if (isSgFunctionCallExp(getNextParentInterstingNode(interestingDefParent->get_parent())) ||
                isSgFunctionCallExp(getNextParentInterstingNode(interestingDefParent)) ||
                isSgFunctionCallExp(interestingDefParent) ||
                isSgFunctionCallExp(interestingDefParent->get_parent()) ||
                isSgFunctionCallExp(interestingDefParent->get_parent()->get_parent()) ) {

                    //establish edge from function call to actual out
                    defDepNode=getNode(DependenceNode::ACTUALOUT,interestingDefParent);
                    establishEdge(defDepNode,useDepNode,DATA);                            
            // if the next node is a function definition
            } else if (isSgFunctionDefinition(interestingDefParent))
            {
                    //connect edge from function definition to formal in
                    defDepNode=getNode(DependenceNode::FORMALIN,interestingDefParent);
                    establishEdge(defDepNode,useDepNode,DATA);
            }
            // if the next node is a function parameter arg list
            else if (isSgFunctionParameterList(interestingDefParent->get_parent())) {
                    

                    //connect the function args to the formal in nodes
                    defDepNode=getNode(DependenceNode::FORMALIN,interestingDefParent);
                    establishEdge(defDepNode,useDepNode,DATA);
            }

            else {
                //assume a general data edge
                defDepNode=getNode(interestingDefParent);
                establishEdge(defDepNode,useDepNode,DATA);
            }
          }
        }






        //NOW SWITCH from wanting Uses to Defs:

        //Additional Dependence Graph Initialization:
        //connect formal in defs to variable uses
        if (DUVariableAnalysisExt::isIDef(varRef)) {
          //            cout <<"\tIUSE"<<endl;
          //            cout <<"\tIDEF"<<endl;
          defPlaces=defuse->getDefFor(varRef,initName);
          for (unsigned int j=0;j<defPlaces.size();j++) {
            //                cout<<"\tdef "<<j<<": "<<defPlaces[j]->unparseToString()<<endl;
            //                cout<<"\tclass:"<<defPlaces[j]->class_name()<<endl;
            interestingDefParent=getNextParentInterstingNode(defPlaces[j]);
            if (isSgFunctionParameterList(interestingDefParent) || isSgFunctionParameterList(interestingDefParent) ||
                isSgFunctionParameterList(defPlaces[j]->get_parent()) && isSgFunctionDeclaration(defPlaces[j]->get_parent()->get_parent()))
            {
              defDepNode=getNode(DependenceNode::FORMALIN,defPlaces[j]);
            }
            else
            {
              defDepNode=getNode(interestingDefParent);
            }
            establishEdge(defDepNode,useDepNode,DATA);
          }
        }
        
      } //END OF MAIN VARIABLE LOOP


        //FINAL DEPENDENCE GRAPH STEPS:


       //uw-mist
       //begin by connecting all ActualOut nodes to the function args
       //start by getting all callsites representing a function
      for (int i=0;i<_interprocedural->callSiteCount();i++)
      {  
        //for this individual function, visit each arg
        for (int j=0;j<_interprocedural->getActualInCount(i);j++)
        {
            SgNode * actOut = _interprocedural->getActualIn(i,j);

        //if it is not a reference expression, search to find the lower reference expressions in the complex arg
        //uw-mist TODO: (If neccessary) for now, just skip
            if(!isSgVarRefExp(actOut))
                continue;

        //search the def/use map
            SgInitializedName *actOutInitName=isSgVarRefExp(actOut)->get_symbol()->get_declaration();
        DependenceNode * actOutDep = getNode(DependenceNode::ACTUALOUT,actOut);

        //connect to all potential definitions (not as exact as possible, but should work for first pass
        //uw-mist TODO: connect directly to all potential use paths instead
            std::vector< SgNode* > defPlaces=defuse->getDefFor(actOut,actOutInitName);
            for (unsigned int k=0;k<defPlaces.size();k++) {


                    establishEdge(actOutDep,getNode(getNextParentInterstingNode(defPlaces[k])),DATA);
            }


         }
      }

          
          
      // force a dependence from the ACTUALOUT to the Functionscall
      // iterate over all function-calls to connect the actual in/out edges
      Rose_STL_Container< SgNode * > functionCall=NodeQuery::querySubTree(_head,V_SgFunctionCallExp);
      for (Rose_STL_Container< SgNode * >::iterator call=functionCall.begin(); call != functionCall.end();call++) {
        // track down the parent imporant node to establish a data-dependency
        DependenceNode * callDepNode,*returnNode;
        // actualreturn
          returnNode=getNode(DependenceNode::ACTUALRETURN,*call);
          SgNode* callTmp=(*call)->get_parent();               // if the paren is the interesting node or a call break
          while(!IsImportantForSliceSgFilter(callTmp) && !isSgFunctionCallExp(callTmp)) {
            callTmp=callTmp->get_parent();
          }
          // returnvalue is used in a function call, connect
          if (isSgFunctionCallExp(callTmp)) {
            // get the actual in
            SgNode *paramFindTmp=*call;
            while(!isSgExprListExp(paramFindTmp->get_parent())) {
              paramFindTmp=paramFindTmp->get_parent();
            }                 // paramFindTmp is now the parameter of the function call 
            callDepNode=getNode(DependenceNode::ACTUALIN,paramFindTmp);
          } else {
            callDepNode=getNode(callTmp);
          }
          assert(returnNode!=NULL);
          assert(callDepNode!=NULL);    
          establishEdge(returnNode,callDepNode,DATA);
        }
        

        
        //Now connect return statements:

        //first, build up list of return statements
        Rose_STL_Container< SgNode * >returnStmts = NodeQuery::querySubTree(_head,V_SgReturnStmt);
        // if the last stmnt is not a return stmt, add that statement to the list, such that any modified formal_in parameters are linked correctly
        if (_head->get_body ()->get_statements ().size() &&
            !isSgReturnStmt(*(_head->get_body ()->get_statements ().rbegin()))) {
          
          // cout <<"last stmt is "<<(*(_head->get_body ()->get_statements ().rbegin()))->unparseToString()<<endl;
          // cout <<"last stmt is "<<_head->get_body ()->unparseToString()<<endl;
          //    cout <<"cfg says: "<<_head->get_declaration()->cfgForEnd ().getNode()->unparseToString()<<" is the end"<<endl;
          //   returnStmts.push_back(_head->get_declaration()->cfgForEnd ().getNode());
          // the last stmt might be a def, take the body as the sink for the CFG
          //    returnStmts.push_back(_head->get_body ());
          returnStmts.push_back(_head);
          //    returnStmts.push_back(*(_head->get_body ()->get_statements ().rbegin()));
        }
        
        // process return statements
        for (Rose_STL_Container< SgNode * >::iterator returnS=returnStmts.begin(); returnS != returnStmts.end();returnS++) {
          SgNode * stmt=*returnS;
          // cout <<"processing end-stantement: "<<stmt->unparseToString()<<endl;
          // if the return statement has actually some return values, connect those to the formal out
          if (isSgReturnStmt(stmt) /*&& isSgReturnStmt(stmt)->get_expression ()!=NULL*/) {
            // cout <<"is return,creating out edge"<<endl;
            // check if the sub-expression of the return contains any function calls for wich we have to create data-dependencys .. later

            Rose_STL_Container< SgNode * > returnRefs=NodeQuery::querySubTree(stmt,V_SgVarRefExp); 
                for (Rose_STL_Container<SgNode*>::iterator refIt=returnRefs.begin();refIt!=returnRefs.end();refIt++)
            {
                            establishEdge( getNode(getNextParentInterstingNode(*refIt)), getNode(DependenceNode::FORMALRETURN,_head->get_declaration()), DATA);
            // if this varaible is not from the initial name list
              }
    
            //SgVarRefExp * varRef=isSgVarRefExp(*i);

           }


        }


        // since not all functionparameters may be requried for this function, but the stack has to be valid, force a data depenancy form the fucntion enrty to the formal in
        std::set<SgInitializedName*> functionParameterSet(_head->get_declaration()->get_args().begin(),_head->get_declaration()->get_args().end());
        for (std::set<SgInitializedName*>::iterator param=functionParameterSet.begin();param!=functionParameterSet.end();param++) {
          //        cout <<"adding backedge for slicing purpose"<<endl;
          establishEdge(
                        getNode(DependenceNode::FORMALIN,*param),
                        getNode(DependenceNode::ENTRY,functionDef),
                        COMPLETENESS_HELPER);
        };
    }
コード例 #27
0
void generateStencilCode(StencilEvaluationTraversal & traversal, bool generateLowlevelCode)
   {
  // Read the stencil and generate the inner most loop AST for the stencil.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          string stencilName = stencilInitializedName->get_name();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

               lastStatement = destinationDataPointerVariableDeclaration;
             }

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

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

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

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

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

               ROSE_ASSERT(stencilSubTree != NULL);

               stencilSubTreeArray.push_back(stencilSubTree);
             }

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

       // Assemble the stencilSubTreeArray into a single expression.
          SgExprStatement* stencilStatement = assembleStencilSubTreeArray(stencil_lhs,stencilSubTreeArray,stencilDimension,destinationVariableSymbol);
          SageInterface::appendStatement(stencilStatement,innerLoopBody);
        }
   }
コード例 #28
0
ファイル: AstDOTGeneration.C プロジェクト: LindaLovelace/rose
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;
   }
コード例 #29
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.
コード例 #30
0
ファイル: stencilEvaluation.C プロジェクト: 8l/rose
StencilEvaluation_InheritedAttribute
StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundPairShiftDoubleConstructor = false;

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

     double stencilCoeficientValue = 0.0;

  // StencilOffsetFSM offset;
     StencilOffsetFSM* stencilOffsetFSM = NULL;

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

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

          string name = initializedName->get_name();

          SgInitializer* initializer = initializedName->get_initptr();

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

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

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

                                   ROSE_ASSERT(stencilOffsetFSM != NULL);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // Construct the return attribute from the modified input attribute.
     return StencilEvaluation_InheritedAttribute(inheritedAttribute);
   }