Esempio n. 1
0
File: f2cType.C Progetto: 8l/rose
SgType* Fortran_to_C::translateType(SgType* oldType)
{
  switch(oldType->variantT())
  {
    case V_SgTypeString:
      {
        SgExpression* stringLength = deepCopy(isSgTypeString(oldType)->get_lengthExpression());
        SgArrayType* newType =  buildArrayType(buildCharType(),NULL);
        newType->set_rank(1);
        newType->set_dim_info(buildExprListExp(stringLength));
        return newType;
      }
    case V_SgTypeFloat:
      {
        SgIntVal* typeKind = isSgIntVal(oldType->get_type_kind());
        if(typeKind == NULL)
        {
          // TODO: we just return original type. Might need to fix this in the future
          return oldType;
        }
        switch(typeKind->get_value())
        {
          case 4:
            return buildFloatType();
          case 8:
            return buildDoubleType();
          default:
            ROSE_ASSERT(false);
        }
      }
    case V_SgTypeInt:
      {
        SgIntVal* typeKind = isSgIntVal(oldType->get_type_kind());
        if(typeKind == NULL)
        {
          // TODO: we just return original type. Might need to fix this in the future
          return oldType;
        }
        switch(typeKind->get_value())
        {
          case 2:
            return buildShortType();
          case 4:
            return buildIntType();
          case 8:
            return buildLongType();
          default:
            ROSE_ASSERT(false);
        }
      }
    default:
      return oldType;
  }
}
Esempio n. 2
0
DeterminismState getExpectation(SgNode *ast, const char *varName)
{
  SgName name(varName);

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

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

    return QUESTIONABLE;
  }

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

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

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

  int value = ivSd->get_value();
  return value ? DETERMINISTIC : NONDETERMINISTIC;
}
Esempio n. 3
0
File: f2cArray.C Progetto: 8l/rose
SgExpression* Fortran_to_C::foldBinaryOp(SgExpression* inputExpression)
{
  SgExpression* foldedExp;
  if(isSgBinaryOp(inputExpression))
  {
    SgBinaryOp* binOp = isSgBinaryOp(inputExpression);
    SgIntVal* rhs = isSgIntVal(binOp->get_rhs_operand());
    if(!rhs) return inputExpression;
    SgIntVal* lhs = isSgIntVal(binOp->get_lhs_operand());
    if(!lhs) return inputExpression;
    int foldedVal;
    switch(binOp->variantT())
    {
      case V_SgAddOp:
        {
         foldedVal = lhs->get_value() + rhs->get_value();
         break;
        }
      case V_SgSubtractOp:
        {
         foldedVal = lhs->get_value() - rhs->get_value();
         break;
        }
      case V_SgMultiplyOp:
        {
         foldedVal = lhs->get_value() * rhs->get_value();
         break;
        }
      default:
       { 
         cerr<<"warning: calculuate - unhandled operator type:"<<binOp->class_name() << endl;
         return inputExpression;
       } 
    }
    foldedExp = buildIntVal(foldedVal);     
  }
  else
    return inputExpression;
  return foldedExp;
}
Esempio n. 4
0
DOTSynthesizedAttribute
AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l)
   {
     SubTreeSynthesizedAttributes::iterator iter;
     ROSE_ASSERT(node);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

               name = genericString->get_string();
             }

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

               name = genericString->get_string();

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

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

               name = genericString->get_string();
             }

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

               name = genericString->get_string();
             }

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

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

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

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

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

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

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

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

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

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

     nodelabel += additionalNodeInfo(node);

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

     string x;
     string y;
     x += additionalOptions;

     nodeoption += additionalOptions;

     DOTSynthesizedAttribute d(0);

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

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

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

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

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

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

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

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

          testnum++;
        }

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



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

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

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

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



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

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

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

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

               dotrep.writeToFileAsGraph(filename);
               break;
             }

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

               string original_filename = file->getFileName();

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

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

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

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

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

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

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

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

     d.node = node;
     return d;
   }
Esempio n. 5
0
SgExpression* MintArrayInterface::linearizeThisArrayRefs(SgNode* arrayNode, 
							 SgBasicBlock* kernel_body, 
							 SgScopeStatement* indexScope, 
							 SgInitializedName* arr_iname, 
							 bool useSameIndex) 
					
{
	//an instance of an array reference E[k][j+1][i]
	SgExpression* arrRefWithIndices = isSgExpression(arrayNode);

	SgExpression* arrayName;

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

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

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

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

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

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

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

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

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

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

}//end of indexList of one array
Esempio n. 6
0
StencilEvaluation_InheritedAttribute
StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundPairShiftDoubleConstructor = false;

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

     double stencilCoeficientValue = 0.0;

  // StencilOffsetFSM offset;
     StencilOffsetFSM* stencilOffsetFSM = NULL;

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

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

          string name = initializedName->get_name();

          SgInitializer* initializer = initializedName->get_initptr();

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

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

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

                                   ROSE_ASSERT(stencilOffsetFSM != NULL);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // Construct the return attribute from the modified input attribute.
     return StencilEvaluation_InheritedAttribute(inheritedAttribute);
   }
void
FortranProgramDeclarationsAndDefinitions::analyseParallelLoopArguments (
    FortranParallelLoop * parallelLoop, SgExprListExp * actualArguments,
    int numberOfOpArgs)
{
  using boost::iequals;
  using boost::lexical_cast;
  using std::find;
  using std::string;
  using std::vector;
  using std::map;

  Debug::getInstance ()->debugMessage (
      "Analysing OP_PAR_LOOP actual arguments", Debug::FUNCTION_LEVEL,
      __FILE__, __LINE__);

  unsigned int OP_DAT_ArgumentGroup = 1;
  
  /*
   * ======================================================
   * Loops over the arguments to populate the parallel loop object
   * Each object in the actualArguments array is a function call
   * We analyse the arguments of each call
   * \warning: the args start from position 2 (the first two args are
   * the user kernel reference and the iteration set
   * ======================================================
   */
  
  for ( int i = 2; i < numberOfOpArgs + 2; i++ )
  {
   /*
    * ======================================================
    * Distinguish between op_dat and global variable by
    * checking the function name
    * ======================================================
    */
    SgFunctionCallExp * functionExpression = isSgFunctionCallExp (
      actualArguments->get_expressions ()[i]);
    
    ROSE_ASSERT (functionExpression != NULL);
    
    string functionName = functionExpression ->getAssociatedFunctionSymbol ()->
      get_name ().getString ();
    
    SgExprListExp * opArgArguments = functionExpression ->get_args ();
    ROSE_ASSERT (opArgArguments );

    /*
     * ======================================================
     * Assume that this is not an op_mat, possibly amend later
     * ======================================================     
     */
    parallelLoop->setIsOpMatArg (OP_DAT_ArgumentGroup, false);
    
    if ( functionName == "op_arg_dat" )
    {     
     /*
      * ======================================================
      * Obtain the op_dat reference and its name
      * ======================================================
      */
     
      SgVarRefExp * opDatReference = NULL;

      opDatReference = getOpDatReferenceFromOpArg (opArgArguments);

      ROSE_ASSERT (opDatReference != NULL);

      string const opDatName = opDatReference->get_symbol ()->get_name ().getString ();

     /*
      * ======================================================
      * Obtain the map reference and name, and select access
      * type (direct or indirect)
      * ======================================================            
      */
      SgVarRefExp * opMapReference;

      opMapReference = getOpMapReferenceFromOpArg (opArgArguments);

      ROSE_ASSERT (opMapReference != NULL);

      string const mappingValue = opMapReference->get_symbol ()->get_name ().getString ();

      if (iequals (mappingValue, OP2::OP_ID))
      {
        /*
         * ======================================================
         * OP_ID signals identity mapping and therefore direct
         * access to the data
         * ======================================================
         */
        Debug::getInstance ()->debugMessage ("...DIRECT mapping descriptor",
            Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

        parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, DIRECT);
      }
      else
      {
        Debug::getInstance ()->debugMessage ("...INDIRECT mapping descriptor",
            Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

        parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, INDIRECT);
      }

      setOpDatProperties (parallelLoop, opDatName, OP_DAT_ArgumentGroup);

      setParallelLoopAccessDescriptor (parallelLoop, opArgArguments, OP_DAT_ArgumentGroup, DAT_ACC_POSITION);
    }
    else if ( functionName == "op_arg_gbl" )
    {

      Debug::getInstance ()->debugMessage ("...GLOBAL mapping descriptor",
        Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

     /*
      * ======================================================
      * Get the OP_GBL variable reference and name
      * ======================================================
      */
      SgVarRefExp * opDatReference;

      if (isSgDotExp (opArgArguments->get_expressions ()[DAT_POSITION])
          != NULL)
      {
        opDatReference
            = isSgVarRefExp (
                isSgDotExp (
                    opArgArguments->get_expressions ()[DAT_POSITION])->get_rhs_operand ());
      }
      else
      {
        opDatReference = isSgVarRefExp (
            opArgArguments->get_expressions ()[DAT_POSITION]);
      }

      string const globalName =
          opDatReference->get_symbol ()->get_name ().getString ();
      

     /*
      * ======================================================
      * Get the OP_GBL dimension: check the number of args
      * to the op_arg_gbl function (3 = array, 2 = scalar)
      * ======================================================
      */
      if ( opArgArguments->get_expressions ().size () == GBL_SCALAR_ARG_NUM )
      {

        Debug::getInstance ()->debugMessage ("'" + globalName + "' is a scalar",
            Debug::FUNCTION_LEVEL, __FILE__, __LINE__);

       /*
        * ======================================================
        * Since this is a scalar, set the dimension to 1
        * ======================================================
        */

        parallelLoop->setOpDatDimension (OP_DAT_ArgumentGroup, 1);
      }
      else
      {
        SgIntVal * intValExp = isSgIntVal (opArgArguments->get_expressions ()[GBL_DIM_POSITION]);
        ROSE_ASSERT (intValExp != NULL);
        
        int globalDimension = intValExp->get_value ();
        
        parallelLoop->setOpDatDimension (OP_DAT_ArgumentGroup, globalDimension);
        
        Debug::getInstance ()->debugMessage ("'" + globalName
          + "' is NOT a scalar, but has dimension " + lexical_cast<string> (globalDimension),
          Debug::FUNCTION_LEVEL, __FILE__, __LINE__);
      }

     /*
      * ======================================================
      * Set the other fields
      * ======================================================
      */
      parallelLoop->setOpDatType (OP_DAT_ArgumentGroup,
        (opArgArguments->get_expressions ()[DAT_POSITION])->get_type ());
     
      parallelLoop->setUniqueOpDat (globalName);

      parallelLoop->setOpDatVariableName (OP_DAT_ArgumentGroup, globalName);

      parallelLoop->setDuplicateOpDat (OP_DAT_ArgumentGroup, false);

      parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, GLOBAL);

      if ( opArgArguments->get_expressions ().size () == GBL_SCALAR_ARG_NUM )       
        setParallelLoopAccessDescriptor (parallelLoop, opArgArguments,
          OP_DAT_ArgumentGroup, GBL_SCALAR_ACC_POSITION);
      else        
        setParallelLoopAccessDescriptor (parallelLoop, opArgArguments,
          OP_DAT_ArgumentGroup, GBL_ARRAY_ACC_POSITION);
    }
    else if ( functionName == "op_arg_dat_generic" )
    {
      Debug::getInstance ()->debugMessage ("Found generic op_dat",
        Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

      /*
       * ======================================================
       * Obtain the op_dat reference and its name
       * ======================================================
       */
      SgVarRefExp * opDatReference = NULL;

      opDatReference = getOpDatReferenceFromOpArg (opArgArguments);

      ROSE_ASSERT (opDatReference != NULL);

      string const opDatName = opDatReference->get_symbol ()->get_name ().getString ();      

      /*
       * ======================================================
       * Obtain the map reference and name, and select access
       * type (direct or indirect)
       * ======================================================
       */
      SgVarRefExp * opMapReference;

      opMapReference = getOpMapReferenceFromOpArg (opArgArguments);

      ROSE_ASSERT (opMapReference != NULL);

      string const mappingValue = opMapReference->get_symbol ()->get_name ().getString ();

      if (iequals (mappingValue, OP2::OP_ID))
        {
          /*
           * ======================================================
           * OP_ID signals identity mapping and therefore direct
           * access to the data
           * ======================================================
           */
          Debug::getInstance ()->debugMessage ("...DIRECT mapping descriptor",
            Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

          parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, DIRECT);
        }
      else
        {
          Debug::getInstance ()->debugMessage ("...INDIRECT mapping descriptor",
            Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

          parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, INDIRECT);
        }

      /*
       * ======================================================
       * In case of generic loop, I have to read also the
       * dimension and type to be able to set the op_dat info
       * in the parallel loop class
       * ======================================================
       */
      SgIntVal * opDatDimension = isSgIntVal (
        opArgArguments->get_expressions ()[GENERIC_DIM_POSITION]);

        
      SgStringVal * opDataBaseTypeString = isSgStringVal (
        opArgArguments->get_expressions ()[GENERIC_TYPE_POSITION]);

      ROSE_ASSERT (opDataBaseTypeString != NULL);
        
      SgType * opDataBaseType = getTypeFromString (opDataBaseTypeString->get_value (),
        opDatName);

      ROSE_ASSERT (opDataBaseType != NULL);

      setOpDatPropertiesGeneric (parallelLoop, opDatName, opDatDimension->get_value (),
         opDataBaseType, OP_DAT_ArgumentGroup);

      Debug::getInstance ()->debugMessage ("Getting access",
        Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);

      setParallelLoopAccessDescriptor (parallelLoop, opArgArguments,
        OP_DAT_ArgumentGroup, GENERIC_ACC_POSITION);
    } 
    else if ( functionName == "op_arg_mat" )
    {
      Debug::getInstance ()->debugMessage ("Unsupported argument type",
        Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);
    }
    else
    {
      Debug::getInstance ()->debugMessage ("Argument type not recognised",
        Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);      
    }

   /*
    * ======================================================
    * This identifies the argument position in the data
    * structures, while the iteration variable 'i' identifies
    * the corresponding op_arg position in the op_par_loop
    * arguments (i == OP_DAT_ArgumentGroup + 2)
    * ======================================================
    */

    OP_DAT_ArgumentGroup++;
  }
  
  parallelLoop->setNumberOfOpDatArgumentGroups (numberOfOpArgs);
  parallelLoop->setNumberOfOpMatArgumentGroups (0);
  
  if ( parallelLoop->isDirectLoop () )
    Debug::getInstance ()->debugMessage ("This is a DIRECT parallel loop",
      Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);
  else
    Debug::getInstance ()->debugMessage ("This is an INDIRECT parallel loop",
      Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__);  
}
Esempio n. 8
0
void
UDrawGraph::visit (SgNode * node)
{
  using boost::lexical_cast;
  using std::string;

  file << newVertex (counter) << beginAttributes;

  switch (node->variantT ())
  {
    case V_SgInitializedName:
    {
      SgInitializedName * castedNode = isSgInitializedName (node);
      file << setName (castedNode->get_name ().getString ());
      break;
    }

    case V_SgVarRefExp:
    {
      SgVarRefExp * castedNode = isSgVarRefExp (node);
      file << setName (castedNode->get_symbol ()->get_name ().getString ());
      file << setColor (RED);
      break;
    }

    case V_SgVariableDeclaration:
    {
      file << setName (node->class_name ());
      file << setShape (RHOMBUS);
      break;
    }

    case V_SgIntVal:
    {
      SgIntVal * castedNode = isSgIntVal (node);
      file << setName (lexical_cast <string> (castedNode->get_value ()));
      file << setColor (GREEN);
      break;
    }

    case V_SgFloatVal:
    {
      SgFloatVal * castedNode = isSgFloatVal (node);
      file << setName (lexical_cast <string> (castedNode->get_value ()));
      file << setColor (GREEN);
      break;
    }

    case V_SgAddOp:
    {
      file << setName ("+");
      file << setColor (YELLOW);
      break;
    }

    case V_SgMinusOp:
    case V_SgSubtractOp:
    {
      file << setName ("-");
      file << setColor (YELLOW);
      break;
    }

    case V_SgMultiplyOp:
    {
      file << setName ("*");
      file << setColor (YELLOW);
      break;
    }

    case V_SgDivideOp:
    {
      file << setName ("/");
      file << setColor (YELLOW);
      break;
    }

    case V_SgAssignOp:
    {
      file << setName ("=");
      file << setColor (YELLOW);
      break;
    }

    case V_SgLessThanOp:
    {
      file << setName ("<");
      file << setColor (YELLOW);
      break;
    }

    case V_SgLessOrEqualOp:
    {
      file << setName ("<=");
      file << setColor (YELLOW);
      break;
    }

    case V_SgGreaterThanOp:
    {
      file << setName (">");
      file << setColor (YELLOW);
      break;
    }

    case V_SgGreaterOrEqualOp:
    {
      file << setName (">=");
      file << setColor (YELLOW);
      break;
    }

    case V_SgAddressOfOp:
    {
      file << setName ("&");
      file << setColor (YELLOW);
      break;
    }

    default:
    {
      file << setName (node->class_name ());
      break;
    }
  }

  file << endAttibutes << beginAttributes;

  if (counter != rootID)
  {
    SgNode * parent = node->get_parent ();

    unsigned int const parentID = nodes[parent];

    file << newEdge << beginAttributes << setDirectionalLessEdge
        << endAttibutes << edgeLink (parentID) << endEdge;
  }

  file << endVertex;

  nodes[node] = counter;

  counter++;
}
Esempio n. 9
0
POETCode* POETAstInterface::Ast2POET(const Ast& n)
{
  static SgTemplateInstantiationFunctionDecl* tmp=0;
  SgNode* input = (SgNode*) n;
  if (input == 0) return EMPTY;
  POETCode* res = POETAstInterface::find_Ast2POET(input);
  if (res != 0) return res;

  {
  SgProject* sageProject=isSgProject(input); 
  if (sageProject != 0) {
    int filenum = sageProject->numberOfFiles(); 
    for (int i = 0; i < filenum; ++i) { 
      SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); 
      SgGlobal *root = sageFile->get_globalScope(); 
      SgDeclarationStatementPtrList declList = root->get_declarations ();
      POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp);
      curfile = new POETCode_ext(sageFile, curfile);
      POETAstInterface::set_Ast2POET(sageFile, curfile);
      res=LIST(curfile, res);
    }
    POETAstInterface::set_Ast2POET(sageProject,res); 
    return res;
  } }
  { 
  SgBasicBlock* block = isSgBasicBlock(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_statements(), res, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
  { 
  SgExprListExp* block = isSgExprListExp(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_expressions(), 0, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
 {
  SgForStatement *f = isSgForStatement(input);
  if (f != 0) {
      POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp);
      POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment())));
      res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body())));  
      POETAstInterface::set_Ast2POET(input, res); 
      return res;
  }
  }
  {
    SgVarRefExp * v = isSgVarRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgIntVal * v = isSgIntVal(input);
    if (v != 0) {
       res = ICONST(v->get_value());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
   SgInitializedName* var = isSgInitializedName(input);
   if (var != 0) {
     POETCode* name = STRING(var->get_name().str()); 
     POETCode* init = Ast2POET(var->get_initializer());
     res = new POETCode_ext(var, PAIR(name,init));
     POETAstInterface::set_Ast2POET(input, res); 
     return res;
   }
  }

/*
  {
  std::string fname;
  AstInterface::AstList params;
  AstNodeType returnType;
  AstNodePtr body;
  if (AstInterface :: IsFunctionDefinition( input, &fname, &params, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) {
if (body != AST_NULL)
 std::cerr << "body not empty:" << fname << "\n";
      POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), 
                 STRING(AstInterface::GetTypeName(returnType)), 
                 Ast2POET(body.get_ptr()));
      res = new POETCode_ext(input, c);
      POETAstInterface::set_Ast2POET(input,res);
      return res;
  } }   
*/

  AstInterface::AstList c = AstInterface::GetChildrenList(input);
  switch (input->variantT()) {
    case V_SgCastExp:
    case V_SgAssignInitializer:
      res = Ast2POET(c[0]); 
      POETAstInterface::set_Ast2POET(input, res); return res; 
    case V_SgDotExp:
     {
      POETCode* v1 = Ast2POET(c[1]);
      if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") 
           return Ast2POET(c[0]);
      res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res;
     }
    case V_SgLessThanOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgSubtractOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAddOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgMultiplyOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgDivideOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAssignOp:
      res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgFunctionCallExp:
      res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
  } 
  POETCode * c2 = 0; 
  if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input);
   switch (c.size()) {
   case 0: break;
   case 1: c2 = Ast2POET(c[0]); break;
   case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break;
   case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break;
   case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break;
   default: 
     //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n";
     c2 = EMPTY;
   }
  if (tmp == input) tmp = 0;
  res = new POETCode_ext(input, c2); 
  POETAstInterface::set_Ast2POET(input,res);
  return res;
}
Esempio n. 10
0
//Generates SSA form numbers for the variables contained in *ex and attaches them as AstValueAttributes to the related SgNodes
//Assumption: *ex is located in in the inTrueBranch branch of the if node labeled *condLabel (These two arguments are required to generate the SSA form numbers)  
void SSAGenerator::processSgExpression(SgExpression* ex, Label* condLabel, bool inTrueBranch)
{
	SgIntVal* intVal = dynamic_cast<SgIntVal*>(ex);
	SgMinusOp* minusOp = dynamic_cast<SgMinusOp*>(ex);
	SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(ex);
	SgBinaryOp* binOp = dynamic_cast<SgBinaryOp*>(ex);
	SgFunctionCallExp* funcCall = dynamic_cast<SgFunctionCallExp*>(ex);
	
	if(intVal) //Int value
	{
		//Nothing needs to be done; Case is listed here to have a collection of all expected cases
	}
	else if(minusOp)
	{
		processSgExpression(minusOp->get_operand(), condLabel, inTrueBranch);
	}
	else if(varRef) //Reference to variable that is NOT on the left hand side of an assignment
	{
		//Assign number to variable
		string varName = varRef->get_symbol()->get_name().getString();
		int varNumber = currentNumber(varName, condLabel, inTrueBranch);  
		logger[Sawyer::Message::DEBUG] << "Current number for variable " << varName << ": " << varNumber << endl;
		AstValueAttribute<int>* varNumberAtt = new AstValueAttribute<int>(varNumber);
		varRef->setAttribute("SSA_NUMBER", varNumberAtt);	
	}
	else if(binOp) //Binary operation
	{	
		SgExpression* lhs = binOp->get_lhs_operand();
		SgExpression* rhs = binOp->get_rhs_operand();

		//Process right hand side first
		processSgExpression(rhs, condLabel, inTrueBranch);
		
		//Process left hand side second
		SgAssignOp* assignOp = dynamic_cast<SgAssignOp*>(binOp);	
		if(assignOp) //Assignment to a variable
		{
			//Assign new number to that variable  
			SgVarRefExp* lhsVarRef = dynamic_cast<SgVarRefExp*>(lhs);
			assert(lhsVarRef != NULL);
			processAssignmentTo(lhsVarRef, condLabel, inTrueBranch);
		}
		else //Arithmetic operation or boolean operation (or something unexpected)
		{
			processSgExpression(lhs, condLabel, inTrueBranch);	
		}	
		
	}
	else if(funcCall) //Call to a function
			  //RERS specific; Only two function call types are supported: 
			  //(1) scanf("%d",&...); 
			  //(2) __VERIFIER_error(RERSVerifierErrorNumber); The artificial bool variable RERSErrorOccured has to be updated 
	{
		string funcName = funcCall->getAssociatedFunctionSymbol()->get_name().getString();
		logger[Sawyer::Message::DEBUG] << "Call to function: " << funcName << endl;
		if(funcName == "scanf") //(1)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			SgExpressionPtrList::iterator i = funcArgsPtrs.begin();
			while(i != funcArgsPtrs.end())
			{
				SgAddressOfOp* addrOp = dynamic_cast<SgAddressOfOp*>(*i);
				if(addrOp) 
				{
					SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(addrOp->get_operand());
					if(varRef)
					{
						processAssignmentTo(varRef, condLabel, inTrueBranch);
					}
					else logger[Sawyer::Message::DEBUG] << "FOUND NO REFERENCE TO VARIABLE" << endl;
				}
				i++;	
			}	
		}
		else if(funcName == "__VERIFIER_error" && prepareReachabilityAnalysisZ3)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			assert(funcArgsPtrs.size() == 1);
			SgExpression* argument = *funcArgsPtrs.begin();
			SgIntVal* intArgument = dynamic_cast<SgIntVal*>(argument);
			assert(intArgument != NULL);
			if(intArgument->get_value() == RERSVerifierErrorNumber) //(2) 
			{
				int RERSErrorOccuredNumber = nextNumber("RERSErrorOccured", condLabel, inTrueBranch); 
				logger[Sawyer::Message::DEBUG] << "Next number for variable RERSErrorOccured: " << RERSErrorOccuredNumber << endl;
				AstValueAttribute<int>* numberAtt = new AstValueAttribute<int>(RERSErrorOccuredNumber);
				funcCall->setAttribute("SSA_NUMBER", numberAtt); 
			}
		}
		else logger[Sawyer::Message::DEBUG] << "Ignoring function call" << endl;
	}
	else //Unexpected
	{
		logger[Sawyer::Message::ERROR] << "ERROR: SgExpression could not be handled: " << ex->class_name() << endl;
		assert(false);
	}
}
Esempio n. 11
0
void DataFlow<
  DLX::KLT_Annotation<DLX::OpenACC::language_t>,
  Language::OpenCL,
  Runtime::OpenACC
>::markSplittedData(
  const context_t & context
) const {
  std::map< ::KLT::Data<Annotation> *, std::vector<splitted_access_desc_t> > accesses_map;
  std::map< ::KLT::Data<Annotation> *, std::vector<splitted_access_desc_t> >::iterator it_accesses;

  std::map< ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::node_t *, accesses_list_t>::const_iterator it;
  for (it = context.accesses_map.begin(); it != context.accesses_map.end(); it++) {
    ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::node_t * node = it->first;
    ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::node_t * parent = node->parent;

    ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::loop_t * splitted_loop = NULL;
    ::DLX::Directives::clause_t< ::DLX::OpenACC::language_t, ::DLX::OpenACC::language_t::e_acc_clause_split> * split_clause = NULL;

    // search for a splitted loop in the parents
    while (parent != NULL) {
      ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::loop_t * loop = dynamic_cast< ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::loop_t *>(parent);
      if (loop != NULL && loop->isSplitted()) {
        assert(splitted_loop == NULL); // cannot have nested splitted loops
        splitted_loop = loop;

        std::vector<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::const_iterator it;
        for (it = loop->annotations.begin(); it != loop->annotations.end(); it++) {
          if (it->clause->kind == DLX::OpenACC::language_t::e_acc_clause_split) {
            assert(split_clause == NULL); // only one split clause per loop
            split_clause = (::DLX::Directives::clause_t< ::DLX::OpenACC::language_t, ::DLX::OpenACC::language_t::e_acc_clause_split> *)it->clause;
          }
        }
        assert(split_clause != NULL);
      }
      parent = parent->parent;
    }
    assert(splitted_loop == NULL || split_clause != NULL); // (loop != NULL) => (split_clause != NULL)

    std::vector<data_access_t>::const_iterator it_data_access;
    for (it_data_access = it->second.reads.begin(); it_data_access != it->second.reads.end(); it_data_access++) {
      it_accesses = accesses_map.find(it_data_access->data);
      if (it_accesses == accesses_map.end())
        it_accesses = accesses_map.insert(std::pair< ::KLT::Data<Annotation> *, std::vector<splitted_access_desc_t> >(it_data_access->data, std::vector<splitted_access_desc_t>())).first;
      assert(it_accesses != accesses_map.end());
      it_accesses->second.push_back(splitted_access_desc_t(splitted_access_desc_t::read, splitted_loop, split_clause, &(it_data_access->subscripts)));
    }
    for (it_data_access = it->second.writes.begin(); it_data_access != it->second.writes.end(); it_data_access++) {
      it_accesses = accesses_map.find(it_data_access->data);
      if (it_accesses == accesses_map.end())
        it_accesses = accesses_map.insert(std::pair< ::KLT::Data<Annotation> *, std::vector<splitted_access_desc_t> >(it_data_access->data, std::vector<splitted_access_desc_t>())).first;
      assert(it_accesses != accesses_map.end());
      it_accesses->second.push_back(splitted_access_desc_t(splitted_access_desc_t::write, splitted_loop, split_clause, &(it_data_access->subscripts)));
    }
  }

  for (it_accesses = accesses_map.begin(); it_accesses != accesses_map.end(); it_accesses++) {
    ::KLT::Data<Annotation> * data = it_accesses->first;
    assert(it_accesses->second.size() > 0);

    if (it_accesses->second.size() > 1) {
      std::vector<splitted_access_desc_t>::iterator it_splitted_access = it_accesses->second.begin();
      ::KLT::LoopTrees<DLX::KLT_Annotation<DLX::OpenACC::language_t> >::loop_t * splitted_loop = it_splitted_access->splitted_loop;
      for (; it_splitted_access != it_accesses->second.end(); it_splitted_access++)
        assert(splitted_loop == it_splitted_access->splitted_loop);
    }

    if (it_accesses->second[0].splitted_loop == NULL) continue;

    assert(it_accesses->second[0].split_clause != NULL);
    assert(it_accesses->second[0].subscripts != NULL);
    assert(it_accesses->second[0].subscripts->size() > 0);

    SgVarRefExp * var_ref = isSgVarRefExp(it_accesses->second[0].subscripts->at(0));
    assert(var_ref != NULL);
    if (var_ref->get_symbol() != it_accesses->second[0].splitted_loop->iterator) {
      std::vector<splitted_access_desc_t>::iterator it_splitted_access;
      for (it_splitted_access = it_accesses->second.begin(); it_splitted_access != it_accesses->second.end(); it_splitted_access++)
        assert(it_splitted_access->rw == splitted_access_desc_t::read);
      continue;
    }

    ::KLT::Data<Annotation>::data_distribution_t * data_distribution = new ::KLT::Data<Annotation>::data_distribution_t();
      data_distribution->distributed_dimension = 0;
      switch (it_accesses->second[0].split_clause->parameters.kind) {
        case ::DLX::Directives::generic_clause_t< ::DLX::OpenACC::language_t>::parameters_t< ::DLX::OpenACC::language_t::e_acc_clause_split>::e_acc_split_contiguous:
        {
          data_distribution->kind = ::KLT::Data<Annotation>::data_distribution_t::e_split_contiguous;
          std::vector<SgExpression *>::const_iterator it_portion;
          for (it_portion = it_accesses->second[0].split_clause->parameters.portions.begin(); it_portion != it_accesses->second[0].split_clause->parameters.portions.end(); it_portion++) {
            SgIntVal * portion = isSgIntVal(*it_portion);
            if (portion == NULL) {
              std::cerr << "(*it_portion)->class_name() = " << (*it_portion)->class_name() << std::endl;
              assert(false);
            }
            data_distribution->portions.push_back(portion->get_value());
          }
          break;
        }
        case ::DLX::Directives::generic_clause_t< ::DLX::OpenACC::language_t>::parameters_t< ::DLX::OpenACC::language_t::e_acc_clause_split>::e_acc_split_chunk:
        {
            break;
        }
        default:
          assert(false);
      }
    data->setDistribution(data_distribution);
  }
}
Esempio n. 12
0
ExprSynAttr *examineExpr(SgExpression *expr, ostream &out) {
    stringstream ss1;
    stringstream ss2;
    stringstream ss3;
    SgExpression *e1;
    SgExpression *e2;
    SgBinaryOp *binop;
    SgUnaryOp *unaryop;
    SgType *type;
    ExprSynAttr *ret;
    ExprSynAttr *attr1, *attr2;
    string tmp_name;
    string tmp_type;

    string tmp2_name;
    string tmp2_type;

    if (expr == NULL)
        return NULL;

    ret = new ExprSynAttr();
    attr1 = NULL;
    attr2 = NULL;
    switch(expr->variantT()) {
        /* Begin UnaryOp */
        case V_SgMinusOp:
            out << "(-";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= -" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        case V_SgUnaryAddOp:
            out << "(+";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= +" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        case V_SgNotOp:
            out << "(!";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= (int)!" << attr1->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgPointerDerefExp:
            out << "(*";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->basetype(attr1);
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= *" << attr1->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgAddressOfOp:
             out << "(&";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";
            ret->type = attr1->type + "*";
            /* FIXME ret->sgtype */
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= &" << attr1->result_var;
            ret->code << ";" << endl;
             break;
        case V_SgMinusMinusOp:
            unaryop = isSgUnaryOp(expr);
            if (unaryop->get_mode()) {
                out << "(";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << "--)";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->new_tmp_name();
                ret->add_new_tmp_decl(ret->type, ret->result_var);
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();
                ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl;

                ret->code << attr1->result_var << "=" << attr1->result_var << "-1;" << endl;
            } else {
                out << "(--";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << ")";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->result_var = attr1->result_var;
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();

                ret->code << ret->result_var << "=" << attr1->result_var << "-1;" << endl;
            }
            break;
        case V_SgPlusPlusOp:
            unaryop = isSgUnaryOp(expr);
            if (unaryop->get_mode()) {
                out << "(";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << "++)";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->new_tmp_name();
                ret->add_new_tmp_decl(ret->type, ret->result_var);
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();
                ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl;

                ret->code << attr1->result_var << "=" << attr1->result_var << "+1;" << endl;

            } else {
                out << "(++";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << ")";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->result_var = attr1->result_var;
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();

                ret->code << ret->result_var << "=" << attr1->result_var << "+1;" << endl;

            }
            break;
        case V_SgBitComplementOp:
            out << "(~";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= ~" << attr1->result_var;
            ret->code << ";" << endl;

             break;
        case V_SgCastExp:
        {
            out << "(";
            SgCastExp *castexp = isSgCastExp(expr);
            e1 = castexp->get_operand();
            type = castexp->get_type();
            examineType(type, out);
            out << ")";
            attr1 = examineExpr(e1, out);

            stringstream casts;
            examineType(type, casts);
            ret->type = casts.str();
            ret->sgtype = type;
            ret->new_tmp_name(tmp_name);
            ret->union_tmp_decls(attr1, NULL);
            ret->add_new_tmp_decl(ret->type, tmp_name);

            ret->result_var = tmp_name;
            ret->code << attr1->code.str() << tmp_name;
            ret->code << "=(" << ret->type << ")" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        }
        /* End UnaryOp */
        /* Begin BinaryOp */
        case V_SgEqualityOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "==";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;

            binop_noassign(ret, attr1, attr2, "==");
            break;
        case V_SgLessThanOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "<");
            break;
        case V_SgGreaterThanOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, ">");
            break;
        case V_SgNotEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "!=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "!=");
            break;
        case V_SgLessOrEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "<=");
            break;
        case V_SgGreaterOrEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, ">=");
            break;
        case V_SgAddOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "+";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "+");
            break;
        case V_SgSubtractOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "-";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "-");
            break;
        case V_SgMultiplyOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "*";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "*");
            break;
        case V_SgDivideOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "/";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "/");
            break;
        case V_SgIntegerDivideOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "/";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "/");
            break;
        case V_SgModOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "%";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "%");
            break;
        case V_SgAndOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "&&";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            ret->type = "int";
            binop_noassign(ret, attr1, attr2, "&&");
            break;
        case V_SgOrOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "||";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            ret->type = "int";
            binop_noassign(ret, attr1, attr2, "||");
            break;
        case V_SgBitXorOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "^";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "^");
            break;
        case V_SgBitAndOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "&";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "&");
            break;
        case V_SgBitOrOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "|";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "|");
            break;
        case V_SgCommaOpExp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ",";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, ",");
            break;
        case V_SgLshiftOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<<";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "<<");
            break;
        case V_SgRshiftOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">>";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, ">>");
            break;
        case V_SgAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);

            ret->union_tmp_decls(attr1, attr2);
            ret->result_var = attr1->result_var;
            ret->code << attr2->code.str() << attr1->code.str() << ret->result_var;
            ret->code << "=" << attr2->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgPlusAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "+=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "+");
            break;
        case V_SgMinusAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "-=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "-");
            break;
        case V_SgAndAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "&=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "&");
            break;
        case V_SgIorAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "|=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "|");
            break;
        case V_SgMultAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "*=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "*");
            break;
        case V_SgDivAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "/=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "/");
            break;
        case V_SgModAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "%=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "%");
            break;
        case V_SgXorAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "^=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "^");
            break;
        case V_SgLshiftAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "<<=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "<<");
            break;
        case V_SgRshiftAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << ">>=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, ">>");
            break;

        case V_SgExponentiationOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "ExpUnknown";
            attr2 = examineExpr(e2, out);
            out << ")";
            break;
        case V_SgConcatenationOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "CatUnknown";
            attr2 = examineExpr(e2, out);
            out << ")";
            break;
        case V_SgPntrArrRefExp:
        {
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "[";
            attr2 = examineExpr(e2, out);
            out << "]";

            ret->basetype(attr1);
            ret->union_tmp_decls(attr1, attr2);

            ret->result_var = attr1->result_var + "[" + attr2->result_var + "]";

            ret->code << attr1->code.str() << attr2->code.str();
            break;
        }

        /* End BinaryOp */

        /* Begin variables */
        case V_SgVarRefExp:
        {
            stringstream casts;
            SgVarRefExp *varref = isSgVarRefExp(expr);
            if (NULL == varref)
                return NULL;
            SgVariableSymbol *svsym = varref->get_symbol();
            if (NULL == svsym)
                return NULL;
            out << svsym->get_name().getString();
            ret->result_var = svsym->get_name().getString();
            examineType(svsym->get_type(), casts);
            ret->type = casts.str();
            ret->sgtype = svsym->get_type();
            /*
            ret->new_tmp_name();
            examineType(svsym->get_type(), casts);
            ret->type = casts.str();
            ret->sgtype = svsym->get_type();
            ret->add_new_tmp_decl(ret->type, ret->result_var);

            ret->code << ret->result_var << " = " << svsym->get_name().getString();
            ret->code << ";" << endl;
            */
            break;
        }
        case V_SgLabelRefExp:
            SgLabelRefExp *labref = isSgLabelRefExp(expr);
            out << labref->get_name().getString();
            break;

        /* Begin Constants */
        case V_SgIntVal:
        {
            stringstream casts;

            SgIntVal *intval = isSgIntVal(expr);
            out << intval->get_value();
            casts << intval->get_value();

            ret->result_var = casts.str();
            ret->type = "int";
            ret->sgtype = intval->get_type();
            
            break;
        }
        case V_SgLongIntVal:
        {
            stringstream casts;

            SgLongIntVal *longval = isSgLongIntVal(expr);
            out << longval->get_value() << "L";
            casts << longval->get_value() << "L";

            ret->result_var = casts.str();
            ret->type = "long";
            ret->sgtype = longval->get_type();
            
            break;
        }
 
        case V_SgUnsignedIntVal:
        {
            stringstream casts;

            SgUnsignedIntVal *uintval = isSgUnsignedIntVal(expr);
            out << uintval->get_value() << "U";
            casts << uintval->get_value() << "U";
 
            ret->result_var = casts.str();
            ret->type = "unsigned";
            ret->sgtype = uintval->get_type();
            
            break;
        }
        case V_SgUnsignedLongVal:
        {
            stringstream casts;

            SgUnsignedLongVal *ulongval = isSgUnsignedLongVal(expr);
            out << ulongval->get_value() << "UL";
            casts << ulongval->get_value() << "UL";

            ret->result_var = casts.str();
            ret->type = "unsigned long";
            ret->sgtype = ulongval->get_type();
            
            break;
        }
        case V_SgDoubleVal:
        {
            stringstream casts;

            SgDoubleVal *doubleval = isSgDoubleVal(expr);
            out << doubleval->get_value();
            casts << doubleval->get_value();

            ret->result_var = casts.str();
            ret->type = "double";
            ret->sgtype = doubleval->get_type();
            
            break;
        }
        case V_SgFloatVal:
        {
            stringstream casts;

            SgFloatVal *floatval = isSgFloatVal(expr);
            out << floatval->get_value();
            casts << floatval->get_value();

            ret->result_var = casts.str();
            ret->type = "float";
            ret->sgtype = floatval->get_type();
            
            break;
        }
        default:
            out << "/* UNKNOWN EXPR[" << expr->class_name() << "](" << expr->variantT() << ") " << expr->unparseToString() << " */" << endl;
            cerr << "UNKNOWN EXPR[" << expr->class_name() << "] " << expr->unparseToString() << endl;
            break;
    }

    if (NULL != attr1)
        delete attr1;
    if (NULL != attr2)
        delete attr2;
    return ret;
}
Esempio n. 13
0
bool StencilAnalysis::isShareableReference(const std::vector<SgExpression*> subscripts, 
					   const bool corner_yz //=FALSE
					   ) 
{
  //March 2 2011, made changes in the function, we have more robust sharing conditions
  //checks if an array reference can be replaced with shared memory reference
  //by looking at the index expressions 
  //assumes the variable is already checked for candidacy

  //check if subsrcipts are _gidx, _gidy or _gidz
  std::vector<SgExpression*>::const_iterator it;
  
  size_t count = 0;
  int indexNo = 0;

  for(it= subscripts.begin(); it != subscripts.end(); it++)
    {      
      indexNo++;
      SgExpression* index = isSgExpression(*it);

      Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(index, V_SgVarRefExp);
      
      if(varList.size() != 1) //there should be only 1 variable and that should be gidx,y,z
	return false;
      //check if that varRef is x, y, z

      SgVarRefExp* varExp = isSgVarRefExp(*(varList.begin()));
      ROSE_ASSERT(varExp);

      string index_str = varExp->unparseToString();      
      
      if(indexNo == 1 && index_str != GIDX )
	return false;
      if(indexNo == 2 && index_str != GIDY )
	return false;
      if(indexNo == 3 && index_str != GIDZ )
	return false;

      Rose_STL_Container<SgNode*> constList = NodeQuery::querySubTree(index, V_SgIntVal);

      if(constList.size() > 1 )
	return false;

      if(constList.size() == 1)
	{

	  SgIntVal* constVal = isSgIntVal(*(constList.begin()));
	  ROSE_ASSERT(constVal);

	  if(constVal->get_value() > MAX_ORDER)
	    return false;

	  //we keep maximum 3 planes in shared memory
	  if(constVal->get_value() > 1 && indexNo == 3)
	    return false;

	  Rose_STL_Container<SgNode*> binOpList = NodeQuery::querySubTree(index, V_SgBinaryOp);
      
	  if(binOpList.size() != 1)
	    return false;

	  SgBinaryOp* binOp = isSgBinaryOp(*(binOpList.begin()));

	  //we want either one add or subtract operation in the index expression
	  //no complex indexing is supported for now. 
	  //A[i+2][i-4] is valid but A[i*2] is not valid
	  
	  if( !isSgAddOp(binOp) &&  !isSgSubtractOp(binOp))
	    return false;

	  if(indexNo == 3 && !corner_yz) 
	    { //corner of yz is only shareable when corner_yz is true
	      return false;
	    }

	}
      count++;
    }

  return (count == subscripts.size()) ? true : false ;

}
Esempio n. 14
0
int StencilAnalysis::getSharingCategory(const std::vector<SgExpression*> subscripts) 
{
  //return 2 if it is up or down
  //return 1 if it is off-center
  //return 0 if it is center
  //return -1 if it is neither

  //check if subsrcipts are _gidx, _gidy or _gidz
  std::vector<SgExpression*>::const_iterator it;
  
  size_t count = 0;
  int indexNo = 0;
  size_t category = 0;

  for(it= subscripts.begin(); it != subscripts.end(); it++)
    {      
      indexNo++;
      SgExpression* index = isSgExpression(*it);

      Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(index, V_SgVarRefExp);
      
      if(varList.size() != 1) //there should be only 1 variable and that should be gidx,y,z
	return -1;
      //check if that varRef is x, y, z

      SgVarRefExp* varExp = isSgVarRefExp(*(varList.begin()));
      ROSE_ASSERT(varExp);

      string index_str = varExp->unparseToString();      
      
      if(indexNo == 1 && index_str != GIDX )
	return -1;
      else if(indexNo == 2 && index_str != GIDY )
	return -1;
      else if(indexNo == 3 && index_str != GIDZ )
	return -1;

      Rose_STL_Container<SgNode*> constList = NodeQuery::querySubTree(index, V_SgIntVal);

      if(constList.size() > 1 )
	return -1;

      if(constList.size() == 1)
	{
	  category = 1;

	  SgIntVal* constVal = isSgIntVal(*(constList.begin()));
	  ROSE_ASSERT(constVal);

	  if(constVal->get_value() > MAX_ORDER)
	    return -1;

	  //we keep maximum 3 planes in shared memory
	  if(constVal->get_value() > 1 && indexNo == 3)
	    return -1;

	  Rose_STL_Container<SgNode*> binOpList = NodeQuery::querySubTree(index, V_SgBinaryOp);
      
	  if(binOpList.size() != 1)
	    return -1;

	  SgBinaryOp* binOp = isSgBinaryOp(*(binOpList.begin()));

	  //we want either one add or subtract operation in the index expression
	  //no complex indexing is supported for now. 
	  //A[i+2][i-4] is valid but A[i*2] is not valid
	  
	  if( !isSgAddOp(binOp) &&  !isSgSubtractOp(binOp))
	    return -1;

	  if(indexNo == 3) 
	    { 
	      category = 2;
	    }
	}
      count++;
    }

  return (count == subscripts.size()) ? category : -1 ;

}