1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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);
}
}
|