コード例 #1
0
int main(int argc, char * argv[])
{
  SgProject *project = frontend (argc, argv);
  SgFunctionDeclaration* func_decl = SageInterface::findDeclarationStatement<SgFunctionDeclaration> 
     (project, "foo", NULL, true);
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(func_decl->get_definition(), V_SgVarRefExp);
  for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++)
  {
    SgVarRefExp *vRef = isSgVarRefExp((*i));
    cout<<"varRefExp: "<< vRef->unparseToString()<<endl;
  }

  // We expect two references 
  // from input_ompVariableCollecting.C
  if (nodeList.size() !=2)
  {
    cerr<<"Error. We should find exactly two variable references."<<endl;
  }
  ROSE_ASSERT (nodeList.size() ==2);

  return backend(project);
}
コード例 #2
0
ファイル: MintArrayInterface.C プロジェクト: 8l/rose
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
コード例 #3
0
ファイル: StencilAnalysis.C プロジェクト: 8l/rose
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 ;

}
コード例 #4
0
ファイル: StencilAnalysis.C プロジェクト: 8l/rose
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 ;

}