From d6f16587ab292b20857933b3ba13d3d1c62a8d62 Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Fri, 6 Mar 2009 06:45:05 +0000
Subject: [PATCH] Sprinkle some PrettyStackEntry magic into the passmanager. 
 With this, we now 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 |  23 +++++
 lib/Analysis/LoopPass.cpp   |  12 ++-
 lib/VMCore/PassManager.cpp  | 184 +++++++++++++++++++-----------------
 3 files changed, 129 insertions(+), 90 deletions(-)

diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index 2d68239e2aa..6e4f94697b9 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -88,7 +88,12 @@
 // 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
 //
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp
index c45c2ef4c0b..c4ff9889446 100644
--- a/lib/Analysis/LoopPass.cpp
+++ b/lib/Analysis/LoopPass.cpp
@@ -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, "");
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index c85a3093340..174aa474dfb 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -19,11 +19,11 @@
 #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;
 }