[llvm-commits] [llvm] r81338 - /llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp

Andreas Neustifter astifter-llvm at gmx.at
Wed Sep 9 06:01:04 PDT 2009


Author: astifter
Date: Wed Sep  9 08:01:03 2009
New Revision: 81338

URL: http://llvm.org/viewvc/llvm-project?rev=81338&view=rev
Log:
Fixed wrong storage option for ProfileVerifierDisableAssertions.
Fixed non working -profile-verifier-noassert option.
Fixed missing newline in debugEntry().
Cleaned up assert messages. (assert(0 && Message) is still shown, but the message is printed before.)
When verifiying loaded profiles the ProfileVerifier got confused when block was a setjmp target, this is checked now.
When verifiying loaded profiles the ProfileVerifier got confused when block eventually reaching an exit(), this is checked now.

Modified:
    llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp

Modified: llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp?rev=81338&r1=81337&r2=81338&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp (original)
+++ llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp Wed Sep  9 08:01:03 2009
@@ -12,16 +12,20 @@
 //
 //===----------------------------------------------------------------------===//
 #define DEBUG_TYPE "profile-verifier"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/ProfileInfo.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CallSite.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Support/InstIterator.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Debug.h"
 #include <set>
 using namespace llvm;
 
-static cl::opt<bool,true>
+static cl::opt<bool,false>
 ProfileVerifierDisableAssertions("profile-verifier-noassert",
      cl::desc("Disable assertions"));
 
@@ -39,6 +43,7 @@
 
     ProfileInfo *PI;
     std::set<const BasicBlock*> BBisVisited;
+    std::set<const Function*>   FisVisited;
     bool DisableAssertions;
 
     // When debugging is enabled, the verifier prints a whole slew of debug
@@ -52,8 +57,11 @@
   public:
     static char ID; // Class identification, replacement for typeinfo
 
-    explicit ProfileVerifierPass (bool da = false) : FunctionPass(&ID), 
-                                                     DisableAssertions(da) {
+    explicit ProfileVerifierPass () : FunctionPass(&ID) {
+      DisableAssertions = ProfileVerifierDisableAssertions;
+    }
+    explicit ProfileVerifierPass (bool da) : FunctionPass(&ID), 
+                                             DisableAssertions(da) {
     }
 
     void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -67,8 +75,9 @@
 
     /// run - Verify the profile information.
     bool runOnFunction(Function &F);
-    void recurseBasicBlock(const BasicBlock *BB);
+    void recurseBasicBlock(const BasicBlock*);
 
+    bool   exitReachable(const Function*);
     double ReadOrAssert(ProfileInfo::Edge);
     void   CheckValue(bool, const char*, DetailedBlockInfo*);
   };
@@ -96,10 +105,10 @@
   for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
         bbi != bbe; ++bbi ) {
     if (ProcessedPreds.insert(*bbi).second) {
-      double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
+      ProfileInfo::Edge E = PI->getEdge(*bbi,BB);
+      double EdgeWeight = PI->getEdgeWeight(E);
       if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
-      errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
-            <<"): "<<EdgeWeight<<"\n";
+      errs() << "calculated in-edge " << E << ": " << EdgeWeight << "\n";
       inWeight += EdgeWeight;
       inCount++;
     }
@@ -110,10 +119,10 @@
   for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
         bbi != bbe; ++bbi ) {
     if (ProcessedSuccs.insert(*bbi).second) {
-      double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
+      ProfileInfo::Edge E = PI->getEdge(BB,*bbi);
+      double EdgeWeight = PI->getEdgeWeight(E);
       if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
-      errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
-            <<"): "<<EdgeWeight<<"\n";
+      errs() << "calculated out-edge " << E << ": " << EdgeWeight << "\n";
       outWeight += EdgeWeight;
       outCount++;
     }
@@ -137,7 +146,7 @@
   errs() << "inWeight="  << DI->inWeight   << ",";
   errs() << "inCount="   << DI->inCount    << ",";
   errs() << "outWeight=" << DI->outWeight  << ",";
-  errs() << "outCount="  << DI->outCount   << ",";
+  errs() << "outCount="  << DI->outCount   << "\n";
   if (!PrintedDebugTree) {
     PrintedDebugTree = true;
     printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
@@ -158,30 +167,50 @@
   return false; 
 }
 
+bool ProfileVerifierPass::exitReachable(const Function *F) {
+  if (!F) return false;
+
+  if (FisVisited.count(F)) return false;
+
+  Function *Exit = F->getParent()->getFunction("exit");
+  if (Exit == F) {
+    return true;
+  }
+
+  FisVisited.insert(F);
+  bool exits = false;
+  for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+    if (const CallInst *CI = dyn_cast<CallInst>(&*I)) {
+      exits |= exitReachable(CI->getCalledFunction());
+      if (exits) break;
+    }
+  }
+  return exits;
+}
+
+#define ASSERTMESSAGE(M) \
+    errs() << (M) << "\n"; \
+    if (!DisableAssertions) assert(0 && (M));
+
 double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) {
-  const char *Message = "ASSERT:Edge has missing value";
   double EdgeWeight = PI->getEdgeWeight(E);
   if (EdgeWeight == ProfileInfo::MissingValue) {
-    if (DisableAssertions) {
-      errs() << Message << "\n";
-      return 0;
-    } else { 
-      assert(0 && Message);
-      return 0;
-    }
+    errs() << "Edge " << E << " in Function " 
+           << E.first->getParent()->getNameStr() << ": ";
+    ASSERTMESSAGE("ASSERT:Edge has missing value");
+    return 0;
   } else {
     return EdgeWeight;
   }
 }
 
-void ProfileVerifierPass::CheckValue(bool Error, const char *Message, DetailedBlockInfo *DI) {
+void ProfileVerifierPass::CheckValue(bool Error, const char *Message,
+                                     DetailedBlockInfo *DI) {
   if (Error) {
     DEBUG(debugEntry(DI));
-    if (DisableAssertions) {
-      errs() << Message << "\n";
-    } else { 
-      assert(0 && Message);
-    }
+    errs() << "Block " << DI->BB->getNameStr() << " in Function " 
+           << DI->BB->getParent()->getNameStr() << ": ";
+    ASSERTMESSAGE(Message);
   }
   return;
 }
@@ -194,8 +223,8 @@
   DI.BB = BB;
   DI.outCount = DI.inCount = DI.inWeight = DI.outWeight = 0;
   std::set<const BasicBlock*> ProcessedPreds;
-  for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
-        bbi != bbe; ++bbi ) {
+  for (pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
+       bbi != bbe; ++bbi) {
     if (ProcessedPreds.insert(*bbi).second) {
       DI.inWeight += ReadOrAssert(PI->getEdge(*bbi,BB));
       DI.inCount++;
@@ -203,8 +232,8 @@
   }
 
   std::set<const BasicBlock*> ProcessedSuccs;
-  for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
-        bbi != bbe; ++bbi ) {
+  for (succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
+       bbi != bbe; ++bbi) {
     if (ProcessedSuccs.insert(*bbi).second) {
       DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
       DI.outCount++;
@@ -212,15 +241,57 @@
   }
 
   DI.BBWeight = PI->getExecutionCount(BB);
-  CheckValue(DI.BBWeight == ProfileInfo::MissingValue, "ASSERT:BasicBlock has missing value", &DI);
+  CheckValue(DI.BBWeight == ProfileInfo::MissingValue,
+             "ASSERT:BasicBlock has missing value", &DI);
 
-  if (DI.inCount > 0) {
-    CheckValue(!Equals(DI.inWeight,DI.BBWeight), "ASSERT:inWeight and BBWeight do not match", &DI);
+  // Check if this block is a setjmp target.
+  bool isSetJmpTarget = false;
+  if (DI.outWeight > DI.inWeight) {
+    for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
+         i != ie; ++i) {
+      if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
+        Function *F = CI->getCalledFunction();
+        if (F && (F->getNameStr() == "_setjmp")) {
+          isSetJmpTarget = true; break;
+        }
+      }
+    }
   }
-  if (DI.outCount > 0) {
-    CheckValue(!Equals(DI.outWeight,DI.BBWeight), "ASSERT:outWeight and BBWeight do not match", &DI);
+  // Check if this block is eventually reaching exit.
+  bool isExitReachable = false;
+  if (DI.inWeight > DI.outWeight) {
+    for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
+         i != ie; ++i) {
+      if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
+        FisVisited.clear();
+        isExitReachable |= exitReachable(CI->getCalledFunction());
+        if (isExitReachable) break;
+      }
+    }
+  }
+
+  if (DI.inCount > 0 && DI.outCount == 0) {
+     // If this is a block with no successors.
+    if (!isSetJmpTarget) {
+      CheckValue(!Equals(DI.inWeight,DI.BBWeight), 
+                 "ASSERT:inWeight and BBWeight do not match", &DI);
+    }
+  } else if (DI.inCount == 0 && DI.outCount > 0) {
+    // If this is a block with no predecessors.
+    if (!isExitReachable)
+      CheckValue(!Equals(DI.BBWeight,DI.outWeight), 
+                 "ASSERT:BBWeight and outWeight do not match", &DI);
+  } else {
+    // If this block has successors and predecessors.
+    if (DI.inWeight > DI.outWeight && !isExitReachable)
+      CheckValue(!Equals(DI.inWeight,DI.outWeight), 
+                 "ASSERT:inWeight and outWeight do not match", &DI);
+    if (DI.inWeight < DI.outWeight && !isSetJmpTarget)
+      CheckValue(!Equals(DI.inWeight,DI.outWeight), 
+                 "ASSERT:inWeight and outWeight do not match", &DI);
   }
 
+
   // mark as visited and recurse into subnodes
   BBisVisited.insert(BB);
   for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB); 
@@ -233,7 +304,7 @@
   PI = &getAnalysis<ProfileInfo>();
 
   if (PI->getExecutionCount(&F) == ProfileInfo::MissingValue) {
-    DEBUG(errs()<<"Function "<<F.getNameStr()<<" has no profile\n");
+    DEBUG(errs() << "Function " << F.getNameStr() << " has no profile\n");
     return false;
   }
 





More information about the llvm-commits mailing list