Sprinkle some PrettyStackEntry magic into the passmanager. With this, we now
authorChris Lattner <sabre@nondot.org>
Fri, 6 Mar 2009 06:45:05 +0000 (06:45 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 6 Mar 2009 06:45:05 +0000 (06:45 +0000)
get nice and happy stack traces when we crash in an optimizer or codegen.  For
example, an abort put in UnswitchLoops now looks like this:

Stack dump:
0. Program arguments: clang pr3399.c -S -O3
1. <eof> parser at end of file
2. per-module optimization passes
3. Running pass 'CallGraph Pass Manager' on module 'pr3399.c'.
4. Running pass 'Loop Pass Manager' on function '@foo'
5. Running pass 'Unswitch loops' on basic block '%for.inc'
Abort

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66260 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/PassManagers.h
lib/Analysis/LoopPass.cpp
lib/VMCore/PassManager.cpp

index 2d68239e2aad5b50e76bcfa2a1ffb204e0a0404b..6e4f94697b99ff540137840f68cff9344be98216 100644 (file)
 // MPPassManagers.
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Support/PrettyStackTrace.h"
+
 namespace llvm {
+  class Pass;
+  class Value;
+  class Module;
 
 /// FunctionPassManager and PassManager, two top level managers, serve 
 /// as the public interface of pass manager infrastructure.
@@ -109,6 +114,24 @@ enum PassDebuggingString {
   ON_CG_MSG // "' on Call Graph ...\n'"
 };  
 
+/// PassManagerPrettyStackEntry - This is used 
+class PassManagerPrettyStackEntry : public PrettyStackTraceEntry {
+  Pass *P;
+  Value *V;
+  Module *M;
+public:
+  PassManagerPrettyStackEntry(Pass *p)
+    : P(p) {}  // When P is releaseMemory'd.
+  PassManagerPrettyStackEntry(Pass *p, Value &v)
+    : P(p), V(&v), M(0) {} // When P is run on V
+  PassManagerPrettyStackEntry(Pass *p, Module &m)
+    : P(p), V(0), M(&m) {}// When P is run on M
+  
+  /// print - Emit information about this stack frame to OS.
+  virtual void print(raw_ostream &OS) const;
+};
+  
+  
 //===----------------------------------------------------------------------===//
 // PMStack
 //
index c45c2ef4c0bb5819412f1e29de53140f96e76d9d..c4ff9889446da81dc5bdeb2b32e277b83e0916fa 100644 (file)
@@ -209,7 +209,6 @@ bool LPPassManager::runOnFunction(Function &F) {
 
     // Run all passes on current SCC
     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
-        
       Pass *P = getContainedPass(Index);
 
       dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, "");
@@ -217,11 +216,14 @@ bool LPPassManager::runOnFunction(Function &F) {
 
       initializeAnalysisImpl(P);
 
-      StartPassTimer(P);
       LoopPass *LP = dynamic_cast<LoopPass *>(P);
-      assert (LP && "Invalid LPPassManager member");
-      Changed |= LP->runOnLoop(CurrentLoop, *this);
-      StopPassTimer(P);
+      {
+        PassManagerPrettyStackEntry X(LP, *CurrentLoop->getHeader());
+        StartPassTimer(P);
+        assert(LP && "Invalid LPPassManager member");
+        Changed |= LP->runOnLoop(CurrentLoop, *this);
+        StopPassTimer(P);
+      }
 
       if (Changed)
         dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, "");
index c85a30933401a9a98cc1172f57b533f7de0309dd..174aa474dfb6e88a4bb921d11a1b1f83434262b2 100644 (file)
 #include "llvm/ModuleProvider.h"
 #include "llvm/Support/Streams.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm-c/Core.h"
 #include <algorithm>
 #include <cstdio>
-#include <vector>
 #include <map>
 using namespace llvm;
 
@@ -60,6 +60,40 @@ PassDebugging("debug-pass", cl::Hidden,
                              clEnumValEnd));
 } // End of llvm namespace
 
+void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
+  if (V == 0 && M == 0)
+    OS << "Releasing pass '";
+  else
+    OS << "Running pass '";
+  
+  OS << P->getPassName() << "'";
+  
+  if (M) {
+    OS << " on module '" << M->getModuleIdentifier() << "'.\n";
+    return;
+  }
+  if (V == 0) {
+    OS << '\n';
+    return;
+  }
+
+  std::string Name = V->getNameStr();
+  if (Name.empty())
+    Name = "<anonymous>";
+  else if (isa<GlobalValue>(V))
+    Name = "@" + Name;
+  else
+    Name = "%" + Name;
+
+  if (isa<Function>(V))
+    OS << " on function '" << Name << "'\n";
+  else if (isa<BasicBlock>(V))
+    OS << " on basic block '" << Name << "'\n";
+  else
+    OS << " on value '" << Name << "'\n";
+}
+
+
 namespace {
 
 //===----------------------------------------------------------------------===//
@@ -288,7 +322,6 @@ public:
   }
 
   inline void addTopLevelPass(Pass *P) {
-
     if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
       
       // P is a immutable pass and it will be managed by this
@@ -301,7 +334,6 @@ public:
     } else {
       P->assignPassManager(activeStack);
     }
-
   }
 
   MPPassManager *getContainedManager(unsigned N) {
@@ -309,7 +341,6 @@ public:
     MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
     return MP;
   }
-
 };
 
 char PassManagerImpl::ID = 0;
@@ -318,11 +349,10 @@ char PassManagerImpl::ID = 0;
 namespace {
 
 //===----------------------------------------------------------------------===//
-// TimingInfo Class - This class is used to calculate information about the
-// amount of time each pass takes to execute.  This only happens when
-// -time-passes is enabled on the command line.
-//
-
+/// TimingInfo Class - This class is used to calculate information about the
+/// amount of time each pass takes to execute.  This only happens when
+/// -time-passes is enabled on the command line.
+///
 class VISIBILITY_HIDDEN TimingInfo {
   std::map<Pass*, Timer> TimingData;
   TimerGroup TG;
@@ -344,7 +374,6 @@ public:
   static void createTheTimeInfo();
 
   void passStarted(Pass *P) {
-
     if (dynamic_cast<PMDataManager *>(P)) 
       return;
 
@@ -354,7 +383,6 @@ public:
     I->second.startTimer();
   }
   void passEnded(Pass *P) {
-
     if (dynamic_cast<PMDataManager *>(P)) 
       return;
 
@@ -372,15 +400,13 @@ static TimingInfo *TheTimeInfo;
 // PMTopLevelManager implementation
 
 /// Initialize top level manager. Create first pass manager.
-PMTopLevelManager::PMTopLevelManager (enum TopLevelManagerType t) {
-
+PMTopLevelManager::PMTopLevelManager(enum TopLevelManagerType t) {
   if (t == TLM_Pass) {
     MPPassManager *MPP = new MPPassManager(1);
     MPP->setTopLevelManager(this);
     addPassManager(MPP);
     activeStack.push(MPP);
-  } 
-  else if (t == TLM_Function) {
+  } else if (t == TLM_Function) {
     FPPassManager *FPP = new FPPassManager(1);
     FPP->setTopLevelManager(this);
     addPassManager(FPP);
@@ -391,7 +417,6 @@ PMTopLevelManager::PMTopLevelManager (enum TopLevelManagerType t) {
 /// Set pass P as the last user of the given analysis passes.
 void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &AnalysisPasses, 
                                     Pass *P) {
-
   for (SmallVector<Pass *, 12>::iterator I = AnalysisPasses.begin(),
          E = AnalysisPasses.end(); I != E; ++I) {
     Pass *AP = *I;
@@ -562,20 +587,15 @@ void PMTopLevelManager::dumpArguments() const {
 
   cerr << "Pass Arguments: ";
   for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
-         E = PassManagers.end(); I != E; ++I) {
-    PMDataManager *PMD = *I;
-    PMD->dumpPassArguments();
-  }
+         E = PassManagers.end(); I != E; ++I)
+    (*I)->dumpPassArguments();
   cerr << "\n";
 }
 
 void PMTopLevelManager::initializeAllAnalysisInfo() {
-  
   for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(),
-         E = PassManagers.end(); I != E; ++I) {
-    PMDataManager *PMD = *I;
-    PMD->initializeAnalysisInfo();
-  }
+         E = PassManagers.end(); I != E; ++I)
+    (*I)->initializeAnalysisInfo();
   
   // Initailize other pass managers
   for (SmallVector<PMDataManager *, 8>::iterator I = IndirectPassManagers.begin(),
@@ -772,9 +792,14 @@ void PMDataManager::removeDeadPasses(Pass *P, const char *Msg,
 
     dumpPassInfo(*I, FREEING_MSG, DBG_STR, Msg);
 
-    if (TheTimeInfo) TheTimeInfo->passStarted(*I);
-    (*I)->releaseMemory();
-    if (TheTimeInfo) TheTimeInfo->passEnded(*I);
+    {
+      // If the pass crashes releasing memory, remember this.
+      PassManagerPrettyStackEntry X(*I);
+      
+      if (TheTimeInfo) TheTimeInfo->passStarted(*I);
+      (*I)->releaseMemory();
+      if (TheTimeInfo) TheTimeInfo->passEnded(*I);
+    }
     if (const PassInfo *PI = (*I)->getPassInfo()) {
       std::map<AnalysisID, Pass*>::iterator Pos =
         AvailableAnalysis.find(PI);
@@ -1008,8 +1033,7 @@ void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
   }
 }
 
-void PMDataManager::dumpRequiredSet(const Pass *P)
-  const {
+void PMDataManager::dumpRequiredSet(const Pass *P) const {
   if (PassDebugging < Details)
     return;
     
@@ -1018,8 +1042,7 @@ void PMDataManager::dumpRequiredSet(const Pass *P)
   dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
 }
 
-void PMDataManager::dumpPreservedSet(const Pass *P)
-  const {
+void PMDataManager::dumpPreservedSet(const Pass *P) const {
   if (PassDebugging < Details)
     return;
     
@@ -1029,17 +1052,16 @@ void PMDataManager::dumpPreservedSet(const Pass *P)
 }
 
 void PMDataManager::dumpAnalysisUsage(const char *Msg, const Pass *P,
-                                        const AnalysisUsage::VectorType &Set)
-  const {
+                                   const AnalysisUsage::VectorType &Set) const {
   assert(PassDebugging >= Details);
   if (Set.empty())
     return;
   cerr << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
-    for (unsigned i = 0; i != Set.size(); ++i) {
-      if (i) cerr << ",";
-      cerr << " " << Set[i]->getPassName();
-    }
-    cerr << "\n";
+  for (unsigned i = 0; i != Set.size(); ++i) {
+    if (i) cerr << ",";
+    cerr << " " << Set[i]->getPassName();
+  }
+  cerr << "\n";
 }
 
 /// Add RequiredPass into list of lower level passes required by pass P.
@@ -1093,9 +1115,7 @@ Pass *AnalysisResolver::findImplPass(Pass *P, const PassInfo *AnalysisPI,
 /// Execute all of the passes scheduled for execution by invoking 
 /// runOnBasicBlock method.  Keep track of whether any of the passes modifies 
 /// the function, and if so, return true.
-bool
-BBPassManager::runOnFunction(Function &F) {
-
+bool BBPassManager::runOnFunction(Function &F) {
   if (F.isDeclaration())
     return false;
 
@@ -1110,9 +1130,14 @@ BBPassManager::runOnFunction(Function &F) {
 
       initializeAnalysisImpl(BP);
 
-      if (TheTimeInfo) TheTimeInfo->passStarted(BP);
-      Changed |= BP->runOnBasicBlock(*I);
-      if (TheTimeInfo) TheTimeInfo->passEnded(BP);
+      {
+        // If the pass crashes, remember this.
+        PassManagerPrettyStackEntry X(BP, *I);
+      
+        if (TheTimeInfo) TheTimeInfo->passStarted(BP);
+        Changed |= BP->runOnBasicBlock(*I);
+        if (TheTimeInfo) TheTimeInfo->passEnded(BP);
+      }
 
       if (Changed) 
         dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
@@ -1132,10 +1157,8 @@ BBPassManager::runOnFunction(Function &F) {
 bool BBPassManager::doInitialization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
-    BasicBlockPass *BP = getContainedPass(Index);
-    Changed |= BP->doInitialization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+    Changed |= getContainedPass(Index)->doInitialization(M);
 
   return Changed;
 }
@@ -1143,10 +1166,8 @@ bool BBPassManager::doInitialization(Module &M) {
 bool BBPassManager::doFinalization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
-    BasicBlockPass *BP = getContainedPass(Index);
-    Changed |= BP->doFinalization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+    Changed |= getContainedPass(Index)->doFinalization(M);
 
   return Changed;
 }
@@ -1234,10 +1255,8 @@ bool FunctionPassManager::doFinalization() {
 bool FunctionPassManagerImpl::doInitialization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {  
-    FPPassManager *FP = getContainedManager(Index);
-    Changed |= FP->doInitialization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+    Changed |= getContainedManager(Index)->doInitialization(M);
 
   return Changed;
 }
@@ -1245,10 +1264,8 @@ bool FunctionPassManagerImpl::doInitialization(Module &M) {
 bool FunctionPassManagerImpl::doFinalization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {  
-    FPPassManager *FP = getContainedManager(Index);
-    Changed |= FP->doFinalization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+    Changed |= getContainedManager(Index)->doFinalization(M);
 
   return Changed;
 }
@@ -1256,19 +1273,15 @@ bool FunctionPassManagerImpl::doFinalization(Module &M) {
 // Execute all the passes managed by this top level manager.
 // Return true if any function is modified by a pass.
 bool FunctionPassManagerImpl::run(Function &F) {
-
   bool Changed = false;
-
   TimingInfo::createTheTimeInfo();
 
   dumpArguments();
   dumpPasses();
 
   initializeAllAnalysisInfo();
-  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {  
-    FPPassManager *FP = getContainedManager(Index);
-    Changed |= FP->runOnFunction(F);
-  }
+  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+    Changed |= getContainedManager(Index)->runOnFunction(F);
   return Changed;
 }
 
@@ -1307,9 +1320,13 @@ bool FPPassManager::runOnFunction(Function &F) {
 
     initializeAnalysisImpl(FP);
 
-    if (TheTimeInfo) TheTimeInfo->passStarted(FP);
-    Changed |= FP->runOnFunction(F);
-    if (TheTimeInfo) TheTimeInfo->passEnded(FP);
+    {
+      PassManagerPrettyStackEntry X(FP, F);
+
+      if (TheTimeInfo) TheTimeInfo->passStarted(FP);
+      Changed |= FP->runOnFunction(F);
+      if (TheTimeInfo) TheTimeInfo->passEnded(FP);
+    }
 
     if (Changed) 
       dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getNameStart());
@@ -1338,10 +1355,8 @@ bool FPPassManager::runOnModule(Module &M) {
 bool FPPassManager::doInitialization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
-    FunctionPass *FP = getContainedPass(Index);
-    Changed |= FP->doInitialization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+    Changed |= getContainedPass(Index)->doInitialization(M);
 
   return Changed;
 }
@@ -1349,10 +1364,8 @@ bool FPPassManager::doInitialization(Module &M) {
 bool FPPassManager::doFinalization(Module &M) {
   bool Changed = false;
 
-  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
-    FunctionPass *FP = getContainedPass(Index);
-    Changed |= FP->doFinalization(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+    Changed |= getContainedPass(Index)->doFinalization(M);
 
   return Changed;
 }
@@ -1376,9 +1389,12 @@ MPPassManager::runOnModule(Module &M) {
 
     initializeAnalysisImpl(MP);
 
-    if (TheTimeInfo) TheTimeInfo->passStarted(MP);
-    Changed |= MP->runOnModule(M);
-    if (TheTimeInfo) TheTimeInfo->passEnded(MP);
+    {
+      PassManagerPrettyStackEntry X(MP, M);
+      if (TheTimeInfo) TheTimeInfo->passStarted(MP);
+      Changed |= MP->runOnModule(M);
+      if (TheTimeInfo) TheTimeInfo->passEnded(MP);
+    }
 
     if (Changed) 
       dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
@@ -1444,10 +1460,8 @@ bool PassManagerImpl::run(Module &M) {
   dumpPasses();
 
   initializeAllAnalysisInfo();
-  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {  
-    MPPassManager *MP = getContainedManager(Index);
-    Changed |= MP->runOnModule(M);
-  }
+  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+    Changed |= getContainedManager(Index)->runOnModule(M);
   return Changed;
 }