aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore/Pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore/Pass.cpp')
-rw-r--r--lib/VMCore/Pass.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
new file mode 100644
index 0000000000..2f2fd0e211
--- /dev/null
+++ b/lib/VMCore/Pass.cpp
@@ -0,0 +1,117 @@
+//===- 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<Pass>);
+}
+
+class BasicBlockPassBatcher : public MethodPass {
+ typedef std::vector<BasicBlockPass*> SubPassesType;
+ SubPassesType SubPasses;
+public:
+ ~BasicBlockPassBatcher() {
+ for_each(SubPasses.begin(), SubPasses.end(), deleter<BasicBlockPass>);
+ }
+
+ 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<MethodPass*> SubPassesType;
+ SubPassesType SubPasses;
+ BasicBlockPassBatcher *BBPBatcher;
+public:
+ ~MethodPassBatcher() {
+ for_each(SubPasses.begin(), SubPasses.end(), deleter<MethodPass>);
+ }
+
+ void add(MethodPass *P) {
+ if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P)) {
+ if (BBPBatcher == 0) {
+ BBPBatcher = new BasicBlockPassBatcher();
+ SubPasses.push_back(BBPBatcher);
+ }
+ BBPBatcher->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(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<MethodPass*>(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);
+ }
+}