diff options
author | David Greene <greened@obbligato.org> | 2010-04-02 23:17:14 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2010-04-02 23:17:14 +0000 |
commit | 5c8aa950fe3484b6e115647328c196f8be64f9ed (patch) | |
tree | 71f9b6e935bfe9fda09ef15a2d3de3bd4f6e3d46 /lib/VMCore/PassManager.cpp | |
parent | 55f71187a53d29e9df39d5ae298f7368028f93d0 (diff) | |
download | external_llvm-5c8aa950fe3484b6e115647328c196f8be64f9ed.zip external_llvm-5c8aa950fe3484b6e115647328c196f8be64f9ed.tar.gz external_llvm-5c8aa950fe3484b6e115647328c196f8be64f9ed.tar.bz2 |
Ok, third time's the charm. No changes from last time except the CMake
source addition. Apparently the buildbots were wrong about failures.
---
Add some switches helpful for debugging:
-print-before=<Pass Name>
Dump IR before running pass <Pass Name>.
-print-before-all
Dump IR before running each pass.
-print-after-all
Dump IR after running each pass.
These are helpful when tracking down a miscompilation. It is easy to
get IR dumps and do diffs on them, etc.
To make this work well, add a new getPrinterPass API to Pass so that
each kind of pass (ModulePass, FunctionPass, etc.) can create a Pass
suitable for dumping out the kind of object the Pass works on.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100249 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/PassManager.cpp')
-rw-r--r-- | lib/VMCore/PassManager.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 6774cec..6ca35ac0 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -13,6 +13,7 @@ #include "llvm/PassManagers.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -20,6 +21,7 @@ #include "llvm/Module.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PassNameParser.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" @@ -55,6 +57,57 @@ PassDebugging("debug-pass", cl::Hidden, clEnumVal(Executions, "print pass name before it is executed"), clEnumVal(Details , "print pass details when it is executed"), clEnumValEnd)); + +typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser> +PassOptionList; + +// Print IR out before/after specified passes. +static PassOptionList +PrintBefore("print-before", + llvm::cl::desc("Print IR before specified passes")); + +static PassOptionList +PrintAfter("print-after", + llvm::cl::desc("Print IR after specified passes")); + +static cl::opt<bool> +PrintBeforeAll("print-before-all", + llvm::cl::desc("Print IR before each pass"), + cl::init(false)); +static cl::opt<bool> +PrintAfterAll("print-after-all", + llvm::cl::desc("Print IR after each pass"), + cl::init(false)); + +/// This is a helper to determine whether to print IR before or +/// after a pass. + +static bool ShouldPrintBeforeOrAfterPass(Pass *P, + PassOptionList &PassesToPrint) { + for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { + const llvm::PassInfo *PassInf = PassesToPrint[i]; + if (PassInf && P->getPassInfo()) + if (PassInf->getPassArgument() == + P->getPassInfo()->getPassArgument()) { + return true; + } + } + return false; +} + + +/// This is a utility to check whether a pass should have IR dumped +/// before it. +static bool ShouldPrintBeforePass(Pass *P) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(P, PrintBefore); +} + +/// This is a utility to check whether a pass should have IR dumped +/// after it. +static bool ShouldPrintAfterPass(Pass *P) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(P, PrintAfter); +} + } // End of llvm namespace /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions @@ -182,6 +235,11 @@ public: schedulePass(P); } + /// createPrinterPass - Get a function printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintFunctionPass(Banner, &O); + } + // Prepare for running an on the fly pass, freeing memory if needed // from a previous run. void releaseMemoryOnTheFly(); @@ -252,6 +310,11 @@ public: } } + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool runOnModule(Module &M); @@ -331,6 +394,11 @@ public: schedulePass(P); } + /// createPrinterPass - Get a module printer pass. + Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const { + return createPrintModulePass(&O, false, Banner); + } + /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool run(Module &M); @@ -1208,7 +1276,14 @@ FunctionPassManager::~FunctionPassManager() { /// there is no need to delete the pass. (TODO delete passes.) /// This implies that all passes MUST be allocated with 'new'. void FunctionPassManager::add(Pass *P) { + if (ShouldPrintBeforePass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") + + P->getPassName() + " ***")); FPM->add(P); + + if (ShouldPrintAfterPass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") + + P->getPassName() + " ***")); } /// run - Execute all of the passes scheduled for execution. Keep @@ -1519,7 +1594,15 @@ PassManager::~PassManager() { /// will be destroyed as well, so there is no need to delete the pass. This /// implies that all passes MUST be allocated with 'new'. void PassManager::add(Pass *P) { + if (ShouldPrintBeforePass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") + + P->getPassName() + " ***")); + PM->add(P); + + if (ShouldPrintAfterPass(P)) + add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") + + P->getPassName() + " ***")); } /// run - Execute all of the passes scheduled for execution. Keep track of |