/*
 Inserts the loop before the expr statement
 for (_$dim = 0; _$dim < _length$dim; _$dim++) ;
 */
void insertLoop(SgExprStatement* exprStmt, int index) {

	string indexStr = StringUtility::numberToString(index);
	string indexName = "_" + indexStr;
	string lengthName = "_length" + indexStr;

	ROSE_ASSERT(exprStmt != NULL);
	SgScopeStatement* scope = exprStmt->get_scope();

	SgVarRefExp* indexRefExp = buildVarRefExp(indexName, scope);
	SgVarRefExp* lengthRefExp = buildVarRefExp(lengthName, scope);
	// Init Statement
	SgStatement* init_stmt = buildAssignStatement(indexRefExp, buildIntVal(0));

	// Cond Statement
	SgExprStatement* cond_stmt = buildExprStatement(buildLessThanOp(indexRefExp, lengthRefExp));

	// Increment Expression
	SgExpression *incr_exp = buildPlusPlusOp(indexRefExp, SgUnaryOp::postfix);

	SgForStatement* loop = buildForStatement(init_stmt, cond_stmt, incr_exp, buildBasicBlock());
	ROSE_ASSERT(loop != NULL);
	insertStatementBefore(exprStmt, loop);
	removeStatement(exprStmt);
	appendStatement(exprStmt, isSgBasicBlock(loop->get_loop_body()));

}
Esempio n. 2
0
  //A generic function to check if a loop has a tag statement prepended to it, asking for instrumentation
  //If so, the loop will be instrumented and the tag statement will be returned.
  // This function supports both C/C++ for loops and Fortran Do loops
  SgStatement* instrumentLoopForCounting(SgStatement* loop)
  {
    //get scope of the loop
    assert (loop != NULL);
    SgForStatement* forloop = isSgForStatement(loop); 
    SgFortranDo* doloop = isSgFortranDo(loop);  
    SgScopeStatement* scope = NULL; 

    if (forloop)
      scope = forloop->get_scope();
    else if (doloop)
      scope = doloop->get_scope(); 
    else
    {
      cerr<<"Error in instrumentLoopForCounting(): Unrecognized loop type:"<< loop->class_name()<<endl;
      assert(false);
    }
    ROSE_ASSERT(scope != NULL);

    // Only for a do-loop which immediately follows  chiterations =  ..
    SgVariableSymbol * chiterations_sym = lookupVariableSymbolInParentScopes(SgName("chiterations"), isSgScopeStatement(loop));
    if (chiterations_sym==NULL) return NULL;
    SgStatement* prev_stmt = getPreviousStatement(loop,false);

    // backwards search, skipping pragma declaration etc.
    while (prev_stmt!=NULL && !isAssignmentStmtOf (prev_stmt, chiterations_sym->get_declaration()))
      prev_stmt = getPreviousStatement(prev_stmt,false);
    if (prev_stmt == NULL) return NULL;

    // To support nested loops, we need to use unique chiterations variable for each loop
    // otherwise the value stored in inner loop will overwrite the iteration count for the outerloop.
    loop_id ++; // increment loop ID
    // insert size_t chiterations_id ; 
    // Find the enclosing function declaration, including its derived instances like 
    //isSgProcedureHeaderStatement, isSgProgramHeaderStatement, and isSgMemberFunctionDeclaration. 
    SgFunctionDeclaration* func_decl = getEnclosingFunctionDeclaration   (loop); 
    ROSE_ASSERT (func_decl !=NULL);
    SgFunctionDefinition* func_def = func_decl->get_definition();
    ROSE_ASSERT (func_def !=NULL);
    SgBasicBlock* func_body = func_def->get_body();
    // insert a new variable declaration
    std::string new_iter_var_name = std::string("chiterations_") + StringUtility::numberToString(loop_id);
    SgVariableDeclaration* new_iter_var_decl = buildVariableDeclaration(new_iter_var_name, chiterations_sym->get_type(), NULL, func_body); 
    SgStatement* last_decl = findLastDeclarationStatement(func_body);
    if (last_decl!=NULL)
      insertStatementAfter (last_decl, new_iter_var_decl, false);
    else
      prependStatement(new_iter_var_decl, func_body);

    // rewrite the assignment stmt's left hand variable to be the new symbol
    SgExpression* lhs = NULL; 
    bool rt = isAssignmentStatement (prev_stmt, &lhs); 
    ROSE_ASSERT (rt == true);
    ROSE_ASSERT (lhs != NULL);
    SgVarRefExp* var_ref = isSgVarRefExp (lhs);
    ROSE_ASSERT (var_ref != NULL);
    var_ref->set_symbol(getFirstVarSym (new_iter_var_decl));

    SgStatement* loop_body = NULL; 
    if (forloop)
      loop_body = forloop->get_loop_body();
    else if (doloop)
       loop_body = doloop->get_body();
    assert (loop_body != NULL);     

    // count FP operations for each loop
    CountFPOperations (loop_body);
    //chflops=chflops+chiterations*n
    FPCounters* current_result = getFPCounters (loop_body);
    if (current_result->getTotalCount() >0)
    {
      SgExprStatement* stmt = buildCounterAccumulationStmt("chflops", new_iter_var_name , buildIntVal(current_result->getTotalCount()),scope);
      insertStatementAfter (loop, stmt);
      attachComment(stmt,"      aitool generated FLOPS counting statement ...");
    }

    // Obtain per-iteration load/store bytes calculation expressions
    // excluding scalar types to match the manual version
    //CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars = true, bool includeIntType = true);
    std::pair <SgExpression*, SgExpression*> load_store_count_pair = CountLoadStoreBytes (loop_body, false, true);
    // chstores=chstores+chiterations*8
    if (load_store_count_pair.second!= NULL)
    {
      SgExprStatement* store_byte_stmt = buildCounterAccumulationStmt("chstores", new_iter_var_name, load_store_count_pair.second, scope);
      insertStatementAfter (loop, store_byte_stmt);
      attachComment(store_byte_stmt,"      aitool generated Stores counting statement ...");
    }
    // handle loads stmt 2nd so it can be inserted as the first after the loop
    // build  chloads=chloads+chiterations*2*8
    if (load_store_count_pair.first != NULL)
    {
      SgExprStatement* load_byte_stmt = buildCounterAccumulationStmt("chloads", new_iter_var_name, load_store_count_pair.first, scope);
      insertStatementAfter (loop, load_byte_stmt);
      attachComment(load_byte_stmt,"      aitool generated Loads counting statement ...");
    }

    return prev_stmt; 
  } // end instrumentLoopForCounting()
Esempio n. 3
0
void createOneGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body,
					 MintInitNameMapExpList_t refList, 
					 SgDeclarationStatement* src_location)
{
  //We declare one index variable for all arrays: one for 1D, one for 2D, one for 3D
  //Need a compiler flag for this

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

  ROSE_ASSERT(src_location);

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

  SgScopeStatement* indexScope= src_location->get_scope();

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

  MintInitNameMapExpList_t::iterator arr; 

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

      int dim = MintArrayInterface::getDimension(iname);

      ROSE_ASSERT(dim <= 3);

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

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

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

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

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

      string index_str = "index";

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

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

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

      //step 6 check if there is a loop, if there is we need to update the index 
      //but we only update if the loop makes changes in the array reference 
      std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement);
      
      if(loopNest.size() > 0)
	{
	  SgForStatement* loop = *(loopNest.begin());
	  SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body());
	  SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp);
	  ROSE_ASSERT(update_stmt);
	  prependStatement(update_stmt, loop_body);
	}      
    }
} 
Esempio n. 4
0
void createGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body,
				      MintInitNameMapExpList_t refList, 
				      SgDeclarationStatement* src_location)
{
  //we need to exclude the ones for shared memory
  //step 4 create an index expression for each distinct array 
  //e.g. _gidx + _gidy * widthUnew  in 2D
  //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D

  ROSE_ASSERT(src_location);

  SgScopeStatement* indexScope= src_location->get_scope();

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

  MintInitNameMapExpList_t::iterator arr; 

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

      int dim = MintArrayInterface::getDimension(iname);

      ROSE_ASSERT(dim <= 3);

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

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

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

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

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

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

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

      //step 6 check if there is a loop, if there is we need to update the index 
      //but we only update if the loop makes changes in the array reference 
      std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement);
      
      if(loopNest.size() > 0)
	{
	  SgForStatement* loop = *(loopNest.begin());
	  SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body());
	  SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp);
	  ROSE_ASSERT(update_stmt);
	  prependStatement(update_stmt, loop_body);
	}      
    }
} 
Esempio n. 5
0
bool processStatements(SgNode* n)
{
  ROSE_ASSERT (n!=NULL);
  // Skip compiler generated code, system headers, etc.
  if (isSgLocatedNode(n))
  {
    if (isSgLocatedNode(n)->get_file_info()->isCompilerGenerated())
      return false;
  }

  // For C/C++ loops 
  if (isSgForStatement(n)!=NULL){
    SgForStatement* loop = isSgForStatement(n);
    SgScopeStatement* scope = loop->get_scope();
    ROSE_ASSERT(scope != NULL);

   if (running_mode == e_analysis_and_instrument)
     instrumentLoopForCounting (loop);
   else if (running_mode == e_static_counting)
   {  
     CountFPOperations (loop->get_loop_body());
     // verify the counting results are consistent with reference results from pragmas	 
     if (SgStatement* prev_stmt = getPreviousStatement(loop))
     {
       if (isSgPragmaDeclaration(prev_stmt))
       {
         FPCounters* ref_result = getFPCounters (prev_stmt);
         FPCounters* current_result = getFPCounters (loop->get_loop_body());
         if (ref_result != NULL)
         {
           if (!current_result->consistentWithReference (ref_result))
           {
             cerr<<"Error. Calculated FP operation counts differ from reference counts parsed from pragma!"<<endl;
             ref_result->printInfo("Reference counts are ....");
             current_result->printInfo("Calculated counts are ....");
           }
           assert (current_result->consistentWithReference (ref_result)); 
         }
         else
         {
           // I believe ref_result should be available at this point
           assert (false);
         }  
       }
     } // end verification
   } 
  } 
  // Get reference FP operation counting values from pragma, if available.
  // This is no longer useful since we use bottomup traversal!!
  // We should split this into another phase!!
  else if (isSgPragmaDeclaration(n))
  {
    FPCounters* result = parse_aitool_pragma(isSgPragmaDeclaration(n));
    if (result != NULL)
    {
      isSgPragmaDeclaration(n) -> setAttribute("FPCounters", result);
      if (debug)
      {
        FPCounters* result2 = getFPCounters (isSgLocatedNode(n));
        result2->printInfo("After set and getFPCounters");
      }
    }
  }
  // Now Fortran support
  else if (SgFortranDo* doloop = isSgFortranDo(n))
  {
     instrumentLoopForCounting (doloop);
  }
  return true;
}
Esempio n. 6
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. 7
0
bool
ClastToSage::insertPragmas(SgNode* root)
{
  // 1- Collect the list of outer-parallel loop iterators specified
  // by pluto, as given by the .pragmas file.  Grammar is: 1 line per
  // iterator, "ITER \SPACE PRAGMA STRING \ENDLNE"
  std::ifstream plutofile;
  plutofile.open(".pragmas");
  std::vector<std::string> ompLoopIterators;
  if (plutofile)
    {
      std::string iter;
      char junk[256];
      while (plutofile >> iter)
	{
	  ompLoopIterators.push_back(iter);
	  plutofile.getline(junk, 256);
	}
      plutofile.close();
    }

  // 2- Collect the list of inner-parallel loop iterators specified
  // by pluto, as given by the .vectorize file.  Grammar is: 1 line per
  // iterator, "ITER\ENDLINE"
  plutofile.open(".vectorize");
  std::vector<std::string> simdLoopIterators;
  if (plutofile)
    {
      std::string iter;
      char junk[256];
      while (plutofile >> iter)
	{
	  simdLoopIterators.push_back(iter);
	  plutofile.getline(junk, 256);
	}
      plutofile.close();
    }


  // 3- Collect all for loops.
  std::vector<SgNode*> forLoops =
    NodeQuery::querySubTree(root, V_SgForStatement);

  std::set<std::string>::const_iterator i;
  std::set<std::string> allIterators;
  allIterators.insert(ompLoopIterators.begin(), ompLoopIterators.end());
  allIterators.insert(simdLoopIterators.begin(), simdLoopIterators.end());
  // 4- Iterate on all dimensions to parallelize.
  for (i = allIterators.begin(); i != allIterators.end(); ++i)
    {
      SgName iterName(*i);
      SgSymbol* iterSymb = isSgScopeStatement(root)->lookup_symbol(iterName);

      if (iterSymb == NULL)
	{
	  // The loop iterator symbol does not exist. Typical case
	  // where the tile size exceeds the iteration domain size:
	  // there is only one parallel iteration, thus no loop,
	  // thus no iterator. Safely proceed to the next loop iterator.
	  continue;
	}

      std::vector<SgNode*>::const_iterator j;
      for (j = forLoops.begin(); j != forLoops.end(); ++j)
	{
	  SgForStatement* fornode = isSgForStatement(*j);
	  ROSE_ASSERT(fornode);
	  // Get the loop iterator.
	  SgVariableSymbol* forSymb =
	    SageTools::getLoopIteratorSymbol(fornode);
	  ROSE_ASSERT(forSymb);

	  if (forSymb == iterSymb)
	    {
	      std::string pragmaClause;

	      if (std::find(simdLoopIterators.begin(),
			    simdLoopIterators.end(),*i)
		  != simdLoopIterators.end())
		{
		  // This is a SIMDizable loop.
		  // For a vectorizable and parallelizable dimension,
		  // vectorization has precedence.
		  pragmaClause = "#pragma ivdep\n#pragma vector always";
		}
	      else
		if (std::find(ompLoopIterators.begin(), ompLoopIterators.end(),
			      *i) != ompLoopIterators.end())
		  {
		    // This is an OpenMP parallelizable loop.

		    // Collect all loop iterator names in the enclosed loops
		    std::vector<SgNode*> innerLoops =
		      NodeQuery::querySubTree(fornode->get_loop_body(),
					      V_SgForStatement);

		    // Create the pragma clause.
		    pragmaClause = "#pragma omp parallel for";
		    bool first = true;
		    std::vector<SgNode*>::const_iterator k;
		    std::set<SgVariableSymbol*> loopSymbols;
		    for (k = innerLoops.begin(); k != innerLoops.end(); ++k)
		      loopSymbols.insert(SageTools::getLoopIteratorSymbol
					 (isSgForStatement(*k)));
		    if (loopSymbols.size() > 0)
		      pragmaClause = pragmaClause + " private(";
		    std::set<SgVariableSymbol*>::const_iterator l;
		    for (l = loopSymbols.begin(); l != loopSymbols.end(); ++l)
		      {
			std::string iterName = (*l)->get_name().getString();
			if (first)
			  {
			    pragmaClause = pragmaClause + iterName;
			    first = false;
			  }
			else
			  pragmaClause = pragmaClause + ", " + iterName;

		      }
		    if (loopSymbols.size() > 0)
		      pragmaClause = pragmaClause + ")";
		  }
		else
		  {
		    // Should never occur.
		    ROSE_ASSERT(0);
		  }
	      // Annotate the for node with the pragma clause.
	      SageInterface::attachArbitraryText(fornode, pragmaClause,
						 PreprocessingInfo::before);

	      // Put loop lower bound and upper bound outside the loop
	      // (OpenMp does not like complex loop bounds).
	      /// LNP: FIXME: do it if it becomes needed.
	    }


	}
    }

  return true;

}
Esempio n. 8
0
ExprSynAttr *examineStatement(SgStatement *stmt, ostream &out) {
    SgExpression *expr;
    SgExprStatement *expr_stmt;
    ExprSynAttr *expr_attr = NULL;
    ExprSynAttr *attr1 = NULL;

    stringstream fake;
    int i;
    if (NULL == stmt)
        return NULL;
    //out << "/* " << stmt->unparseToString() << " */" << endl;

    switch(stmt->variantT()) {
        case V_SgExprStatement:
        {
            expr_stmt = isSgExprStatement(stmt);
            expr_attr = examineExpr(expr_stmt->get_expression(), fake);
            //out << ";";
            if (NULL != expr_attr) {
                expr_attr->output_comments(out);
            }
            break;
        }
        case V_SgVariableDeclaration:
        {
            SgVariableDeclaration *vardecl = isSgVariableDeclaration(stmt);
            expr_attr = examineVariableDeclaration(vardecl, out);
            break;
        }
        case V_SgBreakStmt:
        {
            out << "break;";
            expr_attr->code << "break;";
            break;
        }
        case V_SgContinueStmt:
        {
            out << "continue;";
            expr_attr->code << "continue;";
            break;
        }
        case V_SgReturnStmt:
        {
            SgReturnStmt *retstmt = isSgReturnStmt(stmt);
            expr_attr = new ExprSynAttr();
            out << "return ";
            expr = retstmt->get_expression();
            if (expr) {
                attr1 = examineExpr(expr, out);
                expr_attr->union_tmp_decls(attr1);
                expr_attr->code << attr1->code.str();
            }
            out << ";";
            expr_attr->code << "return ";
            if (attr1) {
                expr_attr->result_var = attr1->result_var;
                expr_attr->code << expr_attr->result_var;
            }
            expr_attr->code << ";";
            break;
        }
        case V_SgForStatement:
        {
            stringstream head;
            head << "for (";
            SgForStatement *forstmt = isSgForStatement(stmt);
            SgStatementPtrList &init_stmt_list = forstmt->get_init_stmt();
            SgStatementPtrList::const_iterator init_stmt_iter;
            for (init_stmt_iter = init_stmt_list.begin();
                    init_stmt_iter != init_stmt_list.end();
                    init_stmt_iter++) {
                stmt = *init_stmt_iter;
                if (init_stmt_iter != init_stmt_list.begin())
                    head << ", ";
                expr_stmt = isSgExprStatement(stmt);
                if (expr_stmt)
                    examineExpr(expr_stmt->get_expression(), head);
            }
            head << "; ";
            expr_stmt = isSgExprStatement(forstmt->get_test());
            if (expr_stmt)
                examineExpr(expr_stmt->get_expression(), head);
            head << "; ";
            expr = forstmt->get_increment();
            examineExpr(expr, head);
            head << ")" << endl;

            /* Loop body */
            stmt = forstmt->get_loop_body();
            expr_attr = examineStatement(stmt, fake);
            attr1 = new ExprSynAttr();
            attr1->code << head.str();
            if (!isSgScopeStatement(stmt)) {
                attr1->code << "{" << endl;
            }
            expr_attr->output_tmp_decls(attr1->code);
            attr1->code << expr_attr->code.str();
            if (!isSgScopeStatement(stmt)) {
                attr1->code << "}" << endl;
            }
            delete expr_attr;
            expr_attr = attr1;
            attr1 = NULL;
            out << head.str();
            out << fake.str();
            break;
        }
        case V_SgBasicBlock:
        {
            SgScopeStatement *scope = isSgScopeStatement(stmt);
            expr_attr = examineScopeStatement(scope, "scope", out);
            break;
        }
        case V_SgIfStmt: 
        {
            stringstream head;
            SgIfStmt *ifstmt = isSgIfStmt(stmt);
            head << "if (";
            stmt = ifstmt->get_conditional();
            expr_stmt = isSgExprStatement(stmt);
            if (expr_stmt) {
                attr1 = examineExpr(expr_stmt->get_expression(), head);
                if (attr1 != NULL)
                    delete attr1;
            }
            head << ")" << endl;
            out << head.str();

            /* True body */
            stmt = ifstmt->get_true_body();
            expr_attr = examineStatement(stmt, fake);
            attr1 = new ExprSynAttr();
            attr1->code << head.str();
            if (!isSgScopeStatement(stmt)) {
                attr1->code << "{" << endl;
            }
            expr_attr->output_tmp_decls(attr1->code);
            attr1->code << expr_attr->code.str();
            if (!isSgScopeStatement(stmt)) {
                attr1->code << "}" << endl;
            }
            delete expr_attr;
            expr_attr = attr1;
            attr1 = NULL;
            out << head.str();
            out << fake.str();

            /* False body */
            stmt = ifstmt->get_false_body();
            if (stmt) {
                out << endl << "else" << endl;
                expr_attr->code << endl << "else" << endl;
                attr1 = examineStatement(stmt, out);
                if (!isSgScopeStatement(stmt)) {
                    expr_attr->code << "{" << endl;
                }
                attr1->output_tmp_decls(expr_attr->code);
                expr_attr->code << attr1->code.str();
                if (!isSgScopeStatement(stmt)) {
                    expr_attr->code << "}" << endl;
                }
            }

            break;
        }
        case V_SgWhileStmt:
        {
            stringstream head;
            SgWhileStmt *whilestmt = isSgWhileStmt(stmt);
            expr_stmt = isSgExprStatement(whilestmt->get_condition());
            head << "while (";
            if (expr_stmt) {
                attr1 = examineExpr(expr_stmt->get_expression(), head);
                if (NULL != attr1)
                    delete attr1;
            }
            out << head.str() << ")" << endl;
            head << ")" << endl;
            if (!isSgScopeStatement(stmt)) {
                head << "{" << endl;
            }
            expr_attr = new ExprSynAttr();
            expr_attr->code << head.str();

            /* Loop Body */
            stmt = whilestmt->get_body();
            attr1 = examineStatement(stmt, out);

            attr1->output_tmp_decls(expr_attr->code);
            expr_attr->code << attr1->code.str();
            if (!isSgScopeStatement(stmt)) {
                expr_attr->code << "}" << endl;
            }

            delete attr1;
            break;
        }
        case V_SgDoWhileStmt:
        {
            stringstream head;
            SgDoWhileStmt *dowhilestmt = isSgDoWhileStmt(stmt);
            expr_stmt = isSgExprStatement(dowhilestmt->get_condition());
            stmt = dowhilestmt->get_body();
            out << "do";
            head << "do" << endl;
            if (!isSgScopeStatement(stmt)) {
                head << "{" << endl;
            }
            expr_attr = new ExprSynAttr();
            expr_attr->code << head.str();
            attr1 = examineStatement(stmt, out);


            attr1->output_tmp_decls(expr_attr->code);
            expr_attr->code << attr1->code.str();
            if (!isSgScopeStatement(stmt)) {
                expr_attr->code << "}" << endl;
            }
            expr_attr->code << " while (";
            delete attr1;
            out << " while (";
            head.str("");
            if (expr_stmt) {
                attr1 = examineExpr(expr_stmt->get_expression(), head);
                delete attr1;
                out << head.str();
                expr_attr->code << head.str();
            }
            out << ");" << endl;
            expr_attr->code << ");" << endl;
            break;
        }
    }

    return expr_attr;
}
Esempio n. 9
0
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	
	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				SgForStatement *forStat = isSgForStatement(astNode); 
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				for(size_t i=0; i<mAllFors.size(); i++) {
					if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) {
						ostringstream newFor;
						newFor << "for(";
						newFor << (*(forStat->get_init_stmt().begin()))->unparseToString();
						newFor << forStat->get_test_expr()->unparseToString() << ";" ;
						newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ;
						newFor << forStat->get_loop_body()->unparseToString();
						cout << " is blocked loop..." << endl;
						returnAttribute.replace( astNode, newFor.str() );
					}
				}
			} break;

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() <<  endl;
				forBlockVector fors = inheritedAttribute.getForScopes();

				// replace variable occurrences in the loop kernel
				if(inheritedAttribute.getLoopKernel()) {
					for(size_t i=0;i<fors.size(); i++) {
						if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) &&
								( isSgVarRefExp(astNode)->get_type() == fors[i]->varType )
							) {
							string blockedVarName("blocked_");
							blockedVarName += fors[i]->varName;
							AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName );
							cout << "   replacing with '"<<blockedVarName<<"' " << endl;
						}
					}
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
			returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	//if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work?
	if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) {
		// we're back at the loop kernel block, now replace and insert new loops...
		insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() );
	}

	return returnAttribute;
}
Esempio n. 10
0
// Functions required by the tree traversal mechanism
MyInheritedAttribute
MyTraversal::evaluateRewriteInheritedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute )
{
	MyInheritedAttribute returnAttribute = inheritedAttribute;

	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				SgForStatement *forStat = isSgForStatement(astNode); 

				forBlockInfo *inf = new forBlockInfo;
				inf->forStmt = forStat;
				SgInitializedName *varin = isSgInitializedName( forStat->get_traversalSuccessorContainer()[0] //for init
						->get_traversalSuccessorContainer()[0] // var decl
						->get_traversalSuccessorContainer()[0] // initialized name
						);
				assert( varin );
				inf->varName = varin->get_name().str();
				inf->varType = varin->get_type();
				inf->blocked = false;
				inf->blockSize = 0;

				returnAttribute.addForStatement( inf );
				mAllFors.push_back( inf );

				list<SgNode*> forList = NodeQuery::querySubTree( astNode, forStatementNodeQuery );
				if( (forList.size()==1) && // only the current loop?
						(returnAttribute.getForScopes().size()>1) ) {
					cerr << "   it is the innermost for loop " << endl;
					mpLoopBody = forStat->get_loop_body();
				}
			} break;

		default:
			break;
	}

	if(astNode == mpLoopBody) {
		bool loopsValid = true;
		
		// do some basic checks for validity
		forBlockVector fors = returnAttribute.getForScopes();
		for(size_t i=0;i<fors.size(); i++) {
			SgExpression *testExpr = fors[i]->forStmt->get_test_expr();
			SgExpression *incExpr  = fors[i]->forStmt->get_increment_expr();
			if(isSgPlusPlusOp(incExpr) ==NULL)  loopsValid = false;
			if(isSgLessThanOp(testExpr) ==NULL) loopsValid = false;
			else {
				if(! isSgVarRefExp(isSgLessThanOp(testExpr)->get_lhs_operand()) ) loopsValid = false;
			}
		}

		// this is the basic block of the innermost loop
		// only do trafos, if more than two nested loop nests, and we found the inner one
		if(loopsValid) {
			returnAttribute.setLoopKernel( true );
		} else {
			cout << " loop nest not valid, skipping transformation..." << endl;
		}
	}
	
	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable++;
			cerr << "nested scope found, #" << mReplaceVariable << endl;
		}
	} 

	return returnAttribute;
}