Add pass printer passes in the right place.

The pass pointer should never be referenced after sending it to
schedulePass(), which may delete the pass. To fix this bug I had to
clean up the design leading to more goodness.

You may notice now that any non-analysis pass is printed. So things like loop-simplify and lcssa show up, while target lib, target data, alias analysis do not show up. Normally, analysis don't mutate the IR, but you can now check this by using both -print-after and -print-before. The effects of analysis will now show up in between the two.

The llc path is still in bad shape. But I'll be improving it in my next checkin. Meanwhile, print-machineinstrs still works the same way. With print-before/after, many llc passes that were not printed before now are, some of these should be converted to analysis. A few very important passes, isel and scheduler, are not properly initialized, so not printed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149480 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2012-02-01 07:16:20 +00:00
parent 19c51a9b3e
commit 11e4329154
3 changed files with 50 additions and 94 deletions

View File

@ -59,10 +59,6 @@ public:
bool run(Module &M); bool run(Module &M);
private: private:
/// addImpl - Add a pass to the queue of passes to run, without
/// checking whether to add a printer pass.
void addImpl(Pass *P);
/// PassManagerImpl_New is the actual class. PassManager is just the /// PassManagerImpl_New is the actual class. PassManager is just the
/// wraper to publish simple pass manager interface /// wraper to publish simple pass manager interface
PassManagerImpl *PM; PassManagerImpl *PM;
@ -79,7 +75,7 @@ public:
/// add - Add a pass to the queue of passes to run. This passes /// add - Add a pass to the queue of passes to run. This passes
/// ownership of the Pass to the PassManager. When the /// ownership of the Pass to the PassManager. When the
/// PassManager_X is destroyed, the pass will be destroyed as well, so /// PassManager_X is destroyed, the pass will be destroyed as well, so
/// there is no need to delete the pass. (TODO delete passes.) /// there is no need to delete the pass.
/// This implies that all passes MUST be allocated with 'new'. /// This implies that all passes MUST be allocated with 'new'.
void add(Pass *P); void add(Pass *P);
@ -98,10 +94,6 @@ public:
bool doFinalization(); bool doFinalization();
private: private:
/// addImpl - Add a pass to the queue of passes to run, without
/// checking whether to add a printer pass.
void addImpl(Pass *P);
FunctionPassManagerImpl *FPM; FunctionPassManagerImpl *FPM;
Module *M; Module *M;
}; };

View File

@ -82,7 +82,7 @@
// relies on PassManagerImpl to do all the tasks. // relies on PassManagerImpl to do all the tasks.
// //
// [o] class PassManagerImpl : public Pass, public PMDataManager, // [o] class PassManagerImpl : public Pass, public PMDataManager,
// public PMDTopLevelManager // public PMTopLevelManager
// //
// PassManagerImpl is a top level pass manager responsible for managing // PassManagerImpl is a top level pass manager responsible for managing
// MPPassManagers. // MPPassManagers.
@ -174,9 +174,8 @@ protected:
void initializeAllAnalysisInfo(); void initializeAllAnalysisInfo();
private: private:
/// This is implemented by top level pass manager and used by virtual PMDataManager *getAsPMDataManager() = 0;
/// schedulePass() to add analysis info passes that are not available. virtual PassManagerType getTopLevelPassManagerType() = 0;
virtual void addTopLevelPass(Pass *P) = 0;
public: public:
/// Schedule pass P for execution. Make sure that passes required by /// Schedule pass P for execution. Make sure that passes required by

View File

@ -84,10 +84,8 @@ PrintAfterAll("print-after-all",
/// This is a helper to determine whether to print IR before or /// This is a helper to determine whether to print IR before or
/// after a pass. /// after a pass.
static bool ShouldPrintBeforeOrAfterPass(const void *PassID, static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
PassOptionList &PassesToPrint) { PassOptionList &PassesToPrint) {
if (const llvm::PassInfo *PI =
PassRegistry::getPassRegistry()->getPassInfo(PassID)) {
for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
const llvm::PassInfo *PassInf = PassesToPrint[i]; const llvm::PassInfo *PassInf = PassesToPrint[i];
if (PassInf) if (PassInf)
@ -95,21 +93,19 @@ static bool ShouldPrintBeforeOrAfterPass(const void *PassID,
return true; return true;
} }
} }
}
return false; return false;
} }
/// This is a utility to check whether a pass should have IR dumped /// This is a utility to check whether a pass should have IR dumped
/// before it. /// before it.
static bool ShouldPrintBeforePass(const void *PassID) { static bool ShouldPrintBeforePass(const PassInfo *PI) {
return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore); return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
} }
/// This is a utility to check whether a pass should have IR dumped /// This is a utility to check whether a pass should have IR dumped
/// after it. /// after it.
static bool ShouldPrintAfterPass(const void *PassID) { static bool ShouldPrintAfterPass(const PassInfo *PI) {
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter); return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
} }
} // End of llvm namespace } // End of llvm namespace
@ -264,27 +260,15 @@ public:
virtual PMDataManager *getAsPMDataManager() { return this; } virtual PMDataManager *getAsPMDataManager() { return this; }
virtual Pass *getAsPass() { return this; } virtual Pass *getAsPass() { return this; }
virtual PassManagerType getTopLevelPassManagerType() {
return PMT_FunctionPassManager;
}
/// Pass Manager itself does not invalidate any analysis info. /// Pass Manager itself does not invalidate any analysis info.
void getAnalysisUsage(AnalysisUsage &Info) const { void getAnalysisUsage(AnalysisUsage &Info) const {
Info.setPreservesAll(); Info.setPreservesAll();
} }
void addTopLevelPass(Pass *P) {
if (ImmutablePass *IP = P->getAsImmutablePass()) {
// P is a immutable pass and it will be managed by this
// top level manager. Set up analysis resolver to connect them.
AnalysisResolver *AR = new AnalysisResolver(*this);
P->setResolver(AR);
initializeAnalysisImpl(P);
addImmutablePass(IP);
recordAvailableAnalysis(IP);
} else {
P->assignPassManager(activeStack, PMT_FunctionPassManager);
}
}
FPPassManager *getContainedManager(unsigned N) { FPPassManager *getContainedManager(unsigned N) {
assert(N < PassManagers.size() && "Pass number out of range!"); assert(N < PassManagers.size() && "Pass number out of range!");
FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]); FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
@ -417,22 +401,11 @@ public:
Info.setPreservesAll(); Info.setPreservesAll();
} }
void addTopLevelPass(Pass *P) {
if (ImmutablePass *IP = P->getAsImmutablePass()) {
// P is a immutable pass and it will be managed by this
// top level manager. Set up analysis resolver to connect them.
AnalysisResolver *AR = new AnalysisResolver(*this);
P->setResolver(AR);
initializeAnalysisImpl(P);
addImmutablePass(IP);
recordAvailableAnalysis(IP);
} else {
P->assignPassManager(activeStack, PMT_ModulePassManager);
}
}
virtual PMDataManager *getAsPMDataManager() { return this; } virtual PMDataManager *getAsPMDataManager() { return this; }
virtual Pass *getAsPass() { return this; } virtual Pass *getAsPass() { return this; }
virtual PassManagerType getTopLevelPassManagerType() {
return PMT_ModulePassManager;
}
MPPassManager *getContainedManager(unsigned N) { MPPassManager *getContainedManager(unsigned N) {
assert(N < PassManagers.size() && "Pass number out of range!"); assert(N < PassManagers.size() && "Pass number out of range!");
@ -660,7 +633,32 @@ void PMTopLevelManager::schedulePass(Pass *P) {
} }
// Now all required passes are available. // Now all required passes are available.
addTopLevelPass(P); if (ImmutablePass *IP = P->getAsImmutablePass()) {
// P is a immutable pass and it will be managed by this
// top level manager. Set up analysis resolver to connect them.
PMDataManager *DM = getAsPMDataManager();
AnalysisResolver *AR = new AnalysisResolver(*DM);
P->setResolver(AR);
DM->initializeAnalysisImpl(P);
addImmutablePass(IP);
DM->recordAvailableAnalysis(IP);
return;
}
if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
Pass *PP = P->createPrinterPass(
dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***");
PP->assignPassManager(activeStack, getTopLevelPassManagerType());
}
// Add the requested pass to the best available pass manager.
P->assignPassManager(activeStack, getTopLevelPassManagerType());
if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
Pass *PP = P->createPrinterPass(
dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***");
PP->assignPassManager(activeStack, getTopLevelPassManagerType());
}
} }
/// Find the pass that implements Analysis AID. Search immutable /// Find the pass that implements Analysis AID. Search immutable
@ -1357,31 +1355,13 @@ FunctionPassManager::~FunctionPassManager() {
delete FPM; delete FPM;
} }
/// addImpl - Add a pass to the queue of passes to run, without
/// checking whether to add a printer pass.
void FunctionPassManager::addImpl(Pass *P) {
FPM->add(P);
}
/// add - Add a pass to the queue of passes to run. This passes /// add - Add a pass to the queue of passes to run. This passes
/// ownership of the Pass to the PassManager. When the /// ownership of the Pass to the PassManager. When the
/// PassManager_X is destroyed, the pass will be destroyed as well, so /// PassManager_X is destroyed, the pass will be destroyed as well, so
/// there is no need to delete the pass. (TODO delete passes.) /// there is no need to delete the pass. (TODO delete passes.)
/// This implies that all passes MUST be allocated with 'new'. /// This implies that all passes MUST be allocated with 'new'.
void FunctionPassManager::add(Pass *P) { void FunctionPassManager::add(Pass *P) {
// If this is a not a function pass, don't add a printer for it. FPM->add(P);
const void *PassID = P->getPassID();
if (P->getPassKind() == PT_Function)
if (ShouldPrintBeforePass(PassID))
addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ P->getPassName() + " ***"));
addImpl(P);
if (P->getPassKind() == PT_Function)
if (ShouldPrintAfterPass(PassID))
addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ P->getPassName() + " ***"));
} }
/// run - Execute all of the passes scheduled for execution. Keep /// run - Execute all of the passes scheduled for execution. Keep
@ -1693,27 +1673,12 @@ PassManager::~PassManager() {
delete PM; delete PM;
} }
/// addImpl - Add a pass to the queue of passes to run, without
/// checking whether to add a printer pass.
void PassManager::addImpl(Pass *P) {
PM->add(P);
}
/// add - Add a pass to the queue of passes to run. This passes ownership of /// add - Add a pass to the queue of passes to run. This passes ownership of
/// the Pass to the PassManager. When the PassManager is destroyed, the pass /// the Pass to the PassManager. When the PassManager is destroyed, the pass
/// will be destroyed as well, so there is no need to delete the pass. This /// will be destroyed as well, so there is no need to delete the pass. This
/// implies that all passes MUST be allocated with 'new'. /// implies that all passes MUST be allocated with 'new'.
void PassManager::add(Pass *P) { void PassManager::add(Pass *P) {
const void* PassID = P->getPassID(); PM->add(P);
if (ShouldPrintBeforePass(PassID))
addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ P->getPassName() + " ***"));
addImpl(P);
if (ShouldPrintAfterPass(PassID))
addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ P->getPassName() + " ***"));
} }
/// run - Execute all of the passes scheduled for execution. Keep track of /// run - Execute all of the passes scheduled for execution. Keep track of
@ -1823,7 +1788,7 @@ void ModulePass::assignPassManager(PMStack &PMS,
void FunctionPass::assignPassManager(PMStack &PMS, void FunctionPass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) { PassManagerType PreferredType) {
// Find Module Pass Manager // Find Function Pass Manager
while (!PMS.empty()) { while (!PMS.empty()) {
if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
PMS.pop(); PMS.pop();