Skip to content

Commit 1bb5f8e

Browse files
committed
Add new Pass infrastructure and some examples
llvm-svn: 836
1 parent 97fd6c4 commit 1bb5f8e

File tree

6 files changed

+476
-0
lines changed

6 files changed

+476
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===- llvm/Transforms/LowerAllocations.h - Remove Malloc & Free -*- C++ -*--=//
2+
//
3+
// This file defines the interface to a pass that lowers malloc and free
4+
// instructions to calls to %malloc & %free functions. This transformation is
5+
// a target dependant tranformation because we depend on the size of data types
6+
// and alignment constraints.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_TRANSFORMS_LOWERALLOCATIONS_H
11+
#define LLVM_TRANSFORMS_LOWERALLOCATIONS_H
12+
13+
#include "llvm/Transforms/Pass.h"
14+
class TargetData;
15+
16+
class LowerAllocations : public ConcretePass<LowerAllocations> {
17+
Method *MallocMeth; // Methods in the module we are processing
18+
Method *FreeMeth; // Initialized by doPassInitializationVirt
19+
20+
const TargetData &DataLayout;
21+
public:
22+
inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
23+
MallocMeth = FreeMeth = 0;
24+
}
25+
26+
// doPassInitialization - For the lower allocations pass, this ensures that a
27+
// module contains a declaration for a malloc and a free function.
28+
//
29+
// This function is always successful.
30+
//
31+
bool doPassInitializationVirt(Module *M);
32+
33+
// doPerMethodWork - This method does the actual work of converting
34+
// instructions over, assuming that the pass has already been initialized.
35+
//
36+
bool doPerMethodWorkVirt(Method *M);
37+
};
38+
39+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===- llvm/Transforms/HoistPHIConstants.h - Normalize PHI nodes -*- C++ -*--=//
2+
//
3+
// HoistPHIConstants - Remove literal constants that are arguments of PHI nodes
4+
// by inserting cast instructions in the preceeding basic blocks, and changing
5+
// constant references into references of the casted value.
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_TRANSFORMS_HOISTPHICONSTANTS_H
10+
#define LLVM_TRANSFORMS_HOISTPHICONSTANTS_H
11+
12+
#include "llvm/Transforms/Pass.h"
13+
14+
struct HoistPHIConstants : public StatelessPass<HoistPHIConstants> {
15+
// doPerMethodWork - This method does the work. Always successful.
16+
//
17+
static bool doPerMethodWork(Method *M);
18+
};
19+
20+
#endif

llvm/include/llvm/Transforms/Pass.h

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//===- llvm/Transforms/Pass.h - Base class for XForm Passes ------*- C++ -*--=//
2+
//
3+
// This file defines a marker class that indicates that a specified class is a
4+
// transformation pass implementation.
5+
//
6+
// Pass's are designed this way so that it is possible to apply N passes to a
7+
// module, by first doing N Pass specific initializations for the module, then
8+
// looping over all of the methods in the module, doing method specific work
9+
// N times for each method. Like this:
10+
//
11+
// for_each(Passes.begin(), Passes.end(), doPassInitialization(Module));
12+
// for_each(Method *M <- Module->begin(), Module->end())
13+
// for_each(Passes.begin(), Passes.end(), doPerMethodWork(M));
14+
//
15+
// The other way to do things is like this:
16+
// for_each(Pass *P <- Passes.begin(), Passes.end()) {
17+
// Passes->doPassInitialization(Module)
18+
// for_each(Module->begin(), Module->end(), P->doPerMethodWork);
19+
// }
20+
//
21+
// But this can cause thrashing and poor cache performance, so we don't do it
22+
// that way.
23+
//
24+
// Because a transformation does not see all methods consecutively, it should
25+
// be careful about the state that it maintains... another pass may modify a
26+
// method between two invokacations of doPerMethodWork.
27+
//
28+
// Also, implementations of doMethodWork should not remove any methods from the
29+
// module.
30+
//
31+
//===----------------------------------------------------------------------===//
32+
33+
#ifndef LLVM_TRANSFORMS_PASS_H
34+
#define LLVM_TRANSFORMS_PASS_H
35+
36+
#include "llvm/Module.h"
37+
#include "llvm/Method.h"
38+
39+
//===----------------------------------------------------------------------===//
40+
// Pass interface - Implemented by all 'passes'.
41+
//
42+
struct Pass {
43+
//===--------------------------------------------------------------------===//
44+
// The externally useful entry points
45+
//
46+
47+
// runAllPasses - Run a bunch of passes on the specified module, efficiently.
48+
static bool runAllPasses(Module *M, vector<Pass*> &Passes) {
49+
for (unsigned i = 0; i < Passes.size(); ++i)
50+
if (Passes[i]->doPassInitializationVirt(M)) return true;
51+
52+
// Loop over all of the methods, applying all of the passes to them
53+
for (Module::iterator I = M->begin(); I != M->end(); ++I)
54+
for (unsigned i = 0; i < Passes.size(); ++i)
55+
if (Passes[i]->doPerMethodWorkVirt(*I)) return true;
56+
return false;
57+
}
58+
59+
// runAllPassesAndFree - Run a bunch of passes on the specified module,
60+
// efficiently. When done, delete all of the passes.
61+
//
62+
static bool runAllPassesAndFree(Module *M, vector<Pass*> &Passes) {
63+
// First run all of the passes
64+
bool Result = runAllPasses(M, Passes);
65+
66+
// Free all of the passes.
67+
for (unsigned i = 0; i < Passes.size(); ++i)
68+
delete Passes[i];
69+
return Result;
70+
}
71+
72+
73+
// run(Module*) - Run this pass on a module and all of the methods contained
74+
// within it. Returns false on success.
75+
//
76+
bool run(Module *M) {
77+
if (doPassInitializationVirt(M)) return true;
78+
79+
// Loop over methods in the module. doPerMethodWork could add a method to
80+
// the Module, so we have to keep checking for end of method list condition.
81+
//
82+
for (Module::iterator I = M->begin(); I != M->end(); ++I)
83+
if (doPerMethodWorkVirt(*I)) return true;
84+
return false;
85+
}
86+
87+
// run(Method*) - Run this pass on a module and one specific method. Returns
88+
// false on success.
89+
//
90+
bool run(Method *M) {
91+
if (doPassInitializationVirt(M->getParent())) return true;
92+
return doPerMethodWorkVirt(M);
93+
}
94+
95+
96+
//===--------------------------------------------------------------------===//
97+
// Functions to be implemented by subclasses
98+
//
99+
100+
// Destructor - Virtual so we can be subclassed
101+
inline virtual ~Pass() {}
102+
103+
// doPassInitializationVirt - Virtual method overridden by subclasses to do
104+
// any neccesary per-module initialization. Returns false on success.
105+
//
106+
virtual bool doPassInitializationVirt(Module *M) = 0;
107+
108+
// doPerMethodWorkVirt - Virtual method overriden by subclasses to do the
109+
// per-method processing of the pass. Returns false on success.
110+
//
111+
virtual bool doPerMethodWorkVirt(Method *M) = 0;
112+
};
113+
114+
115+
//===----------------------------------------------------------------------===//
116+
// ConcretePass<t> class - This is used by implementations of passes to fill in
117+
// boiler plate code. SubClass should be a concrete class that is derived from
118+
// ConcretePass.
119+
//
120+
// Deriving from this class is good because if new methods are added in the
121+
// future, code for your pass won't have to change to stub out the unused
122+
// functionality.
123+
//
124+
template<class SubClass>
125+
struct ConcretePass : public Pass {
126+
127+
// doPassInitializationVirt - Default to success.
128+
virtual bool doPassInitializationVirt(Module *M) { return false; }
129+
130+
// doPerMethodWorkVirt - Default to success.
131+
virtual bool doPerMethodWorkVirt(Method *M) { return false; }
132+
};
133+
134+
135+
136+
//===----------------------------------------------------------------------===//
137+
// StatelessPass<t> class - This is used by implementations of passes to fill in
138+
// boiler plate code. Subclassing this class indicates that a class has no
139+
// state to keep around, so it's safe to invoke static versions of functions.
140+
// This can be more efficient that using virtual function dispatch all of the
141+
// time.
142+
//
143+
// SubClass should be a concrete class that is derived from StatelessPass.
144+
//
145+
template<class SubClass>
146+
struct StatelessPass : public ConcretePass<SubClass> {
147+
148+
//===--------------------------------------------------------------------===//
149+
// The externally useful entry points - These are specialized to avoid the
150+
// overhead of virtual method invokations if
151+
//
152+
// run(Module*) - Run this pass on a module and all of the methods contained
153+
// within it. Returns false on success.
154+
//
155+
static bool run(Module *M) {
156+
if (doPassInitialization(M->getParent())) return true;
157+
158+
// Loop over methods in the module. doPerMethodWork could add a method to
159+
// the Module, so we have to keep checking for end of method list condition.
160+
//
161+
for (Module::iterator I = M->begin(); I != M->end(); ++I)
162+
if (doPerMethodWork(*I)) return true;
163+
return false;
164+
}
165+
166+
// run(Method*) - Run this pass on a module and one specific method. Returns
167+
// false on success.
168+
//
169+
static bool run(Method *M) {
170+
if (doPassInitialization(M->getParent())) return true;
171+
return doPerMethodWork(M);
172+
}
173+
174+
//===--------------------------------------------------------------------===//
175+
// Default static method implementations, these should be defined in SubClass
176+
177+
static bool doPassInitialization(Module *M) { return false; }
178+
static bool doPerMethodWork(Method *M) { return false; }
179+
180+
181+
//===--------------------------------------------------------------------===//
182+
// Virtual method forwarders...
183+
184+
// doPassInitializationVirt - For a StatelessPass, default to implementing in
185+
// terms of the static method.
186+
//
187+
virtual bool doPassInitializationVirt(Module *M) {
188+
return SubClass::doPassInitialization(M);
189+
}
190+
191+
// doPerMethodWorkVirt - For a StatelessPass, default to implementing in
192+
// terms of the static method.
193+
//
194+
virtual bool doPerMethodWorkVirt(Method *M) {
195+
return SubClass::doPerMethodWork(M);
196+
}
197+
};
198+
199+
#endif
200+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===- llvm/Transforms/PrintModulePass.h - Printing Pass ---------*- C++ -*--=//
2+
//
3+
// This file defines a simple pass to print out methods of a module as they are
4+
// processed.
5+
//
6+
//===----------------------------------------------------------------------===//
7+
8+
#ifndef LLVM_TRANSFORMS_PRINTMODULE_H
9+
#define LLVM_TRANSFORMS_PRINTMODULE_H
10+
11+
#include "llvm/Transforms/Pass.h"
12+
#include "llvm/Assembly/Writer.h"
13+
14+
class PrintModulePass : public ConcretePass<PrintModulePass> {
15+
string Banner; // String to print before each method
16+
ostream *Out; // ostream to print on
17+
bool DeleteStream; // Delete the ostream in our dtor?
18+
public:
19+
inline PrintModulePass(const string &B, ostream *o = &cout, bool DS = false)
20+
: Banner(B), Out(o), DeleteStream(DS) {}
21+
22+
~PrintModulePass() {
23+
if (DeleteStream) delete Out;
24+
}
25+
26+
// doPerMethodWork - This pass just prints a banner followed by the method as
27+
// it's processed.
28+
//
29+
bool doPerMethodWorkVirt(Method *M) {
30+
(*Out) << Banner << M;
31+
return false;
32+
}
33+
};
34+
35+
#endif
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===- llvm/Transforms/HoistPHIConstants.h - Normalize PHI nodes ------------=//
2+
//
3+
// HoistPHIConstants - Remove literal constants that are arguments of PHI nodes
4+
// by inserting cast instructions in the preceeding basic blocks, and changing
5+
// constant references into references of the casted value.
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Transforms/HoistPHIConstants.h"
10+
#include "llvm/iOther.h"
11+
#include "llvm/BasicBlock.h"
12+
#include "llvm/Method.h"
13+
#include <map>
14+
15+
typedef pair<BasicBlock *, Value*> BBConstTy;
16+
typedef map<BBConstTy, CastInst *> CachedCopyMap;
17+
18+
static Value *NormalizePhiOperand(PHINode *PN, Value *CPV,
19+
BasicBlock *Pred, CachedCopyMap &CopyCache) {
20+
21+
// Check if we've already inserted a copy for this constant in Pred
22+
// Note that `copyCache[Pred]' will create an empty vector the first time
23+
//
24+
CachedCopyMap::iterator CCI = CopyCache.find(BBConstTy(Pred, CPV));
25+
if (CCI != CopyCache.end()) return CCI->second;
26+
27+
// Create a copy instruction and add it to the cache...
28+
CastInst *Inst = new CastInst(CPV, CPV->getType());
29+
CopyCache.insert(make_pair(BBConstTy(Pred, CPV), Inst));
30+
31+
// Insert the copy just before the terminator inst of the predecessor BB
32+
assert(Pred->getTerminator() && "Degenerate BB encountered!");
33+
Pred->getInstList().insert(Pred->getInstList().end()-1, Inst);
34+
35+
return Inst;
36+
}
37+
38+
39+
//---------------------------------------------------------------------------
40+
// Entry point for normalizing constant args in PHIs
41+
//---------------------------------------------------------------------------
42+
43+
bool HoistPHIConstants::doPerMethodWork(Method *M) {
44+
CachedCopyMap Cache;
45+
46+
for (Method::iterator BI = M->begin(), BE = M->end(); BI != BE; ++BI)
47+
for (BasicBlock::iterator II = (*BI)->begin(); II != (*BI)->end(); ++II) {
48+
Instruction *Inst = *II;
49+
if (!isa<PHINode>(Inst)) break; // All PHIs occur at top of BB!
50+
51+
PHINode *PN = cast<PHINode>(Inst);
52+
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) {
53+
Value *Op = PN->getIncomingValue(i);
54+
if (isa<ConstPoolVal>(Op))
55+
PN->setIncomingValue(i,
56+
NormalizePhiOperand(PN, Op, PN->getIncomingBlock(i), Cache));
57+
}
58+
}
59+
60+
return false;
61+
}

0 commit comments

Comments
 (0)