Implementation of the new spiffy pass system
authorChris Lattner <sabre@nondot.org>
Mon, 21 Jan 2002 07:37:31 +0000 (07:37 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 21 Jan 2002 07:37:31 +0000 (07:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1508 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Pass.cpp [new file with mode: 0644]

diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
new file mode 100644 (file)
index 0000000..2f2fd0e
--- /dev/null
@@ -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);
+  }
+}