//===- Pass.cpp - LLVM Pass Infrastructure Impementation ------------------===// // // This file implements the LLVM Pass infrastructure. It is primarily // responsible with ensuring that passes are executed and batched together // optimally. // //===----------------------------------------------------------------------===// #include "llvm/Pass.h" #include "Support/STLExtras.h" PassManager::~PassManager() { for_each(Passes.begin(), Passes.end(), deleter); } class BasicBlockPassBatcher : public MethodPass { typedef std::vector SubPassesType; SubPassesType SubPasses; public: ~BasicBlockPassBatcher() { for_each(SubPasses.begin(), SubPasses.end(), deleter); } void add(BasicBlockPass *P) { SubPasses.push_back(P); } virtual bool doPassInitialization(Module *M) { bool Changed = false; for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); I != E; ++I) Changed |= (*I)->doInitialization(M); return Changed; } virtual bool runOnMethod(Method *M) { bool Changed = false; for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); I != E; ++I) 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) Changed |= (*I)->doFinalization(M); return Changed; } }; class MethodPassBatcher : public Pass { typedef std::vector SubPassesType; SubPassesType SubPasses; BasicBlockPassBatcher *BBPBatcher; public: ~MethodPassBatcher() { for_each(SubPasses.begin(), SubPasses.end(), deleter); } void add(BasicBlockPass *BBP) { if (BBPBatcher == 0) { BBPBatcher = new BasicBlockPassBatcher(); SubPasses.push_back(BBPBatcher); } BBPBatcher->add(BBP); } 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); } } virtual bool run(Module *M) { bool Changed = false; for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); I != E; ++I) Changed |= (*I)->doInitialization(M); for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); I != E; ++I) Changed |= (*I)->runOnMethod(*MI); for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end(); I != E; ++I) Changed |= (*I)->doFinalization(M); return Changed; } }; // 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); } // add(MethodPass*) - MethodPass's must be batched together... make sure this // happens now. // 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 } // 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); } }