// Override Statements which includes expressions and more
bool HostProgramTuning::VisitStmt(Stmt *s)
{
	if (isa<IfStmt>(s))
	{
		// Cast s to IfStmt to access the then and else clauses
		IfStmt *If = cast<IfStmt>(s);
		Stmt *TH = If->getThen();

		// Add braces if needed to then clause
		InstrumentStmt(TH);

		Stmt *EL = If->getElse();
		if (EL)
		{
			// Add braces if needed to else clause
			InstrumentStmt(EL);
		}
	}
	else
		if (isa<WhileStmt>(s))
		{
			WhileStmt *While = cast<WhileStmt>(s);
			Stmt *BODY = While->getBody();
			InstrumentStmt(BODY);
		}
		else
			if (isa<ForStmt>(s))
			{
				ForStmt *For = cast<ForStmt>(s);
				Stmt *BODY = For->getBody();
				InstrumentStmt(BODY);
			}

	return true; // returning false aborts the traversal
}
Exemple #2
0
void CodeGenFunction::EmitForStmt(const ForStmt &S) {
  // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
  // which contains a continue/break?

  // Evaluate the first part before the loop.
  if (S.getInit())
    EmitStmt(S.getInit());

  // Start the loop with a block that tests the condition.
  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");

  EmitBlock(CondBlock);

  // Evaluate the condition if present.  If not, treat it as a
  // non-zero-constant according to 6.8.5.3p2, aka, true.
  if (S.getCond()) {
    // As long as the condition is true, iterate the loop.
    llvm::BasicBlock *ForBody = createBasicBlock("for.body");
    
    // C99 6.8.5p2/p4: The first substatement is executed if the expression
    // compares unequal to 0.  The condition must be a scalar type.
    EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor);
    
    EmitBlock(ForBody);    
  } else {
    // Treat it as a non-zero constant.  Don't even create a new block for the
    // body, just fall into it.
  }

  // If the for loop doesn't have an increment we can just use the 
  // condition as the continue block.
  llvm::BasicBlock *ContinueBlock;
  if (S.getInc())
    ContinueBlock = createBasicBlock("for.inc");
  else
    ContinueBlock = CondBlock;  
  
  // Store the blocks to use for break and continue.
  BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));

  // If the condition is true, execute the body of the for stmt.
  EmitStmt(S.getBody());

  BreakContinueStack.pop_back();
  
  // If there is an increment, emit it next.
  if (S.getInc()) {
    EmitBlock(ContinueBlock);
    EmitStmt(S.getInc());
  }
      
  // Finally, branch back up to the condition for the next iteration.
  EmitBranch(CondBlock);

  // Emit the fall-through block.
  EmitBlock(AfterFor, true);
}
    bool VisitForStmt(ForStmt *parentStmt)
    {
        Stmt *bodyStmt = parentStmt->getBody();
        ForStmt *forStmt = dyn_cast_or_null<ForStmt>(bodyStmt);
        CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(bodyStmt);
        if (!forStmt && compoundStmt && compoundStmt->size() == 1)
        {
            forStmt = dyn_cast_or_null<ForStmt>(compoundStmt->body_back());
        }
        if (forStmt)
        {
            Stmt *initStmt = parentStmt->getInit();
            Expr *incExpr = forStmt->getInc();
            if (isInnerIncMatchingOuterInit(incExpr, initStmt))
            {
                addViolation(incExpr, this);
            }
        }

        return true;
    }
  bool VisitFunctionDecl(FunctionDecl *f) {
    // Only function definitions (with bodies), not declarations.
    if (f->hasBody()) {
      Stmt *FuncBody = f->getBody();

      // Type name as string
      QualType QT = f->getReturnType();
      std::string TypeStr = QT.getAsString();

      // Function name
      DeclarationName DeclName = f->getNameInfo().getName();
      std::string FuncName = DeclName.getAsString();

      // Add comment before
      std::stringstream SSBefore;
      SSBefore << "// Begin function " << FuncName << " returning " << TypeStr
               << "\n";
      SourceLocation ST = f->getSourceRange().getBegin();
      TheRewriter.InsertText(ST, SSBefore.str(), true, true);

      // And after
      std::stringstream SSAfter;
      SSAfter << "\n// End function " << FuncName;
      ST = FuncBody->getLocEnd().getLocWithOffset(1);
      TheRewriter.InsertText(ST, SSAfter.str(), true, true);
      
      int forCounter=0;
    Stmt::child_iterator CI, CE = FuncBody->child_end();
    for (CI = FuncBody->child_begin(); CI != CE; ++CI) {
      if (*CI != 0) {
        if (isa<ForStmt>(*CI)) 
        {
            forCounter++;
            std::stringstream MarkerBefore;
            std::stringstream MarkerAfter;
            MarkerBefore<<"\nMCPROF_ZONE_ENTER(" << forCounter << ");\n";
            MarkerAfter<<"\nMCPROF_ZONE_EXIT(" << forCounter << ");\n";
            ForStmt *For = cast<ForStmt>(*CI);
            SourceLocation ST = For->getLocStart();
            TheRewriter.InsertText(ST, MarkerBefore.str(), true, false);
            Stmt *ForBody = For->getBody();
            SourceLocation END = ForBody->getLocEnd();
            int offset = Lexer::MeasureTokenLength(END,
                                        TheRewriter.getSourceMgr(),
                                        TheRewriter.getLangOpts()) + 1;

            SourceLocation END1 = END.getLocWithOffset(offset);
            TheRewriter.InsertText(END1, MarkerAfter.str(), true, false);

//          llvm::errs() << " Detected for loop number " << forCounter 
//                       << " in function " << FuncName << "\n";

//             InstrumentStmt(ForBody);

//             Stmt *ForBody = CI->getBody();
//             SourceLocation ST = CI->getLocStart();
//             char *b = sourceManager->getCharacterData(_b)
//             llvm::errs()  << ST << " is location \n";
        }
      }
    }

    }

    return true;
  }