/*
 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()));

}
예제 #2
0
파일: discardAssignment.C 프로젝트: 8l/rose
void
CompassAnalyses::DiscardAssignment::Traversal::
visit(SgNode* node)
   { 
     if (isSgAssignOp(node))
     {
       // simple case: the parent of a "real" assignment op must be an
       // expression statement
       if (!isSgExprStatement(node->get_parent()))
       {
         output->addOutput(new CheckerOutput(node));
       }
       else
       {
         // not so simple case: the parent is an expression statement, but if
         // that statement is an if/loop condition, we still want to complain
         SgNode *assignment = node->get_parent();
         SgNode *p = assignment->get_parent();
         SgDoWhileStmt *dws;
         SgForStatement *fs;
         SgIfStmt *is;
         SgSwitchStatement *ss;
         SgWhileStmt *ws;

         if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
       }
     }
     else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node))
     {
       // not so simple case: call to operator= member function that is not an
       // expression statement by itself
       SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent());
       if (call && !isSgExprStatement(call->get_parent())
        && mf->get_parent() == call->get_function()
        && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0)
       {
         output->addOutput(new CheckerOutput(call));
       }
     }
   } //End of the visit function.
예제 #3
0
void
CompassAnalyses::ExplicitTestForNonBooleanValue::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  
        // 1. conditional expression
        if(NULL != isSgBasicBlock(node))
        {
          Rose_STL_Container<SgNode*> conditionalExpList = NodeQuery::querySubTree(node, V_SgConditionalExp);
          for(Rose_STL_Container<SgNode*>::iterator i=conditionalExpList.begin(); i != conditionalExpList.end(); i++)
          {
            SgConditionalExp* conditionalExp = isSgConditionalExp(*i);
            //ROSE_ASSERT(conditionalExp != NULL);

            if(NULL != conditionalExp && NULL != isSgCastExp(conditionalExp->get_conditional_exp()))
            {
              output->addOutput(new CheckerOutput(conditionalExp));
            }
          }
        } else {

          SgExprStatement* exprStatement = NULL;

          // 2. test statement in a if statement
          SgIfStmt* ifStmt = isSgIfStmt(node);
          if(NULL != ifStmt)
            exprStatement = isSgExprStatement(ifStmt->get_conditional());

          // 3. test statement in a while statement
          SgWhileStmt* whileStmt = isSgWhileStmt(node);
          if(NULL != whileStmt)
            exprStatement = isSgExprStatement(whileStmt->get_condition());

          // 4. test statement in a do-while statement
          SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node);
          if(NULL != doWhileStmt)
            exprStatement = isSgExprStatement(doWhileStmt->get_condition());

          // 5. test statement in a for statement
          SgForStatement* forStatement = isSgForStatement(node);
          if(NULL != forStatement)
            exprStatement = isSgExprStatement(forStatement->get_test());

          if(NULL != exprStatement && NULL != isSgCastExp(exprStatement->get_expression()))
          {
            output->addOutput(new CheckerOutput(node));
          }
        }

   } //End of the visit function.
예제 #4
0
void
CompassAnalyses::FloatingPointExactComparison::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  

     SgExprStatement* exprStatement = NULL;

     SgIfStmt* ifStmt = isSgIfStmt(node);
     if(NULL != ifStmt)
       exprStatement = isSgExprStatement(ifStmt->get_conditional());

     SgWhileStmt* whileStmt = isSgWhileStmt(node);
     if(NULL != whileStmt)
       exprStatement = isSgExprStatement(whileStmt->get_condition());

     SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node);
     if(NULL != doWhileStmt)
       exprStatement = isSgExprStatement(doWhileStmt->get_condition());

     SgForStatement* forStatement = isSgForStatement(node);
     if(NULL != forStatement)
       exprStatement = isSgExprStatement(forStatement->get_test());

     if(NULL != exprStatement && NULL != isSgNotEqualOp(exprStatement->get_expression()))
     {
       SgNotEqualOp* comparison = isSgNotEqualOp(exprStatement->get_expression());
       if((comparison->get_lhs_operand_i() != NULL &&
           isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) ||
          (comparison->get_rhs_operand_i() != NULL &&
           isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL))
       {
         output->addOutput(new CheckerOutput(comparison));
       }
     }

     if(NULL != exprStatement && NULL != isSgEqualityOp(exprStatement->get_expression()))
     {
       SgEqualityOp* comparison = isSgEqualityOp(exprStatement->get_expression());
       if((comparison->get_lhs_operand_i() != NULL &&
           isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) ||
          (comparison->get_rhs_operand_i() != NULL &&
           isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL))
       {
         output->addOutput(new CheckerOutput(comparison));
       }
     }

   } //End of the visit function.
예제 #5
0
파일: mlm.cpp 프로젝트: 8l/rose
void mlmFrontend::attachAttribute(SgPragmaDeclaration* pragma, AstAttribute* attr)
{
// attribute to specify memory level
  if(isSgVariableDeclaration(getNextStatement(pragma)))
  {
    SgVariableDeclaration* decl = isSgVariableDeclaration(getNextStatement(pragma));  
    ROSE_ASSERT(decl);
    SgInitializedNamePtrList nameList = decl->get_variables();
    if(nameList.size() == 1)
    {
      SgInitializedName* initName = nameList[0];
      SgSymbol* symbol = initName->get_symbol_from_symbol_table();
      symbol->setAttribute("mlmAttribute", attr);
    } 
  }
// attribute to specify tiling level
  else if(isSgForStatement(getNextStatement(pragma)))
  {
    SgForStatement* forStmt = isSgForStatement(getNextStatement(pragma));
    ROSE_ASSERT(forStmt);
    forStmt->setAttribute("mlmAttribute", attr);
  }
}
예제 #6
0
파일: measureTool.cpp 프로젝트: 8l/rose
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;
}
void
SourceLocationInheritedAttribute::
refineClassification ( SgNode* astNode )
   {
     ROSE_ASSERT (astNode != NULL);
  // printf ("Inside of SourceLocationInheritedAttribute::refineClassification() astNode->sage_class_name() = %s \n",astNode->sage_class_name());

  // Always update this variable
     currentNode = astNode;

  // Only update the currentStatement if the current node is a SgStatement node
     if (isSgStatement(astNode) != NULL)
        {
          currentStatement = isSgStatement(astNode);

       // With this stack we never have to pop anything off the stack
          statementList.push_back(currentStatement);

       // IDEA: Store the current statement with the scope as we push the scope onto the stack
       // Then we can more accurately associate the statement with a given scope.
       // if (isSgScopeStatement(astNode) != NULL)
       // if ( (isSgScopeStatement(astNode) != NULL) && (astNode->get_traversalSuccessorNamesContainer().size() > 0) )

       // Only save the scoep if it is a global scope or basic block
          if ( (isSgGlobal(astNode) != NULL) ||
               (isSgBasicBlock(astNode) != NULL) )
             {
               SgScopeStatement* scope = isSgScopeStatement(astNode);
               scopeList.push_back(scope);
             }

       // printf ("Need to store the current statement with the scope (or something like that) \n");
        }

#if ROSE_INTERNAL_DEBUG
  // error checking
     unsigned int i;
     for (i = 0; i < scopeList.size(); i++)
        {
          ROSE_ASSERT (scopeList[i] != NULL);
        }
     for (i = 0; i < statementList.size(); i++)
        {
          ROSE_ASSERT (statementList[i] != NULL);
        }
#endif

  // Only update the currentExpression if the current node is a SgExpression node
     if (isSgExpression(astNode) != NULL)
          currentExpression = isSgExpression(astNode);

  // currentFunctionBasicBlockScope = NULL;

  // Refine the information with a classification of the current node
     ROSE_ASSERT (astNode != NULL);
     switch (astNode->variantT())
        {
          case V_SgProject:
               project = isSgProject(astNode);
               break;

       // case V_SgFile:
          case V_SgSourceFile:
          case V_SgBinaryComposite:
               file = isSgFile(astNode);
               break;

          case V_SgGlobal:
               globalScope = isSgGlobal(astNode);

            // This will be reset when we hit a SgBasicBlock (but should be set here
            // so that the local scope can be refered to even in the global scope).
               localScope  = globalScope;

            // With this stack we never have to pop anything off the stack
            // scopeList.push_back(globalScope);
               break;

          case V_SgFunctionDeclaration:
#if 0
               currentFunctionDeclaration = isSgFunctionDeclaration(astNode);
#endif
               break;

          case V_SgFunctionDefinition:
             {
               currentFunctionDefinitionScope = isSgFunctionDefinition(astNode);

            // With this stack we heve have to pop anything off the stack (don't add function definition to scope list)
            // scopeList.push_back(currentFunctionDefinitionScope);
#if 0
            // Maybe the function scope should be set when we process the basic block?
               SgFunctionDefenition functionDefinition = isSgFunctionDefinition(astNode);
               if (functionDefinition != NULL)
                    currentFunctionScope = functionDefinition->get_block();
#endif
               break;
             }

          case V_SgBasicBlock:
             {
            // printf ("Case V_SgBasicBlock \n");
               localScope = isSgBasicBlock(astNode);
               if ( isSgFunctionDefinition(localScope->get_parent()) != NULL )
                  {
                    currentFunctionBasicBlockScope = isSgBasicBlock(astNode);
                    ROSE_ASSERT ( currentFunctionBasicBlockScope == currentFunctionDefinitionScope->get_body() );
                  }

            // loop back through the loop nest to recover the parent scope of the loop nest
               SgForStatement* forStatement = isSgForStatement(localScope->get_parent());
               while ( forStatement != NULL )
                  {
                    SgStatement* parentStatement = isSgStatement(forStatement->get_parent());
                    loopNestParentScope = isSgBasicBlock(parentStatement);
                    ROSE_ASSERT (loopNestParentScope != NULL);
                    forStatement = isSgForStatement(loopNestParentScope->get_parent());
                  }

            // don't worry about nested conditionals (not yet at least)
               SgIfStmt* ifStatement = isSgIfStmt(localScope->get_parent());
               if ( ifStatement != NULL )
                  {
                    SgStatement* parentStatement = isSgStatement(ifStatement->get_parent());
                    conditionalParentScope = isSgBasicBlock(parentStatement);
                    ROSE_ASSERT (conditionalParentScope != NULL);
                  }

            // With this stack we never have to pop anything off the stack
            // scopeList.push_back(localScope);
               break;
             }

       // For now all these cases are the same
          case V_SgCatchOptionStmt:
          case V_SgClassDefinition:
          case V_SgDoWhileStmt:
          case V_SgForStatement:
          case V_SgIfStmt:
          case V_SgSwitchStatement:
          case V_SgWhileStmt:
             {
               SgScopeStatement* scope = isSgScopeStatement(astNode);
               ROSE_ASSERT (scope != NULL);

            // With this stack we never have to pop anything off the stack
            // scopeList.push_back(scope);
               break;
             }

          default:
            // astNode is some other type of AST node which we don't keep track of in this inherited
            // attribute.
#if 0
               printf ("Default case inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode);
               ROSE_ABORT();
#endif
               break;
        }

  // assertValidPointers();

#if 0
     printf ("Inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode);
     display("Inside of SourceLocationInheritedAttribute::refineClassification()");
#endif
#if 0
     printf ("Inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode);
     ROSE_ABORT();
#endif
   }
예제 #8
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;
}
in_list
objectsAllocated(SgStatement *statement, StopCond stopCond)
   {

     in_list objs;
     SgStatement *parent;
     do
        {
#if 0
          in_list::iterator startOfCurrent = objs.end();
#endif
          parent = isSgStatement(statement->get_parent());
          //cout << "parent = " << parent << endl;
          ROSE_ASSERT(parent);
          in_list blockObjs = blockObjectsAllocated(parent, statement);
          objs.insert(objs.end(), blockObjs.begin(), blockObjs.end());
#if 0
          switch (parent->variantT())
             {
               case V_SgBasicBlock:
                     {
                       SgBasicBlock *b = isSgBasicBlock(parent);
                       ROSE_ASSERT(b);
                       SgStatementPtrList &stmts = b->get_statements();
                       for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                          {
                            if (*i == statement) break;
                            addStmtVarsIfAny(objs, startOfCurrent, *i);
                          }
                     }
                  break;
               case V_SgForStatement:
                     {
                       SgForStatement *fs = isSgForStatement(parent);
                       SgStatementPtrList &stmts = fs->get_init_stmt();
                       bool done = false;
                       if (!omitInit)
                          {
                            for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                               {
                                 if (*i == statement)
                                    {
                                      done = true;
                                      break;
                                    }
                                 addStmtVarsIfAny(objs, startOfCurrent, *i);
                               }
                          }
                       if (!done)
                          {
                            if (fs->get_test() != statement)
                               {
                                 addStmtVarsIfAny(objs, startOfCurrent, fs->get_test());
                               }
                          }
                     }
                  break;
               default:
                  break;
             }
#endif
          statement = parent;
        } while (!stopCond(parent));
     return objs;
   }
예제 #10
0
파일: ai_measurement.cpp 프로젝트: 8l/rose
  //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()
예제 #11
0
// Do partial redundancy elimination, looking for copies of one expression expr
// within the basic block root.  A control flow graph for root must be provided
// in cfg, with a map from nodes to their statements in node_statements, a map
// from edges to their CFG edge types in edge_type, and a map from edges to
// their insertion points in edge_insertion_point.  The algorithm used is that
// of Paleri, Srikant, and Shankar ("Partial redundancy elimination: a simple,
// pragmatic, and provably correct algorithm", Science of Computer Programming
// 48 (2003) 1--20).
void PRE::partialRedundancyEliminationOne( SgExpression* expr, SgBasicBlock* root, const myControlFlowGraph& cfg)
{
    // SgBasicBlock* myFunctionBody = getFunctionDefinition(expr)->get_body();

    // DQ (3/16/2006): Added assertions
    ROSE_ASSERT(expr != NULL);
    ROSE_ASSERT(root != NULL);

    vector<SgVariableSymbol*> symbols_in_expression = SageInterface::getSymbolsUsedInExpression(expr);

    if (anyOfListPotentiallyModifiedIn(symbols_in_expression, expr))
    {
        // This expression updates its own arguments, and so is not idempotent
        // Return immediately
        return;
    }

    // Simple or not user-definable expressions
    if (isSgVarRefExp(expr)) return;
    if (isSgValueExp(expr)) return;
    if (isSgFunctionRefExp(expr)) return;
    if (isSgExprListExp(expr)) return;
    if (isSgInitializer(expr)) return;
#if 0
    if ( (isSgAddOp(expr) || isSgSubtractOp(expr)) &&
            (isSgVarRefExp(isSgBinaryOp(expr)->get_lhs_operand()) ||
             isSgValueExp(isSgBinaryOp(expr)->get_lhs_operand())) &&
            (isSgVarRefExp(isSgBinaryOp(expr)->get_rhs_operand()) ||
             isSgValueExp(isSgBinaryOp(expr)->get_rhs_operand())))
        return;
#endif

    // Expressions which do not keep a consistent value each time they are used
    if (!expressionTreeEqual(expr, expr))
        return;

    // cerr << "Trying to do PRE using expression " << expr->unparseToString() << " whose type is " << expr->sage_class_name() << endl;

    VertexIter i   = cfg.graph.vertices().begin(),
               end = cfg.graph.vertices().end();

    // cerr << "CFG has " << distance(i, end) << " nodes" << endl;

    bool needToMakeCachevar = false;
    set<SgNode*> replacements;
    vector<pair<SgNode*, bool /* before */> > insertions;

    vector<bool> transp(cfg.graph.vertices().size()),
           comp(cfg.graph.vertices().size()),
           antloc(cfg.graph.vertices().size());

    vector<SgNode*> first_computation(cfg.graph.vertices().size()),
           last_computation(cfg.graph.vertices().size());

    // Set values of local node properties
    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        const vector<SgNode*>& stmts = cfg.node_statements[*i];

        // Precompute test values for each statement
        vector<bool> argumentsModifiedInStatement(stmts.size());
        vector<int> expressionComputedInStatement(stmts.size());
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            if (anyOfListPotentiallyModifiedIn(symbols_in_expression, stmts[j]))
                argumentsModifiedInStatement[j] = true;
            expressionComputedInStatement[j] = countComputationsOfExpressionIn(expr, stmts[j]);
        }

        // Compute transp
        transp[*i] = true;
        for (unsigned int j = 0; j < stmts.size(); ++j)
            if (argumentsModifiedInStatement[j])
                transp[*i] = false;

        // Compute comp and do local redundancy elimination
        comp[*i] = false;
        SgNode* firstComputationInChain = 0;
        bool needToInsertComputation = false;
        bool computationInsertedOrUsed = false;
        // cout << "In node " << *i << endl;
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            // cout << "In stmt " << j << ", expressionComputedInStatement = " << expressionComputedInStatement[j]
            //      << ", argumentsModifiedInStatement = " << argumentsModifiedInStatement[j] << endl;
            if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j] && comp[*i] /* from last iter */)
            {
                // Do local redundancy elimination
                if (firstComputationInChain && needToInsertComputation)
                {
                    insertions.push_back(make_pair(firstComputationInChain, true));
                    replacements.insert(firstComputationInChain);
                    needToInsertComputation = false;
                }
                replacements.insert(stmts[j]);
                computationInsertedOrUsed = true;
                needToMakeCachevar = true;
            }
            if (expressionComputedInStatement[j])
            {
                comp[*i] = true;
                if (!firstComputationInChain)
                {
                    firstComputationInChain = stmts[j];
                    needToInsertComputation = true;
                    if (expressionComputedInStatement[j] >= 2)
                    {
                        insertions.push_back(make_pair(stmts[j], true));
                        needToMakeCachevar = true;
                        needToInsertComputation = false;
                        computationInsertedOrUsed = true;
                        replacements.insert(stmts[j]);
                    }
                }
                last_computation[*i] = stmts[j];
            }
            if (argumentsModifiedInStatement[j])
            {
                comp[*i] = false; // Must come after expressionComputedInStatement check
                firstComputationInChain = 0;
                needToInsertComputation = false;
            }
        }

        assert (!computationInsertedOrUsed || needToMakeCachevar);

        // Compute antloc
        antloc[*i] = false;
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j])
            {
                antloc[*i] = true;
                first_computation[*i] = stmts[j];
                break;
            }
            if (argumentsModifiedInStatement[j])
            {
                antloc[*i] = false;
                break;
            }
        }
    }

// #define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl;
#define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl;
    PRINT_PROPERTY(transp);
    PRINT_PROPERTY(comp);
    PRINT_PROPERTY(antloc);

    int (simpleGraph::*source_ptr)(int) const = &simpleGraph::source;
    int (simpleGraph::*target_ptr)(int) const = &simpleGraph::target;

    vector<bool> avin(cfg.graph.vertices().size(), true);
    vector<bool> avout(cfg.graph.vertices().size(), true);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(avin, cfg);
    FIXPOINT_OUTPUT_BEGIN(avout, cfg);
    avin[v] = accumulate_neighbors(cfg, v, avout,cfg.graph.in_edges(v),&simpleGraph::source, logical_and<bool>(), true, false);
    avout[v] = comp[v] || (avin[v] && transp[v]);
    FIXPOINT_OUTPUT_END(avout, <=, cfg);
    FIXPOINT_OUTPUT_END(avin, <=, cfg);
    FIXPOINT_END(cfg, out_edges, OutEdgeIter)

    PRINT_PROPERTY(avin);
    PRINT_PROPERTY(avout);

    vector<bool> antin(cfg.graph.vertices().size(), true);
    vector<bool> antout(cfg.graph.vertices().size(), true);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(antin, cfg);
    FIXPOINT_OUTPUT_BEGIN(antout, cfg);
    antout[v] = accumulate_neighbors(cfg, v, antin, cfg.graph.out_edges(v), target_ptr, logical_and<bool>(), true, false);
    antin[v] = antloc[v] || (antout[v] && transp[v]);
    FIXPOINT_OUTPUT_END(antout, <=, cfg);
    FIXPOINT_OUTPUT_END(antin, <=, cfg);
    FIXPOINT_END(cfg, in_edges, InEdgeIter)

    PRINT_PROPERTY(antin);
    PRINT_PROPERTY(antout);

    vector<bool> safein(cfg.graph.vertices().size()), safeout(cfg.graph.vertices().size());

    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        safein[*i] = avin[*i] || antin[*i];
        safeout[*i] = avout[*i] || antout[*i];
    }

    PRINT_PROPERTY(safein);
    PRINT_PROPERTY(safeout);

    vector<bool> spavin(cfg.graph.vertices().size(), false);
    vector<bool> spavout(cfg.graph.vertices().size(), false);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(spavin, cfg);
    FIXPOINT_OUTPUT_BEGIN(spavout, cfg);
    spavin[v] = safein[v] && accumulate_neighbors(cfg, v, spavout, cfg.graph.in_edges(v), source_ptr, logical_or<bool>(), false, false);
    spavout[v] = safeout[v] && (comp[v] || (spavin[v] && transp[v]));
    FIXPOINT_OUTPUT_END(spavout, >=, cfg);
    FIXPOINT_OUTPUT_END(spavin, >=, cfg);
    FIXPOINT_END(cfg, out_edges, OutEdgeIter)

    PRINT_PROPERTY(spavin);
    PRINT_PROPERTY(spavout);

    vector<bool> spantin(cfg.graph.vertices().size(), false);
    vector<bool> spantout(cfg.graph.vertices().size(), false);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(spantin, cfg);
    FIXPOINT_OUTPUT_BEGIN(spantout, cfg);
    spantout[v] = safeout[v] && accumulate_neighbors(cfg, v, spantin, cfg.graph.out_edges(v), target_ptr, logical_or<bool>(), false, false);
    spantin[v] = safein[v] && (antloc[v] || (spantout[v] && transp[v]));
    FIXPOINT_OUTPUT_END(spantout, >=, cfg);
    FIXPOINT_OUTPUT_END(spantin, >=, cfg);
    FIXPOINT_END(cfg, in_edges, InEdgeIter)

    PRINT_PROPERTY(spantin);
    PRINT_PROPERTY(spantout);
#undef PRINT_PROPERTY

    vector<bool> node_insert(cfg.graph.vertices().size());
    vector<bool> replacef(cfg.graph.vertices().size());
    vector<bool> replacel(cfg.graph.vertices().size());

    // printf ("Intermediate test 1: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        node_insert[*i] = comp[*i] && spantout[*i] && (!transp[*i] || !spavin[*i]);
        replacef[*i] = antloc[*i] && (spavin[*i] || (transp[*i] && spantout[*i]));
        replacel[*i] = comp[*i] && (spantout[*i] || (transp[*i] && spavin[*i]));

        if (node_insert[*i])
        {
            needToMakeCachevar = true;
            insertions.push_back(make_pair(last_computation[*i], true));
            // cerr << "Insert computation of " << expr->unparseToString() << " just before last computation in " << *i << endl;
        }

        if (replacef[*i])
        {
            needToMakeCachevar = true;
            replacements.insert(first_computation[*i]);
            // cerr << "Replace first computation of " << *i << endl;
        }

        if (replacel[*i])
        {
            needToMakeCachevar = true;
            replacements.insert(last_computation[*i]);
            // cerr << "Replace last computation of " << *i << endl;
        }
    }

    vector<bool> edge_insert(cfg.graph.edges().size());

    // printf ("Intermediate test 2: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    EdgeIter j = cfg.graph.edges().begin(), jend = cfg.graph.edges().end();
    for (; j != jend; ++j)
    {
        edge_insert[*j] = !spavout[cfg.graph.source(*j)] && spavin[cfg.graph.target(*j)] && spantin[cfg.graph.target(*j)];

        // printf ("edge_insert[*j] = %s \n",edge_insert[*j] ? "true" : "false");
        if (edge_insert[*j])
        {
            needToMakeCachevar = true;
            // cerr << "Insert computation of " << expr->unparseToString() << " on edge from "
            //      << cfg.graph.source(*j) << " to " << cfg.graph.target(*j) << endl;
        }
    }

    // printf ("Before final test: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    // Add cache variable if necessary
    SgVarRefExp* cachevar = 0;
    if (needToMakeCachevar)
    {
        SgName cachevarname = "cachevar__";
        cachevarname << ++SageInterface::gensym_counter;

        // printf ("Building variable name = %s \n",cachevarname.str());

        SgType* type = expr->get_type();
        if (isSgArrayType(type))
            type = new SgPointerType(isSgArrayType(type)->get_base_type());
        assert (SageInterface::isDefaultConstructible(type));
        // FIXME: assert (isAssignable(type));
        SgVariableDeclaration* decl = new SgVariableDeclaration(SgNULL_FILE, cachevarname, type, NULL);
        decl->set_definingDeclaration(decl);
        SgInitializedName* initname = decl->get_variables().back();

        // DQ (10/5/2007): Added an assertion.
        ROSE_ASSERT(initname != NULL);

        decl->addToAttachedPreprocessingInfo(
            new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment,
                                  (string("// Partial redundancy elimination: ") + cachevarname.str() +
                                   " is a cache of " + expr->unparseToString()).c_str(),
                                  "Compiler-Generated in PRE", 0, 0, 0, PreprocessingInfo::before));
        SgVariableSymbol* cachevarsym = new SgVariableSymbol(initname);
        decl->set_parent(root);

        // DQ (10/5/2007): Added scope (suggested by Jeremiah).
        initname->set_scope(root);

        root->get_statements().insert(root->get_statements().begin(),decl);

        root->insert_symbol(cachevarname, cachevarsym);
        cachevar = new SgVarRefExp(SgNULL_FILE, cachevarsym);
        cachevar->set_endOfConstruct(SgNULL_FILE);
    }

    // Do expression computation replacements
    for (set<SgNode*>::iterator i = replacements.begin(); i != replacements.end(); ++i)
    {
        ReplaceExpressionWithVarrefVisitor(expr, cachevar).traverse(*i, postorder);
    }

    // Do edge insertions
    // int count = 0;
    bool failAtEndOfFunction = false;
    for (j = cfg.graph.edges().begin(); j != jend; ++j)
    {
        // printf ("Build the insertion list! count = %d \n",count++);
        if (edge_insert[*j])
        {
#if 0
            // DQ (3/13/2006): Compiler warns that "src" is unused, so I have commented it out!
            Vertex src = cfg.graph.source(*j), tgt = cfg.graph.target(*j);
            cerr << "Doing insertion between " << src << " and " << tgt << endl;
#endif
            pair<SgNode*, bool> insert_point = cfg.edge_insertion_point[*j];
            if (insert_point.first)
            {
                insertions.push_back(insert_point);
            }
            else
            {
                // DQ (3/16/2006): This is a visited when we fixup the NULL pointer to the initializer in a SgForStatment.
                cerr << "Warning: no insertion point found" << endl; //FIXME was assert
                printf ("Need to figure out what to do here! cfg.edge_insertion_point[*j] = %p \n",&(cfg.edge_insertion_point[*j]));

                failAtEndOfFunction = true;
                ROSE_ASSERT(false);
            }
        }
    }

    // Do within-node insertions
    // printf ("At start of loop: insertions.size() = %zu \n",insertions.size());
    for (vector<pair<SgNode*, bool> >::iterator i = insertions.begin(); i != insertions.end(); ++i)
    {
        SgTreeCopy tc1, tc2;
        SgVarRefExp* cachevarCopy = isSgVarRefExp(cachevar->copy(tc1));
        ROSE_ASSERT (cachevarCopy);
        cachevarCopy->set_lvalue(true);
        SgExpression* operation = new SgAssignOp(SgNULL_FILE, cachevarCopy, isSgExpression(expr->copy(tc2)));
#if 0
        printf ("Inside of loop: insertions.size() = %zu \n",insertions.size());
        printf ("\n\ni->first = %p = %s = %s \n",i->first,i->first->class_name().c_str(),i->first->unparseToString().c_str());
        printf ("operation = %p = %s = %s \n",operation,operation->class_name().c_str(),operation->unparseToString().c_str());
#endif
        if (isSgExpression(i->first) && !i->second)
        {
            SgNode* ifp = i->first->get_parent();
            SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, isSgExpression(i->first), operation);
            operation->set_parent(comma);
            comma->set_parent(ifp);
            i->first->set_parent(comma);
            if (isSgForStatement(ifp))
            {
                isSgForStatement(ifp)->set_increment(comma);
            }
            else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_lhs_operand() == i->first)
            {
                isSgBinaryOp(ifp)->set_lhs_operand(comma);
            }
            else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_rhs_operand() == i->first)
            {
                isSgBinaryOp(ifp)->set_rhs_operand(comma);
            }
            else if (isSgUnaryOp(ifp) && isSgUnaryOp(ifp)->get_operand() == i->first)
            {
                isSgUnaryOp(ifp)->set_operand(comma);
            }
            else
            {
                cerr << ifp->sage_class_name() << endl;
                assert (!"Bad parent type for inserting comma expression");
            }
        }
        else
        {
            SgStatement* the_computation = new SgExprStatement(SgNULL_FILE, operation);
            operation->set_parent(the_computation);
            // printf ("In pre.C: the_computation = %p = %s \n",the_computation,the_computation->class_name().c_str());

            if (isSgBasicBlock(i->first) && i->second)
            {
                isSgBasicBlock(i->first)->get_statements().insert(isSgBasicBlock(i->first)->get_statements().begin(),the_computation);
                the_computation->set_parent(i->first);
            }
            else
            {
#if 0
                // DQ (3/14/2006): Bug here when SgExprStatement from SgForStatement test is used here!
                printf ("Bug here when SgExprStatement from SgForStatement test is used: i->first = %s \n",i->first->class_name().c_str());
                i->first->get_file_info()->display("Location i->first");
                printf ("Bug here when SgExprStatement from SgForStatement test is used: TransformationSupport::getStatement(i->first) = %s \n",
                        TransformationSupport::getStatement(i->first)->class_name().c_str());
                printf ("Bug here when SgExprStatement from SgForStatement test is used: the_computation = %s \n",the_computation->class_name().c_str());
                the_computation->get_file_info()->display("Location the_computation: debug");
                ROSE_ASSERT(i->first != NULL);
                ROSE_ASSERT(i->first->get_parent() != NULL);
                printf ("i->first->get_parent() = %s \n",i->first->get_parent()->class_name().c_str());
                i->first->get_file_info()->display("Location i->first: debug");
#endif

                SgForStatement*  forStatement = isSgForStatement(i->first->get_parent());
                if (forStatement != NULL)
                {
                    // Make sure that both pointers are not equal because they are both NULL!
                    ROSE_ASSERT(forStatement->get_test() != NULL);
                    SgExprStatement* possibleTest = isSgExprStatement(i->first);
                    if ( forStatement->get_test() == possibleTest )
                    {
                        // This is a special case of a SgExpressionStatement as a target in a SgForStatement
                        // printf ("Found special case of target being the test of a SgForStatement \n");
                        forStatement->set_test(the_computation);
                        the_computation->set_parent(forStatement);
                    }
                }
                else
                {
                    SgForInitStatement*  forInitStatement = isSgForInitStatement(i->first->get_parent());
                    if (forInitStatement != NULL)
                    {
                        // printf ("Found the SgForInitStatement \n");
                        SgVariableDeclaration* possibleVariable = isSgVariableDeclaration(i->first);
                        SgExprStatement* possibleExpression = isSgExprStatement(i->first);
                        SgStatementPtrList & statementList = forInitStatement->get_init_stmt();
                        SgStatementPtrList::iterator i = statementList.begin();
                        bool addToForInitList = false;
                        while ( (addToForInitList == false) && (i != statementList.end()) )
                        {
                            // if ( *i == possibleVariable )
                            if ( *i == possibleVariable || *i == possibleExpression )
                            {
                                // This is a special case of a SgExpressionStatement as a target in a SgForStatement
                                // printf ("Found special case of SgForInitStatement transformation \n");
                                addToForInitList = true;
                            }
                            i++;
                        }

                        // Only modify the STL list outside of the loop over the list to avoid interator invalidation
                        if (addToForInitList == true)
                        {
                            // Add the the_computation statment to the list in the SgForInitStatement.
                            // Later if we abandon the SgForInitStatement then we would have to add it to
                            // the list of SgInitializedName objects in the SgVariableDeclaration OR modify
                            // the expression list to handle the extra expression (but I think this case in
                            // handled above).
                            // printf ("Adding the_computation to the list in the SgForInitStatement \n");
                            statementList.push_back(the_computation);
                            the_computation->set_parent(forInitStatement);
                        }
                    }
                    else
                    {
                        myStatementInsert(TransformationSupport::getStatement(i->first),the_computation,i->second,true);
                        the_computation->set_parent(TransformationSupport::getStatement(i->first));
                    }
                }
            }
        }
    }

    // DQ (3/16/2006): debugging code to force failure at inspection point
    if (failAtEndOfFunction == true)
    {
        printf ("Error: internal error detected \n");
        ROSE_ASSERT(false);
    }
}
예제 #12
0
파일: ClastToSage.cpp 프로젝트: 8l/rose
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;

}
예제 #13
0
// Move variables declared in a for statement to just outside that statement.
void moveForDeclaredVariables(SgNode* root)
   {
     vector<SgForStatement*> for_statements;
     FindForStatementsVisitor(for_statements).traverse(root, preorder);

     for (unsigned int i = 0; i < for_statements.size(); ++i)
        {
          SgForStatement* stmt = for_statements[i];
#ifdef FD_DEBUG
          cout << "moveForDeclaredVariables: " << stmt->unparseToString() << endl;
#endif
          SgForInitStatement* init = stmt->get_for_init_stmt();
          if (!init) continue;
          SgStatementPtrList& inits = init->get_init_stmt();
          vector<SgVariableDeclaration*> decls;
          for (SgStatementPtrList::iterator j = inits.begin(); j != inits.end(); ++j) {
            SgStatement* one_init = *j;
            if (isSgVariableDeclaration(one_init))
            {
              decls.push_back(isSgVariableDeclaration(one_init));
            }
          }
          if (decls.empty()) continue;
          SgStatement* parent = isSgStatement(stmt->get_parent());
          assert (parent);
          SgBasicBlock* bb = new SgBasicBlock(SgNULL_FILE);
          stmt->set_parent(bb);
          bb->set_parent(parent);
          SgStatementPtrList ls;
          for (unsigned int j = 0; j < decls.size(); ++j)
             {
               for (SgInitializedNamePtrList::iterator k = decls[j]->get_variables().begin(); k != decls[j]->get_variables().end(); ++k)
                  {
#ifdef FD_DEBUG
                    cout << "Working on variable " << (*k)->get_name().getString() << endl;
#endif
                    SgVariableSymbol* sym = new SgVariableSymbol(*k);
                    bb->insert_symbol((*k)->get_name(), sym);
                    (*k)->set_scope(bb);
                    SgAssignInitializer* kinit = 0;
                    if (isSgAssignInitializer((*k)->get_initializer()))
                       {
                         kinit = isSgAssignInitializer((*k)->get_initializer());
                         (*k)->set_initializer(0);
                       }

                    if (kinit)
                       {
                         SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym);
                         vr->set_endOfConstruct(SgNULL_FILE);
                         vr->set_lvalue(true);
                         SgAssignOp* assignment = new SgAssignOp(SgNULL_FILE,vr,kinit->get_operand());
                         vr->set_parent(assignment);
                         kinit->get_operand()->set_parent(assignment);
                         SgExprStatement* expr = new SgExprStatement(SgNULL_FILE, assignment);
                         assignment->set_parent(expr);
                         ls.push_back(expr);
                         expr->set_parent(init);
                       }
                  }

#if 0
               SgStatementPtrList::iterator fiiter = std::find(inits.begin(), inits.end(), decls[j]);
               assert (fiiter != inits.end());
               size_t idx = fiiter - inits.begin();
               inits.erase(inits.begin() + idx);
               inits.insert(inits.begin() + idx, ls.begin(), ls.end());
#endif
               bb->get_statements().push_back(decls[j]);
               decls[j]->set_parent(bb);
             }
          inits = ls;
          bb->get_statements().push_back(stmt);
       // printf ("In moveForDeclaredVariables(): parent = %p = %s bb = %p stmt = %p = %s \n",parent,parent->class_name().c_str(),bb,stmt,stmt->class_name().c_str());
          ROSE_ASSERT(stmt->get_parent() == bb);
          parent->replace_statement(stmt, bb);
        }
   }
예제 #14
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;
}
예제 #15
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;
}
예제 #16
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);
	}      
    }
} 
예제 #17
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);
	}      
    }
} 
예제 #18
0
int
main (int argc, char *argv[])
{
  vector<string> argvList(argv, argv+argc);
  //Processing debugging and annotation options
  //  autopar_command_processing(argvList);
  argvList = commandline_processing (argvList);
  // enable parsing user-defined pragma if enable_diff is true
  // -rose:openmp:parse_only
  if (enable_diff)
    argvList.push_back("-rose:openmp:parse_only");
  SgProject *project = frontend (argvList);
  ROSE_ASSERT (project != NULL);

  // register midend signal handling function
  if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL)
  {
    std::cout
      << "[WARN] "
      << "Configured to keep going after catching a "
      << "signal in AutoPar"
      << std::endl;
    Rose::KeepGoing::setMidendErrorCode (project, 100);
    goto label_end;
  }   

  // create a block to avoid jump crosses initialization of candidateFuncDefs etc.
  {                             
    std::vector<SgFunctionDefinition* > candidateFuncDefs; 
    findCandidateFunctionDefinitions (project, candidateFuncDefs);
    normalizeLoops (candidateFuncDefs);

    //Prepare liveness analysis etc.
    //Too much output for analysis debugging info.
    //initialize_analysis (project,enable_debug);   
    initialize_analysis (project, false);   

    // This is a bit redundant with findCandidateFunctionDefinitions ()
    // But we do need the per file control to decide if omp.h is needed for each file
    //
    // For each source file in the project
    SgFilePtrList & ptr_list = project->get_fileList();
    for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
        iter++)
    {
      SgFile* sageFile = (*iter);
      SgSourceFile * sfile = isSgSourceFile(sageFile);
      ROSE_ASSERT(sfile);
      SgGlobal *root = sfile->get_globalScope();

      Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); 
      bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

      //For each function body in the scope
      //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
      for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) 
      {

        //      cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl;

        SgFunctionDefinition *defn = isSgFunctionDefinition(*p);
        ROSE_ASSERT (defn != NULL);

        SgFunctionDeclaration *func = defn->get_declaration();
        ROSE_ASSERT (func != NULL);

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

        SgBasicBlock *body = defn->get_body();  
        // For each loop 
        Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); 
        if (loops.size()==0) 
        {
          if (enable_debug)
            cout<<"\t skipped since no for loops are found in this function"<<endl;
          continue;
        }

#if 0 // Moved to be executed before running liveness analysis.
        // normalize C99 style for (int i= x, ...) to C89 style: int i;  (i=x, ...)
        // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug
        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin();
            iter!= loops.end(); iter++ )
        {
          SgForStatement* cur_loop = isSgForStatement(*iter);
          ROSE_ASSERT(cur_loop);
          SageInterface::normalizeForLoopInitDeclaration(cur_loop);
        }
#endif
        // X. Replace operators with their equivalent counterparts defined 
        // in "inline" annotations
        AstInterfaceImpl faImpl_1(body);
        CPPAstInterface fa_body(&faImpl_1);
        OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body));

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

        //FR(06/07/2011): aliasinfo was not set which caused segfault
        LoopTransformInterface::set_aliasInfo(&array_interface);

        for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); 
            iter!= loops.end(); iter++ ) 
        {
          SgNode* current_loop = *iter;

          if (enable_debug)
          {
            SgForStatement * fl = isSgForStatement(current_loop);
            cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl;
          }
          //X. Parallelize loop one by one
          // getLoopInvariant() will actually check if the loop has canonical forms 
          // which can be handled by dependence analysis
          SgInitializedName* invarname = getLoopInvariant(current_loop);
          if (invarname != NULL)
          {
            bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot);
            if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file.
              hasOpenMP = true;  
          }
          else // cannot grab loop index from a non-conforming loop, skip parallelization
          {
            if (enable_debug)
              cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl;
            // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be.  
            //hasOpenMP = false;
          }
        }// end for loops
      } // end for-loop for declarations

      // insert omp.h if needed
      if (hasOpenMP && !enable_diff)
      {
        SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root);
        if (enable_patch)
          generatePatchFile(sfile); 
      }
      // compare user-defined and compiler-generated OmpAttributes
      if (enable_diff)
        diffUserDefinedAndCompilerGeneratedOpenMP(sfile); 
    } //end for-loop of files

#if 1
    // undo loop normalization
    std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin();
    for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) 
    {
      SgForStatement* for_loop = (*iter).first; 
      unnormalizeForLoopInitDeclaration (for_loop);
    }
#endif
    // Qing's loop normalization is not robust enough to pass all tests
    //AstTests::runAllTests(project);


    // clean up resources for analyses
    release_analysis();
  }

label_end: 
  // Report errors
  if (keep_going)
  {
    std::vector<std::string> orig_rose_cmdline(argv, argv+argc);
    Rose::KeepGoing::generate_reports (project, orig_rose_cmdline);
  }

  //project->unparse();
  return backend (project);
}
void
FunctionCallNormalization::visit( SgNode *astNode )
   {
     SgStatement *stm = isSgStatement( astNode );

     // visiting all statements which may contain function calls;
     // Note 1: we do not look at the body of loops, or sequences of statements, but only
     // at statements which may contain directly function calls; all other statements will have their component parts visited in turn
     if ( isSgEnumDeclaration( astNode ) || isSgVariableDeclaration( astNode ) || isSgVariableDefinition( astNode ) ||
                               isSgExprStatement( astNode ) || isSgForStatement( astNode ) || isSgReturnStmt( astNode ) ||
                               isSgSwitchStatement( astNode ) )
        {
       // maintain the mappings from function calls to expressions (variables or dereferenced variables)
          map<SgFunctionCallExp *, SgExpression *> fct2Var;

       // list of Declaration structures, one structure per function call
          DeclarationPtrList declarations;
          bool variablesDefined = false;
             
       // list of function calls, in correnspondence with the inForTest list below
          list<SgNode*> functionCallExpList;
          list<bool> inForTest;

          SgForStatement *forStm = isSgForStatement( stm );
          SgSwitchStatement *swStm = isSgSwitchStatement( stm );
          list<SgNode*> temp1, temp2;

       // for-loops and Switch statements have conditions ( and increment ) expressed as expressions
       // and not as standalone statements; this will change in future Sage versions
       // TODO: when for-loops and switch statements have conditions expressed via SgStatements
       // these cases won't be treated separately; however, do-while will have condition expressed via expression
       // so that will be the only exceptional case to be treated separately
          if (forStm != NULL)
             {
            // create a list of function calls in the condition and increment expression
            // the order is important, the condition is evaluated after the increment expression
            // temp1 = FEOQueryForNodes( forStm->get_increment_expr_root(), V_SgFunctionCallExp );
            // temp2 = FEOQueryForNodes( forStm->get_test_expr_root(), V_SgFunctionCallExp );
               temp1 = FEOQueryForNodes( forStm->get_increment(), V_SgFunctionCallExp );
               temp2 = FEOQueryForNodes( forStm->get_test_expr(), V_SgFunctionCallExp );
               functionCallExpList = temp1;
               functionCallExpList.splice( functionCallExpList.end(), temp2 );
             }
            else
             {
               if (swStm != NULL)
                  {
                 // create a list of function calls in the condition in the order of function evaluation
                 // DQ (11/23/2005): Fixed SgSwitchStmt to have SgStatement for conditional.
                 // list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector_root(), V_SgFunctionCallExp );
                    list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector(), V_SgFunctionCallExp );
                    functionCallExpList = temp1;
                  }
                 else
                  {
                 // create a list of function calls in the statement in the order of function evaluation
                    functionCallExpList = FEOQueryForNodes( stm, V_SgFunctionCallExp );
                  }
             }

         // all function calls get replaced: this is because they can occur in expressions (e.g. for-loops)
         // which makes it difficult to build control flow graphs
         if ( functionCallExpList.size() > 0 )
           {
             cout << "--------------------------------------\nStatement ";
             cout << stm->unparseToString() << "\n";;
             
             // traverse the list of function calls in the current statement, generate a structure  Declaration for each call
             // put these structures in a list to be inserted in the code later
             for ( list<SgNode *>::iterator i = functionCallExpList.begin(); i != functionCallExpList.end(); i++ )
               {
                 variablesDefined = true;

                 // get function call exp
                 SgFunctionCallExp *exp = isSgFunctionCallExp( *i );
                 ROSE_ASSERT ( exp );
                 
                 // get type of expression, generate unique variable name
                 SgType *expType = exp->get_type();
                 ROSE_ASSERT ( expType );
                 Sg_File_Info *location = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 ROSE_ASSERT ( location );
                 ostringstream os;
                 os << "__tempVar__" << location;
                 SgName name = os.str().c_str();

                 // replace previous variable bindings in the AST
                 SgExprListExp *paramsList = exp->get_args();
                 SgExpression *function = exp->get_function();
                 ROSE_ASSERT ( paramsList && function );
                 replaceFunctionCallsInExpression( paramsList, fct2Var );
                 replaceFunctionCallsInExpression( function, fct2Var );

                 // duplicate function call expression, for the initialization declaration and the assignment
                 SgTreeCopy treeCopy;
                 SgFunctionCallExp *newExpInit = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpInit );
                 SgFunctionCallExp *newExpAssign = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpAssign );

                 // variables
                 Sg_File_Info *initLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *nonInitLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *assignLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 Declaration *newDecl = new Declaration();
                 SgStatement *nonInitVarDeclaration, *initVarDeclaration, *assignStmt;
                 SgExpression *varRefExp;
                 SgVariableSymbol *varSymbol;
                 SgAssignOp *assignOp;
                 SgInitializedName *initName;

                 bool pointerTypeNeeded = false;

                 // mark whether to replace inside or outside of ForStatement due to the
                 // function call being inside the test or the increment for a for-loop statement
                 // the 'inForTest' list is in 1:1  ordered correpondence with the 'declarations' list
                 if ( forStm )
                   {
        // SgExpressionRoot
                  //   *testExp = isSgForStatement( astNode )->get_test_expr_root(),
                  //   *incrExp = isSgForStatement( astNode )->get_increment_expr_root();
                     SgExpression
                       *testExp = isSgForStatement( astNode )->get_test_expr(),
                       *incrExp = isSgForStatement( astNode )->get_increment();
                     SgNode *up = exp;
                     while ( up && up != testExp && up != incrExp )
                       up = up->get_parent();
                     ROSE_ASSERT ( up );

                     // function call is in the condition of the for-loop
                     if ( up == testExp )
                       inForTest.push_back( true );
                     // function call is in the increment expression
                     else
                       {
                         inForTest.push_back( false );

                         // for increment expressions we need to be able to reassign the return value
                         // of the function; if the ret value is a reference, we need to generate a
                         // pointer of that type (to be able to reassign it later)
                         if ( isSgReferenceType( expType ) )
                           pointerTypeNeeded = true;
                       }
                   }

                 // for do-while statements:  we need to generate declaration of type pointer to be able to have
                 // non-assigned references when looping and assign them at the end of the body of the loop
                 if ( isSgDoWhileStmt( stm->get_parent() ) && isSgReferenceType( expType ) )
                   pointerTypeNeeded = true;

                 // we have a function call returning a reference and we can't initialize the variable
                 // at the point of declaration; we need to define the variable as a pointer
                 if ( pointerTypeNeeded )
                   {
                     // create 'address of' term for function expression, so we can assign it to the pointer
                     SgAddressOfOp *addressOp = new SgAddressOfOp( assignLoc, newExpAssign, expType );

                     // create noninitialized declaration
                     SgType *base = isSgReferenceType( expType )->get_base_type();
                     ROSE_ASSERT( base );
                     SgPointerType *ptrType = SgPointerType::createType( isSgReferenceType( expType )->get_base_type() );
                     ROSE_ASSERT ( ptrType );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, ptrType );

                     // create assignment (symbol, varRefExp, assignment)
                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );

                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );

                     SgPointerDerefExp *ptrDeref= new SgPointerDerefExp( assignLoc, varRefExp, expType );
                     ROSE_ASSERT ( isSgExpression( varRefExp ) && ptrDeref );
                     assignOp = new SgAssignOp( assignLoc, varRefExp, addressOp, ptrType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt &&  nonInitVarDeclaration );
           
                     // we don't need initialized declarations in this case
                     initVarDeclaration = NULL;

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, ptrDeref ) );
                   }
                 else
                   {
                     // create (non- &)initialized declarations, initialized name & symbol
                     SgAssignInitializer *declInit = new SgAssignInitializer( initLoc, newExpInit, expType );
                     ROSE_ASSERT ( declInit );
                     initVarDeclaration = new SgVariableDeclaration ( initLoc, name, expType, declInit );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, expType );
                     ROSE_ASSERT ( initVarDeclaration && nonInitVarDeclaration );

                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );
                     newExpInit->set_parent( initName );
                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );

                     // create variable ref exp
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );
                     ROSE_ASSERT ( isSgVarRefExp( varRefExp ) );

                     // create the assignment
                     assignOp = new SgAssignOp( assignLoc, varRefExp, newExpAssign, expType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt );

                     initVarDeclaration->set_parent( stm->get_parent() );
                     isSgVariableDeclaration( initVarDeclaration )->set_definingDeclaration( isSgDeclarationStatement( initVarDeclaration ) );

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, varRefExp ) );
                   }

                 // save the 'declaration' structure, with all 3 statements and the variable name
                 newDecl->nonInitVarDeclaration = nonInitVarDeclaration;
                 newDecl->initVarDeclaration = initVarDeclaration;
                 newDecl->assignment = assignStmt;
                 newDecl->name = name;
                 nonInitVarDeclaration->set_parent( stm->get_parent() );
                 isSgVariableDeclaration( nonInitVarDeclaration )->set_definingDeclaration( isSgVariableDeclaration( nonInitVarDeclaration ) );
                 assignStmt->set_parent( stm->get_parent() );
                 declarations.push_back( newDecl );
               } // end for
           } // end if  fct calls in crt stmt > 1

         SgScopeStatement *scope = stm->get_scope();
         ROSE_ASSERT ( scope );
         
         // insert function bindings to variables; each 'declaration' structure in the list
         // corresponds to one function call
         for ( DeclarationPtrList::iterator i = declarations.begin(); i != declarations.end(); i++ )
           {
             Declaration *d = *i;
             ROSE_ASSERT ( d && d->assignment && d->nonInitVarDeclaration );

             // if the current statement is a for-loop, we insert Declarations before & in the loop body, depending on the case
             if ( forStm )
               {
                 SgStatement *parentScope = isSgStatement( stm->get_scope() );
                 SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfFor(forStm);
                 ROSE_ASSERT ( !inForTest.empty() && body && parentScope );
                 // SgStatementPtrList &list = body->get_statements();

                 // if function call is in loop condition, we add initialized variable before the loop and at its end
                 // hoist initialized variable declarations outside the loop
                 if ( inForTest.front() )
                   {
                     ROSE_ASSERT ( d->initVarDeclaration );
                     parentScope->insert_statement( stm, d->initVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
                 // function call is in loop post increment so add noninitialized variable decls above the loop
                 else
                   {
                     parentScope->insert_statement( stm, d->nonInitVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }

                 // in a for-loop, always insert assignments at the end of the loop
                 body->get_statements().push_back( d->assignment );
                 d->assignment->set_parent( body );

                 // remove marker
                 inForTest.pop_front();
               }
             else
               {
                 // look at the type of the enclosing scope
                 switch ( scope->variantT() )
                   {

                     // while stmts have to repeat the function calls at the end of the loop;
                     // note there is no "break" statement, since we want to also add initialized
                     // declarations before the while-loop
                   case V_SgWhileStmt:
                     {
                       // assignments need to be inserted at the end of each while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfWhile(isSgWhileStmt( scope ) );
                       ROSE_ASSERT ( body );
                       d->assignment->set_parent( body );
                       body->get_statements().push_back( d->assignment );
                     }

                     // SgForInitStatement has scope SgForStatement, move declarations before the for loop;
                     // same thing if the enclosing scope is an If, or Switch statement
                   case V_SgForStatement:
                   case V_SgIfStmt:
                   case V_SgSwitchStatement:
                     {
                       // adding bindings (initialized variable declarations only, not assignments)
                       // outside the statement, in the parent scope
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->initVarDeclaration, true );\

                       // setting the scope of the initializedName
                       SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );
                     }
                     break;

                     // do-while needs noninitialized declarations before the loop, with assignments inside the loop
                   case V_SgDoWhileStmt:
                     {
                       // adding noninitialized variable declarations before the body of the loop
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->nonInitVarDeclaration, true );

                       // initialized name scope setting
                       SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );

                       // adding assignemts at the end of the do-while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfDoWhile( isSgDoWhileStmt(scope) );
                       ROSE_ASSERT ( body );
                       body->get_statements().push_back( d->assignment );
                       d->assignment->set_parent(body);
                     }
                     break;

                     // for all other scopes, add bindings ( initialized declarations ) before the statement, in the same scope
                   default:
                     scope->insert_statement( stm, d->initVarDeclaration, true );

                     // initialized name scope setting
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( scope->get_scope() );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
               }
           }
         
         // once we have inserted all variable declarations, we need to replace top-level calls in the original statement
         if ( variablesDefined )
           {
             cout << "\tReplacing in the expression " << stm->unparseToString() << "\n";

             // for ForStatements, replace expressions in condition and increment expressions,
             // not in the body, since those get replace later
             if ( forStm )
               {
         // SgExpressionRoot *testExp = forStm->get_test_expr_root(), *incrExp = forStm->get_increment_expr_root();
            SgExpression *testExp = forStm->get_test_expr(), *incrExp = forStm->get_increment();
            replaceFunctionCallsInExpression( incrExp, fct2Var );
            replaceFunctionCallsInExpression( testExp, fct2Var );
               }
             else
               if ( swStm )
             {
            // DQ (11/23/2005): Fixed SgSwitch to permit use of declaration for conditional
            // replaceFunctionCallsInExpression( swStm->get_item_selector_root(), fct2Var );
               replaceFunctionCallsInExpression( swStm->get_item_selector(), fct2Var );
             }
               else
             replaceFunctionCallsInExpression( stm, fct2Var );
           }
       } // end if isSgStatement block
   }
/** Visits AST nodes in pre-order */
FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute)
{
    FunctionCallInheritedAttribute result = parentAttribute;
    SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope);
    SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope);
    SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope);
    
    SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL;
    SgAndOp* parentAndOp =  astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL;
    SgOrOp* parentOrOp =  astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL;

    if (isSgForStatement(astNode))
        result.currentScope = isSgForStatement(astNode);
    else if (isSgWhileStmt(astNode))
        result.currentScope = isSgWhileStmt(astNode);
    else if (isSgDoWhileStmt(astNode))
        result.currentScope = isSgDoWhileStmt(astNode);
    //else if (isSgConditionalExp(astNode))
    //    result.currentScope = isSgConditionalExp(astNode);
    //else if (isSgAndOp(astNode))
    //    result.currentScope = isSgAndOp(astNode);
    //else if (isSgOrOp(astNode))
    //    result.currentScope = isSgOrOp(astNode);
    else if (isSgForInitStatement(astNode)) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT;
        ROSE_ASSERT(isSgForStatement(result.currentScope));
    } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST;
    } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT;
    } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION;
    } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION;
    } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM;
    } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM;
    } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS;
    } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode)  {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS;
    }
    
    //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc.
    if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) {
        //We can't insert a variable declaration at these locations. Use the parent statement
    } else if (isSgStatement(astNode)) {
        result.lastStatement = isSgStatement(astNode);
    }

    return result;
}
예제 #21
0
in_list
blockObjectsAllocated(SgStatement *block, SgStatement *stop)
   {
     in_list objs;
     ROSE_ASSERT(block);
     switch (block->variantT())
        {
          case V_SgBasicBlock:
                {
                  SgBasicBlock *b = isSgBasicBlock(block);
                  ROSE_ASSERT(b);
                  
                  SgNode *parent = block->get_parent();
                  if (SgForStatement *fs = isSgForStatement(parent))
                     {
                        addStmtVarsIfAny(objs, fs->get_test());
                     }
                  else if (SgWhileStmt *ws = isSgWhileStmt(parent))
                     {
                       addStmtVarsIfAny(objs, ws->get_condition());
                     }
                  else if (SgIfStmt *is = isSgIfStmt(parent))
                     {
                       addStmtVarsIfAny(objs, is->get_conditional());

                       if (IsSCGenerated(is))
                          {
                            FindTemporaries ft(objs);
                            ft.traverse(is->get_conditional(), preorder);

                            if (b->get_statements().size() > 1)
                               {
                              // the first statement is the left conjunct of a ,
                              // expression... grab temporaries from this as well
                                 ft.traverse(b->get_statements().front(), preorder);
                               }
                          }
                     }

                  SgStatementPtrList &stmts = b->get_statements();
                  for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                     {
                       if (*i == stop) break;
                       addStmtVarsIfAny(objs, *i);
                     }
                }
             break;
          case V_SgForStatement:
                {
                  SgForStatement *fs = isSgForStatement(block);
                  SgStatementPtrList &stmts = fs->get_init_stmt();
                  for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                     {
                       if (*i == stop)
                          {
                            break;
                          }
                       addStmtVarsIfAny(objs, *i);
                     }
               // addStmtVarsIfAny(objs, fs->get_test());
                }
             break;
          default:
             break;
        }
     return objs;
   }
예제 #22
0
파일: parallelSTLQuery.C 프로젝트: 8l/rose
// Functions required by the tree traversal mechanism
ParallelContainerQueryInheritedAttribute
ParallelContainerQueryTraversal::evaluateInheritedAttribute (
     SgNode* astNode,
     ParallelContainerQueryInheritedAttribute inheritedAttribute )
   {
     traversalNodeCounter++;

  // printf ("In evaluateInheritedAttribute: (astNode->sage_class_name() = %s) \n",astNode->sage_class_name());

     ROSE_ASSERT (containerInfoList != NULL);
     ROSE_ASSERT (containerInfoList->size() > 0);

     switch(astNode->variantT())
        {
          case V_SgForStatement:
             {
            // printf ("Found the SgForStatement \n");
               inheritedAttribute.inForStatement = true;
               break;
             }

          case V_SgForInitStatement:
             {
            // printf ("Found the SgForInitStatement \n");
               if (inheritedAttribute.inForStatement == true)
                    inheritedAttribute.inInitializer = true;
               break;
             }

          case V_SgExpressionRoot:
             {
            // printf ("Found an expression node (inheritedAttribute.inForStatement = %s) \n",
            //      (inheritedAttribute.inForStatement) ? "true" : "false");
               if (inheritedAttribute.inForStatement == true)
                  {
                 // printf ("The parent is a SgForStatement \n");
                    SgNode* parentForStatement = NULL;
                    SgNode* parent = astNode;
                    while (parentForStatement == NULL)
                       {
                      // printf ("Searching for the parent SgForStatement (node = %s) \n",parent->sage_class_name());
                         ROSE_ASSERT (parent != NULL);
                         parentForStatement = isSgForStatement(parent->get_parent());
                         parent = parent->get_parent();
                       }
                    ROSE_ASSERT (parentForStatement != NULL);

                    SgForStatement* forStatement = isSgForStatement(parentForStatement);

                    ROSE_ASSERT (forStatement != NULL);

                 // Of course we are in a for loop (but check just to make sure)
                 // ROSE_ASSERT (inheritedAttribute.inForStatement == true);

                 // Using the parent node see which expression node we 
                 // are in this invocation of evaluateInheritedAttribute
                    if (astNode == forStatement->get_test_expr_root())
                       {
                      // printf ("Found the test expression \n");
                         inheritedAttribute.inTestExpression = true;
                       }
                      else
                       {
                         if (astNode == forStatement->get_increment_expr_root())
                            {
                           // printf ("Found the increment expression \n");
                              inheritedAttribute.inIncrementExpression = true;
                            }
                       }
                  }
               break;
             }

          case V_SgBasicBlock:
             {
               if (inheritedAttribute.inForStatement == true)
                  {
                 // printf ("Found the Basic Block in the for loop \n");
                    inheritedAttribute.inLoopBody = true;
                  }
               break;
             }

       // DQ (11/28/2005): Added default case to avoid compiler warnings
          default:
             {
             }
        }

     return inheritedAttribute;
   }
예제 #23
0
파일: traceCPU.C 프로젝트: 8l/rose
static void CreateLoopProbe(SgFunctionDeclaration *funcDecl, SgBasicBlock *funcBody,
                            SgStatement *stmt, int *loopCount)
{
   SgExpression *lb ;
   SgExpression *ub ;
   SgExpression *step ;
   bool isCanonicalFor = SageInterface::isCanonicalForLoop(stmt, NULL, &lb, &ub, &step) ;

   /* generate loop segment, and iteration information if requested */
   if (countIters && !isCanonicalFor) {
      Sg_File_Info *fileInfo = stmt->get_startOfConstruct() ;
      printf("Non-canonical loop in %s:::%s at line %d\n",
             fileInfo->get_filenameString().c_str(),
             funcDecl->get_name().str(), fileInfo->get_line()) ;
   }
   else
   {
      SgExpression *its = NULL ;
      if (countIters && isCanonicalFor) {
         bool isDecreasing = false ;
         bool adjustBound = false ;

         SgExpression *high ;
         SgExpression *max ;
         SgExpression *minuend ;
         SgExpression *subtrahend ;

         SgExpression *tmp ;
         SgForStatement* fs = isSgForStatement(stmt) ;
         ROSE_ASSERT(fs) ;
         SgBinaryOp* test = isSgBinaryOp(fs->get_test_expr());
         ROSE_ASSERT(test) ;
         switch (test->variantT())
         {
           case V_SgLessOrEqualOp:
             adjustBound = true ;
           case V_SgLessThanOp:
             break;
           case V_SgGreaterOrEqualOp:
             adjustBound = true ;
           case V_SgGreaterThanOp:
//           tmp = lb ;
//           lb = ub ;
//           ub = tmp ;
             isDecreasing = true ;
             break;
//         case V_SgNotEqualOp: // Do we really want to allow this != operator ?
//           break;
           default:
             /* do nothing */ ;
         }

         if (adjustBound)
         {
            high = buildAddOp(SageInterface::copyExpression(ub),
                              buildIntVal(isDecreasing ? -1 : 1)) ;
         }
         else
         {
            high = SageInterface::copyExpression(ub) ;
         }

         /* if step != const 1, we need to adjust high */
         if (!(isSgIntVal(step) && (isSgIntVal(step)->get_value() == 1))) {
            max = buildAddOp(high,
                             buildSubtractOp(SageInterface::copyExpression(step), buildIntVal(1))) ;
         }
         else {
            max = high ;
         }

         minuend    = max ;
         subtrahend = SageInterface::copyExpression(lb) ;
#if 0
         if (isDecreasing)
         {
            SgExpression *tmp ;
            tmp = minuend ;
            minuend = subtrahend ;
            subtrahend = tmp ;
         }
#endif

         /* The control logic is purely to clean up the output, since */
         /* the compiler can do a fine job of folding integer constansts */

         its = buildDivideOp(buildSubtractOp(minuend, subtrahend),
                             SageInterface::copyExpression(step)) ;
#if 0
         if (!(isSgIntVal(step) && (isSgIntVal(step)->get_value() == 1))) {
            its = buildDivideOp(buildSubtractOp(minuend, subtrahend),
                                SageInterface::copyExpression(step)) ;
         }
         else {
            if (!(isSgIntVal(subtrahend) &&
                  (isSgIntVal(subtrahend)->get_value() == 0))) {
               its = buildSubtractOp(minuend, subtrahend) ;
            }
            else {
               its = minuend ;
            }
         }
#endif
       }

       /* start loop code fragment */
       SgVariableDeclaration *loopDecl =
         ET_BuildDecl(funcBody, "ET_loop", *loopCount, ETtype, true) ;

       RegisterItem(funcDecl, funcBody, stmt,
                    "ET_RegisterLoop", ETtype, loopDecl, true) ;
       HandleItem(funcBody, stmt, "ET_PushLoopSeqId", buildVarRefExp(loopDecl), true) ;

       /* end loop code fragment */
       HandleItem(funcBody, stmt, "ET_PopLoopSeqId", its, false) ;

       ++(*loopCount) ;
   }
}
예제 #24
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;
}