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
This commit is contained in:
Chris Lattner 2009-03-06 06:45:05 +00:00
parent 7157228a58
commit d6f16587ab
3 changed files with 129 additions and 90 deletions

View File

@ -88,7 +88,12 @@
// MPPassManagers. // MPPassManagers.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/PrettyStackTrace.h"
namespace llvm { namespace llvm {
class Pass;
class Value;
class Module;
/// FunctionPassManager and PassManager, two top level managers, serve /// FunctionPassManager and PassManager, two top level managers, serve
/// as the public interface of pass manager infrastructure. /// as the public interface of pass manager infrastructure.
@ -109,6 +114,24 @@ enum PassDebuggingString {
ON_CG_MSG // "' on Call Graph ...\n'" 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 // PMStack
// //

View File

@ -209,7 +209,6 @@ bool LPPassManager::runOnFunction(Function &F) {
// Run all passes on current SCC // Run all passes on current SCC
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
Pass *P = getContainedPass(Index); Pass *P = getContainedPass(Index);
dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, ""); dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, "");
@ -217,11 +216,14 @@ bool LPPassManager::runOnFunction(Function &F) {
initializeAnalysisImpl(P); initializeAnalysisImpl(P);
StartPassTimer(P);
LoopPass *LP = dynamic_cast<LoopPass *>(P); LoopPass *LP = dynamic_cast<LoopPass *>(P);
{
PassManagerPrettyStackEntry X(LP, *CurrentLoop->getHeader());
StartPassTimer(P);
assert(LP && "Invalid LPPassManager member"); assert(LP && "Invalid LPPassManager member");
Changed |= LP->runOnLoop(CurrentLoop, *this); Changed |= LP->runOnLoop(CurrentLoop, *this);
StopPassTimer(P); StopPassTimer(P);
}
if (Changed) if (Changed)
dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, ""); dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, "");

View File

@ -19,11 +19,11 @@
#include "llvm/ModuleProvider.h" #include "llvm/ModuleProvider.h"
#include "llvm/Support/Streams.h" #include "llvm/Support/Streams.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm-c/Core.h" #include "llvm-c/Core.h"
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
#include <vector>
#include <map> #include <map>
using namespace llvm; using namespace llvm;
@ -60,6 +60,40 @@ PassDebugging("debug-pass", cl::Hidden,
clEnumValEnd)); clEnumValEnd));
} // End of llvm namespace } // 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 { namespace {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -288,7 +322,6 @@ public:
} }
inline void addTopLevelPass(Pass *P) { inline void addTopLevelPass(Pass *P) {
if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) { if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
// P is a immutable pass and it will be managed by this // P is a immutable pass and it will be managed by this
@ -301,7 +334,6 @@ public:
} else { } else {
P->assignPassManager(activeStack); P->assignPassManager(activeStack);
} }
} }
MPPassManager *getContainedManager(unsigned N) { MPPassManager *getContainedManager(unsigned N) {
@ -309,7 +341,6 @@ public:
MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]); MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
return MP; return MP;
} }
}; };
char PassManagerImpl::ID = 0; char PassManagerImpl::ID = 0;
@ -318,11 +349,10 @@ char PassManagerImpl::ID = 0;
namespace { namespace {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// TimingInfo Class - This class is used to calculate information about the /// TimingInfo Class - This class is used to calculate information about the
// amount of time each pass takes to execute. This only happens when /// amount of time each pass takes to execute. This only happens when
// -time-passes is enabled on the command line. /// -time-passes is enabled on the command line.
// ///
class VISIBILITY_HIDDEN TimingInfo { class VISIBILITY_HIDDEN TimingInfo {
std::map<Pass*, Timer> TimingData; std::map<Pass*, Timer> TimingData;
TimerGroup TG; TimerGroup TG;
@ -344,7 +374,6 @@ public:
static void createTheTimeInfo(); static void createTheTimeInfo();
void passStarted(Pass *P) { void passStarted(Pass *P) {
if (dynamic_cast<PMDataManager *>(P)) if (dynamic_cast<PMDataManager *>(P))
return; return;
@ -354,7 +383,6 @@ public:
I->second.startTimer(); I->second.startTimer();
} }
void passEnded(Pass *P) { void passEnded(Pass *P) {
if (dynamic_cast<PMDataManager *>(P)) if (dynamic_cast<PMDataManager *>(P))
return; return;
@ -373,14 +401,12 @@ static TimingInfo *TheTimeInfo;
/// Initialize top level manager. Create first pass manager. /// Initialize top level manager. Create first pass manager.
PMTopLevelManager::PMTopLevelManager(enum TopLevelManagerType t) { PMTopLevelManager::PMTopLevelManager(enum TopLevelManagerType t) {
if (t == TLM_Pass) { if (t == TLM_Pass) {
MPPassManager *MPP = new MPPassManager(1); MPPassManager *MPP = new MPPassManager(1);
MPP->setTopLevelManager(this); MPP->setTopLevelManager(this);
addPassManager(MPP); addPassManager(MPP);
activeStack.push(MPP); activeStack.push(MPP);
} } else if (t == TLM_Function) {
else if (t == TLM_Function) {
FPPassManager *FPP = new FPPassManager(1); FPPassManager *FPP = new FPPassManager(1);
FPP->setTopLevelManager(this); FPP->setTopLevelManager(this);
addPassManager(FPP); addPassManager(FPP);
@ -391,7 +417,6 @@ PMTopLevelManager::PMTopLevelManager (enum TopLevelManagerType t) {
/// Set pass P as the last user of the given analysis passes. /// Set pass P as the last user of the given analysis passes.
void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &AnalysisPasses, void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &AnalysisPasses,
Pass *P) { Pass *P) {
for (SmallVector<Pass *, 12>::iterator I = AnalysisPasses.begin(), for (SmallVector<Pass *, 12>::iterator I = AnalysisPasses.begin(),
E = AnalysisPasses.end(); I != E; ++I) { E = AnalysisPasses.end(); I != E; ++I) {
Pass *AP = *I; Pass *AP = *I;
@ -562,20 +587,15 @@ void PMTopLevelManager::dumpArguments() const {
cerr << "Pass Arguments: "; cerr << "Pass Arguments: ";
for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I) { E = PassManagers.end(); I != E; ++I)
PMDataManager *PMD = *I; (*I)->dumpPassArguments();
PMD->dumpPassArguments();
}
cerr << "\n"; cerr << "\n";
} }
void PMTopLevelManager::initializeAllAnalysisInfo() { void PMTopLevelManager::initializeAllAnalysisInfo() {
for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(), for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I) { E = PassManagers.end(); I != E; ++I)
PMDataManager *PMD = *I; (*I)->initializeAnalysisInfo();
PMD->initializeAnalysisInfo();
}
// Initailize other pass managers // Initailize other pass managers
for (SmallVector<PMDataManager *, 8>::iterator I = IndirectPassManagers.begin(), 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); dumpPassInfo(*I, FREEING_MSG, DBG_STR, Msg);
{
// If the pass crashes releasing memory, remember this.
PassManagerPrettyStackEntry X(*I);
if (TheTimeInfo) TheTimeInfo->passStarted(*I); if (TheTimeInfo) TheTimeInfo->passStarted(*I);
(*I)->releaseMemory(); (*I)->releaseMemory();
if (TheTimeInfo) TheTimeInfo->passEnded(*I); if (TheTimeInfo) TheTimeInfo->passEnded(*I);
}
if (const PassInfo *PI = (*I)->getPassInfo()) { if (const PassInfo *PI = (*I)->getPassInfo()) {
std::map<AnalysisID, Pass*>::iterator Pos = std::map<AnalysisID, Pass*>::iterator Pos =
AvailableAnalysis.find(PI); AvailableAnalysis.find(PI);
@ -1008,8 +1033,7 @@ void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
} }
} }
void PMDataManager::dumpRequiredSet(const Pass *P) void PMDataManager::dumpRequiredSet(const Pass *P) const {
const {
if (PassDebugging < Details) if (PassDebugging < Details)
return; return;
@ -1018,8 +1042,7 @@ void PMDataManager::dumpRequiredSet(const Pass *P)
dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet()); dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
} }
void PMDataManager::dumpPreservedSet(const Pass *P) void PMDataManager::dumpPreservedSet(const Pass *P) const {
const {
if (PassDebugging < Details) if (PassDebugging < Details)
return; return;
@ -1029,8 +1052,7 @@ void PMDataManager::dumpPreservedSet(const Pass *P)
} }
void PMDataManager::dumpAnalysisUsage(const char *Msg, const Pass *P, void PMDataManager::dumpAnalysisUsage(const char *Msg, const Pass *P,
const AnalysisUsage::VectorType &Set) const AnalysisUsage::VectorType &Set) const {
const {
assert(PassDebugging >= Details); assert(PassDebugging >= Details);
if (Set.empty()) if (Set.empty())
return; return;
@ -1093,9 +1115,7 @@ Pass *AnalysisResolver::findImplPass(Pass *P, const PassInfo *AnalysisPI,
/// Execute all of the passes scheduled for execution by invoking /// Execute all of the passes scheduled for execution by invoking
/// runOnBasicBlock method. Keep track of whether any of the passes modifies /// runOnBasicBlock method. Keep track of whether any of the passes modifies
/// the function, and if so, return true. /// the function, and if so, return true.
bool bool BBPassManager::runOnFunction(Function &F) {
BBPassManager::runOnFunction(Function &F) {
if (F.isDeclaration()) if (F.isDeclaration())
return false; return false;
@ -1110,9 +1130,14 @@ BBPassManager::runOnFunction(Function &F) {
initializeAnalysisImpl(BP); initializeAnalysisImpl(BP);
{
// If the pass crashes, remember this.
PassManagerPrettyStackEntry X(BP, *I);
if (TheTimeInfo) TheTimeInfo->passStarted(BP); if (TheTimeInfo) TheTimeInfo->passStarted(BP);
Changed |= BP->runOnBasicBlock(*I); Changed |= BP->runOnBasicBlock(*I);
if (TheTimeInfo) TheTimeInfo->passEnded(BP); if (TheTimeInfo) TheTimeInfo->passEnded(BP);
}
if (Changed) if (Changed)
dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
@ -1132,10 +1157,8 @@ BBPassManager::runOnFunction(Function &F) {
bool BBPassManager::doInitialization(Module &M) { bool BBPassManager::doInitialization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
BasicBlockPass *BP = getContainedPass(Index); Changed |= getContainedPass(Index)->doInitialization(M);
Changed |= BP->doInitialization(M);
}
return Changed; return Changed;
} }
@ -1143,10 +1166,8 @@ bool BBPassManager::doInitialization(Module &M) {
bool BBPassManager::doFinalization(Module &M) { bool BBPassManager::doFinalization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
BasicBlockPass *BP = getContainedPass(Index); Changed |= getContainedPass(Index)->doFinalization(M);
Changed |= BP->doFinalization(M);
}
return Changed; return Changed;
} }
@ -1234,10 +1255,8 @@ bool FunctionPassManager::doFinalization() {
bool FunctionPassManagerImpl::doInitialization(Module &M) { bool FunctionPassManagerImpl::doInitialization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
FPPassManager *FP = getContainedManager(Index); Changed |= getContainedManager(Index)->doInitialization(M);
Changed |= FP->doInitialization(M);
}
return Changed; return Changed;
} }
@ -1245,10 +1264,8 @@ bool FunctionPassManagerImpl::doInitialization(Module &M) {
bool FunctionPassManagerImpl::doFinalization(Module &M) { bool FunctionPassManagerImpl::doFinalization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
FPPassManager *FP = getContainedManager(Index); Changed |= getContainedManager(Index)->doFinalization(M);
Changed |= FP->doFinalization(M);
}
return Changed; return Changed;
} }
@ -1256,19 +1273,15 @@ bool FunctionPassManagerImpl::doFinalization(Module &M) {
// Execute all the passes managed by this top level manager. // Execute all the passes managed by this top level manager.
// Return true if any function is modified by a pass. // Return true if any function is modified by a pass.
bool FunctionPassManagerImpl::run(Function &F) { bool FunctionPassManagerImpl::run(Function &F) {
bool Changed = false; bool Changed = false;
TimingInfo::createTheTimeInfo(); TimingInfo::createTheTimeInfo();
dumpArguments(); dumpArguments();
dumpPasses(); dumpPasses();
initializeAllAnalysisInfo(); initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
FPPassManager *FP = getContainedManager(Index); Changed |= getContainedManager(Index)->runOnFunction(F);
Changed |= FP->runOnFunction(F);
}
return Changed; return Changed;
} }
@ -1307,9 +1320,13 @@ bool FPPassManager::runOnFunction(Function &F) {
initializeAnalysisImpl(FP); initializeAnalysisImpl(FP);
{
PassManagerPrettyStackEntry X(FP, F);
if (TheTimeInfo) TheTimeInfo->passStarted(FP); if (TheTimeInfo) TheTimeInfo->passStarted(FP);
Changed |= FP->runOnFunction(F); Changed |= FP->runOnFunction(F);
if (TheTimeInfo) TheTimeInfo->passEnded(FP); if (TheTimeInfo) TheTimeInfo->passEnded(FP);
}
if (Changed) if (Changed)
dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getNameStart()); dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getNameStart());
@ -1338,10 +1355,8 @@ bool FPPassManager::runOnModule(Module &M) {
bool FPPassManager::doInitialization(Module &M) { bool FPPassManager::doInitialization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
FunctionPass *FP = getContainedPass(Index); Changed |= getContainedPass(Index)->doInitialization(M);
Changed |= FP->doInitialization(M);
}
return Changed; return Changed;
} }
@ -1349,10 +1364,8 @@ bool FPPassManager::doInitialization(Module &M) {
bool FPPassManager::doFinalization(Module &M) { bool FPPassManager::doFinalization(Module &M) {
bool Changed = false; bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
FunctionPass *FP = getContainedPass(Index); Changed |= getContainedPass(Index)->doFinalization(M);
Changed |= FP->doFinalization(M);
}
return Changed; return Changed;
} }
@ -1376,9 +1389,12 @@ MPPassManager::runOnModule(Module &M) {
initializeAnalysisImpl(MP); initializeAnalysisImpl(MP);
{
PassManagerPrettyStackEntry X(MP, M);
if (TheTimeInfo) TheTimeInfo->passStarted(MP); if (TheTimeInfo) TheTimeInfo->passStarted(MP);
Changed |= MP->runOnModule(M); Changed |= MP->runOnModule(M);
if (TheTimeInfo) TheTimeInfo->passEnded(MP); if (TheTimeInfo) TheTimeInfo->passEnded(MP);
}
if (Changed) if (Changed)
dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
@ -1444,10 +1460,8 @@ bool PassManagerImpl::run(Module &M) {
dumpPasses(); dumpPasses();
initializeAllAnalysisInfo(); initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
MPPassManager *MP = getContainedManager(Index); Changed |= getContainedManager(Index)->runOnModule(M);
Changed |= MP->runOnModule(M);
}
return Changed; return Changed;
} }