From 41300863c5e73edd0228e2486c01a46eb2a153e0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 31 Jan 2002 00:45:31 +0000 Subject: Implement new pass framework git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1606 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/Pass.cpp | 257 +++++++++++++++++++++++++--------------------------- 1 file changed, 125 insertions(+), 132 deletions(-) (limited to 'lib/VMCore/Pass.cpp') diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index 13df793901..a139a25e4d 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -6,175 +6,168 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Pass.h" +#include "llvm/PassManager.h" +#include "llvm/Module.h" +#include "llvm/Method.h" #include "Support/STLExtras.h" #include +// Source of unique analysis ID #'s. +unsigned AnalysisID::NextID = 0; + +void AnalysisResolver::setAnalysisResolver(Pass *P, AnalysisResolver *AR) { + assert(P->Resolver == 0 && "Pass already in a PassManager!"); + P->Resolver = AR; +} + + // Pass debugging information. Often it is useful to find out what pass is // running when a crash occurs in a utility. When this library is compiled with // debugging on, a command line option (--debug-pass) is enabled that causes the // pass name to be printed before it executes. // -#ifdef NDEBUG -// If not debugging, remove the option -inline static void PrintPassInformation(const char *, Pass *, Value *) { } -#else - +#ifndef NDEBUG #include "Support/CommandLine.h" #include #include -// The option is hidden from --help by default -static cl::Flag PassDebugEnabled("debug-pass", - "Print pass names as they are executed by the PassManager", cl::Hidden); - -static void PrintPassInformation(const char *Action, Pass *P, Value *V) { - if (PassDebugEnabled) - std::cerr << Action << " Pass '" << typeid(*P).name() << "' on " - << typeid(*V).name() << " '" << V->getName() << "'...\n"; -} -#endif - +// Different debug levels that can be enabled... +enum PassDebugLevel { + None, PassStructure, PassExecutions, PassDetails +}; +static cl::Enum PassDebugging("debug-pass", cl::Hidden, + "Print PassManager debugging information", + clEnumVal(None , "disable debug output"), + clEnumVal(PassStructure , "print pass structure before run()"), + clEnumVal(PassExecutions, "print pass name before it is executed"), + clEnumVal(PassDetails , "print pass details when it is executed"), 0); -PassManager::~PassManager() { - for_each(Passes.begin(), Passes.end(), deleter); +void PMDebug::PrintPassStructure(Pass *P) { + if (PassDebugging >= PassStructure) + P->dumpPassStructure(); } -class BasicBlockPassBatcher : public MethodPass { - typedef std::vector SubPassesType; - SubPassesType SubPasses; -public: - ~BasicBlockPassBatcher() { - for_each(SubPasses.begin(), SubPasses.end(), deleter); +void PMDebug::PrintPassInformation(unsigned Depth, const char *Action, + Pass *P, Value *V) { + if (PassDebugging >= PassExecutions) { + std::cerr << std::string(Depth*2, ' ') << Action << " '" + << typeid(*P).name(); + if (V) { + std::cerr << "' on "; + switch (V->getValueType()) { + case Value::ModuleVal: + std::cerr << "Module\n"; return; + case Value::MethodVal: + std::cerr << "Method '" << V->getName(); break; + case Value::BasicBlockVal: + std::cerr << "BasicBlock '" << V->getName(); break; + default: + std::cerr << typeid(*V).name() << " '" << V->getName(); break; + } + } + std::cerr << "'...\n"; } +} - void add(BasicBlockPass *P) { SubPasses.push_back(P); } - - virtual bool doInitialization(Module *M) { - bool Changed = false; - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Initializing", *I, M); - Changed |= (*I)->doInitialization(M); +void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg, + const Pass::AnalysisSet &Set) { + if (PassDebugging >= PassDetails && !Set.empty()) { + std::cerr << std::string(Depth*2+2, ' ') << Msg << " Analyses:"; + for (unsigned i = 0; i < Set.size(); ++i) { + Pass *P = Set[i].createPass(); // Good thing this is just debug code... + std::cerr << " " << typeid(*P).name(); + delete P; } - return Changed; + std::cerr << "\n"; } +} - virtual bool runOnMethod(Method *M) { - bool Changed = false; +// dumpPassStructure - Implement the -debug-passes=PassStructure option +void Pass::dumpPassStructure(unsigned Offset = 0) { + std::cerr << std::string(Offset*2, ' ') << typeid(*this).name() << "\n"; +} +#endif - for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Executing", *I, *MI); - Changed |= (*I)->runOnBasicBlock(*MI); - } - return Changed; - } - virtual bool doFinalization(Module *M) { - bool Changed = false; - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Finalizing", *I, M); - Changed |= (*I)->doFinalization(M); - } - return Changed; - } -}; - -class MethodPassBatcher : public Pass { - typedef std::vector SubPassesType; - SubPassesType SubPasses; - BasicBlockPassBatcher *BBPBatcher; -public: - inline MethodPassBatcher() : BBPBatcher(0) {} +//===----------------------------------------------------------------------===// +// Pass Implementation +// - inline ~MethodPassBatcher() { - for_each(SubPasses.begin(), SubPasses.end(), deleter); - } +void Pass::addToPassManager(PassManagerT *PM, AnalysisSet &Destroyed, + AnalysisSet &Provided) { + PM->addPass(this, Destroyed, Provided); +} - void add(BasicBlockPass *BBP) { - if (BBPBatcher == 0) { - BBPBatcher = new BasicBlockPassBatcher(); - SubPasses.push_back(BBPBatcher); - } - BBPBatcher->add(BBP); - } +//===----------------------------------------------------------------------===// +// MethodPass Implementation +// - void add(MethodPass *P) { - if (BasicBlockPass *BBP = dynamic_cast(P)) { - add(BBP); - } else { - BBPBatcher = 0; // Ensure that passes don't get accidentally reordered - SubPasses.push_back(P); - } - } +// run - On a module, we run this pass by initializing, ronOnMethod'ing once +// for every method in the module, then by finalizing. +// +bool MethodPass::run(Module *M) { + bool Changed = doInitialization(M); + + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + if (!(*I)->isExternal()) // Passes are not run on external methods! + Changed |= runOnMethod(*I); + + return Changed | doFinalization(M); +} - virtual bool run(Module *M) { - bool Changed = false; - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Initializing", *I, M); - Changed |= (*I)->doInitialization(M); - } +// run - On a method, we simply initialize, run the method, then finalize. +// +bool MethodPass::run(Method *M) { + if (M->isExternal()) return false; // Passes are not run on external methods! - for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Executing", *I, M); - Changed |= (*I)->runOnMethod(*MI); - } + return doInitialization(M->getParent()) | runOnMethod(M) + | doFinalization(M->getParent()); +} - for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); - I != E; ++I) { - PrintPassInformation("Finalizing", *I, M); - Changed |= (*I)->doFinalization(M); - } - return Changed; - } -}; +void MethodPass::addToPassManager(PassManagerT *PM, + AnalysisSet &Destroyed, + AnalysisSet &Provided) { + PM->addPass(this, Destroyed, Provided); +} -// add(BasicBlockPass*) - If we know it's a BasicBlockPass, we don't have to do -// any checking... -// -void PassManager::add(BasicBlockPass *BBP) { - if (Batcher == 0) // If we don't have a batcher yet, make one now. - add((MethodPass*)BBP); - else - Batcher->add(BBP); +void MethodPass::addToPassManager(PassManagerT *PM, + AnalysisSet &Destroyed, + AnalysisSet &Provided) { + PM->addPass(this, Destroyed, Provided); } +//===----------------------------------------------------------------------===// +// BasicBlockPass Implementation +// -// add(MethodPass*) - MethodPass's must be batched together... make sure this -// happens now. +// To run this pass on a method, we simply call runOnBasicBlock once for each +// method. // -void PassManager::add(MethodPass *MP) { - if (Batcher == 0) { // If we don't have a batcher yet, make one now. - Batcher = new MethodPassBatcher(); - Passes.push_back(Batcher); - } - Batcher->add(MP); // The Batcher will queue them passes up +bool BasicBlockPass::runOnMethod(Method *M) { + bool Changed = false; + for (Method::iterator I = M->begin(), E = M->end(); I != E; ++I) + Changed |= runOnBasicBlock(*I); + return Changed; } -// add - Add a pass to the PassManager, batching it up as appropriate... -void PassManager::add(Pass *P) { - if (MethodPass *MP = dynamic_cast(P)) { - add(MP); // Use the methodpass specific code to do the addition - } else { - Batcher = 0; // Ensure that passes don't get accidentally reordered - Passes.push_back(P); - } +// To run directly on the basic block, we initialize, runOnBasicBlock, then +// finalize. +// +bool BasicBlockPass::run(BasicBlock *BB) { + Module *M = BB->getParent()->getParent(); + return doInitialization(M) | runOnBasicBlock(BB) | doFinalization(M); } +void BasicBlockPass::addToPassManager(PassManagerT *PM, + AnalysisSet &Destroyed, + AnalysisSet &Provided) { + PM->addPass(this, Destroyed, Provided); +} -bool PassManager::run(Module *M) { - bool MadeChanges = false; - // Run all of the pass initializers - for (unsigned i = 0, e = Passes.size(); i < e; ++i) { - PrintPassInformation("Executing", Passes[i], M); - MadeChanges |= Passes[i]->run(M); - } - return MadeChanges; +void BasicBlockPass::addToPassManager(PassManagerT *PM, + AnalysisSet &Destroyed, + AnalysisSet &Provided) { + PM->addPass(this, Destroyed, Provided); } + -- cgit v1.2.3-18-g5258