Implementation of the new spiffy pass system
[oota-llvm.git] / lib / VMCore / Pass.cpp
1 //===- Pass.cpp - LLVM Pass Infrastructure Impementation ------------------===//
2 //
3 // This file implements the LLVM Pass infrastructure.  It is primarily
4 // responsible with ensuring that passes are executed and batched together
5 // optimally.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Pass.h"
10 #include "Support/STLExtras.h"
11
12 PassManager::~PassManager() {
13   for_each(Passes.begin(), Passes.end(), deleter<Pass>);
14 }
15
16 class BasicBlockPassBatcher : public MethodPass {
17   typedef std::vector<BasicBlockPass*> SubPassesType;
18   SubPassesType SubPasses;
19 public:
20   ~BasicBlockPassBatcher() {
21     for_each(SubPasses.begin(), SubPasses.end(), deleter<BasicBlockPass>);
22   }
23
24   void add(BasicBlockPass *P) { SubPasses.push_back(P); }
25
26   virtual bool doPassInitialization(Module *M) {
27     bool Changed = false;
28     for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
29          I != E; ++I)
30       Changed |= (*I)->doInitialization(M);
31     return Changed;
32   }
33
34   virtual bool runOnMethod(Method *M) {
35     bool Changed = false;
36
37     for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
38       for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
39            I != E; ++I)
40         Changed |= (*I)->runOnBasicBlock(*MI);
41     return Changed;
42   }
43
44   virtual bool doFinalization(Module *M) {
45     bool Changed = false;
46     for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
47          I != E; ++I)
48       Changed |= (*I)->doFinalization(M);
49
50     return Changed;
51   }
52 };
53
54 class MethodPassBatcher : public Pass {
55   typedef std::vector<MethodPass*> SubPassesType;
56   SubPassesType SubPasses;
57   BasicBlockPassBatcher *BBPBatcher;
58 public:
59   ~MethodPassBatcher() {
60     for_each(SubPasses.begin(), SubPasses.end(), deleter<MethodPass>);
61   }
62
63   void add(MethodPass *P) {
64     if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P)) {
65       if (BBPBatcher == 0) {
66         BBPBatcher = new BasicBlockPassBatcher();
67         SubPasses.push_back(BBPBatcher);
68       }
69       BBPBatcher->add(BBP);
70     } else {
71       BBPBatcher = 0;  // Ensure that passes don't get accidentally reordered
72       SubPasses.push_back(P);
73     }
74   }
75
76   virtual bool run(Module *M) {
77     bool Changed = false;
78     for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
79          I != E; ++I)
80       Changed |= (*I)->doInitialization(M);
81
82     for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
83       for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
84            I != E; ++I)
85         Changed |= (*I)->runOnMethod(*MI);
86
87     for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
88          I != E; ++I)
89       Changed |= (*I)->doFinalization(M);
90
91     return Changed;
92   }
93 };
94
95
96
97
98 // add(MethodPass*) - MethodPass's must be batched together... make sure this
99 // happens now.
100 //
101 void PassManager::add(MethodPass *MP) {
102   if (Batcher == 0) { // If we don't have a batcher yet, make one now.
103     Batcher = new MethodPassBatcher();
104     Passes.push_back(Batcher);
105   }
106   Batcher->add(MP);   // The Batcher will queue them passes up
107 }
108
109 // add - Add a pass to the PassManager, batching it up as appropriate...
110 void PassManager::add(Pass *P) {
111   if (MethodPass *MP = dynamic_cast<MethodPass*>(P)) {
112     add(MP);  // Use the methodpass specific code to do the addition
113   } else {
114     Batcher = 0;  // Ensure that passes don't get accidentally reordered
115     Passes.push_back(P);
116   }
117 }