5858#include " llvm/IR/Verifier.h"
5959#include " llvm/InitializePasses.h"
6060#include " llvm/Pass.h"
61+ #include " llvm/Transforms/Yk/LivenessAnalysis.h"
6162#include < map>
6263
6364#define DEBUG_TYPE " yk-control-point"
@@ -83,158 +84,14 @@ CallInst *findControlPointCall(Module &M) {
8384 return nullptr ;
8485
8586 // Find the call site of `yk_mt_control_point()`.
86- Value::user_iterator U = CtrlPoint->user_begin ();
87+ const Value::user_iterator U = CtrlPoint->user_begin ();
8788 if (U == CtrlPoint->user_end ())
8889 return nullptr ;
8990
9091 return cast<CallInst>(*U);
9192}
9293
93- // / Wrapper to make `std::set_difference` more concise.
94- // /
95- // / Store the difference between `S1` and `S2` into `Into`.
96- void vset_difference (const std::set<Value *> &S1, const std::set<Value *> &S2,
97- std::set<Value *> &Into) {
98- std::set_difference (S1.begin (), S1.end (), S2.begin (), S2.end (),
99- std::inserter (Into, Into.begin ()));
100- }
101-
102- // / Wrapper to make `std::set_union` more concise.
103- // /
104- // / Store the union of `S1` and `S2` into `Into`.
105- void vset_union (const std::set<Value *> &S1, const std::set<Value *> &S2,
106- std::set<Value *> &Into) {
107- std::set_union (S1.begin (), S1.end (), S2.begin (), S2.end (),
108- std::inserter (Into, Into.begin ()));
109- }
110-
11194namespace llvm {
112- // A liveness analysis for LLVM IR.
113- //
114- // This is based on the algorithm shown in Chapter 10 of the book:
115- //
116- // Modern Compiler Implementation in Java (2nd edition)
117- // by Andrew W. Appel
118- class LivenessAnalysis {
119- std::map<Instruction *, std::set<Value *>> In;
120-
121- // / Find the successor instructions of the specified instruction.
122- std::set<Instruction *> getSuccessorInstructions (Instruction *I) {
123- Instruction *Term = I->getParent ()->getTerminator ();
124- std::set<Instruction *> SuccInsts;
125- if (I != Term) {
126- // Non-terminating instruction: the sole successor instruction is the
127- // next instruction in the block.
128- SuccInsts.insert (I->getNextNode ());
129- } else {
130- // Terminating instruction: successor instructions are the first
131- // instructions of all successor blocks.
132- for (unsigned SuccIdx = 0 ; SuccIdx < Term->getNumSuccessors (); SuccIdx++)
133- SuccInsts.insert (&*Term->getSuccessor (SuccIdx)->begin ());
134- }
135- return SuccInsts;
136- }
137-
138- // / Replaces the value set behind the pointer `S` with the value set `R` and
139- // / returns whether the set behind `S` changed.
140- bool updateValueSet (std::set<Value *> *S, const std::set<Value *> R) {
141- bool Changed = (*S != R);
142- *S = R;
143- return Changed;
144- }
145-
146- public:
147- LivenessAnalysis (Function *Func) {
148- // Compute defs and uses for each instruction.
149- std::map<Instruction *, std::set<Value *>> Defs;
150- std::map<Instruction *, std::set<Value *>> Uses;
151- for (BasicBlock &BB : *Func) {
152- for (Instruction &I : BB) {
153- // Record what this instruction defines.
154- if (!I.getType ()->isVoidTy ())
155- Defs[&I].insert (cast<Value>(&I));
156-
157- // Record what this instruction uses.
158- //
159- // Note that Phi nodes are special and must be skipped. If we consider
160- // their operands as uses, then Phi nodes in loops may use variables
161- // before they are defined, and this messes with the algorithm.
162- //
163- // The book doesn't cover this quirk, as it explains liveness for
164- // non-SSA form, and thus doesn't need to worry about Phi nodes.
165- if (isa<PHINode>(I))
166- continue ;
167-
168- for (auto *U = I.op_begin (); U < I.op_end (); U++) {
169- if ((!isa<Constant>(U)) && (!isa<BasicBlock>(U)) &&
170- (!isa<MetadataAsValue>(U)) && (!isa<InlineAsm>(U))) {
171- Uses[&I].insert (*U);
172- }
173- }
174- }
175- }
176-
177- // A function implicitly defines its arguments.
178- //
179- // To propagate the arguments properly we pretend that the first instruction
180- // in the entry block defines the arguments.
181- Instruction *FirstInst = &*Func->getEntryBlock ().begin ();
182- for (auto &Arg : Func->args ())
183- Defs[FirstInst].insert (&Arg);
184-
185- // Compute the live sets for each instruction.
186- //
187- // This is the fixed-point of the following data-flow equations (page 206
188- // in the book referenced above):
189- //
190- // in[I] = use[I] ∪ (out[I] - def[I])
191- //
192- // out[I] = ∪
193- // (S in succ[I]) in[S]
194- //
195- // Note that only the `In` map is kept after this constructor ends, so
196- // only `In` is a field.
197- std::map<Instruction *, std::set<Value *>> Out;
198- bool Changed;
199- do {
200- Changed = false ;
201- // As the book explains, fixed-points are reached quicker if we process
202- // control flow in "approximately reverse direction" and if we compute
203- // `out[I]` before `in[I]`.
204- //
205- // Because the alrogithm works by propagating liveness from use sites
206- // backwards to def sites (where liveness is killed), by working
207- // backwards we are able to propagate long runs of liveness in one
208- // iteration of the algorithm.
209- for (BasicBlock *BB : post_order (&*Func)) {
210- for (BasicBlock::reverse_iterator II = BB->rbegin (); II != BB->rend ();
211- II++) {
212- Instruction *I = &*II;
213- // Update out[I].
214- std::set<Instruction *> SuccInsts = getSuccessorInstructions (I);
215- std::set<Value *> NewOut;
216- for (Instruction *SI : SuccInsts) {
217- NewOut.insert (In[SI].begin (), In[SI].end ());
218- }
219- Changed |= updateValueSet (&Out[I], std::move (NewOut));
220-
221- // Update in[I].
222- std::set<Value *> OutMinusDef;
223- vset_difference (Out[I], Defs[I], OutMinusDef);
224-
225- std::set<Value *> NewIn;
226- vset_union (Uses[I], OutMinusDef, NewIn);
227- Changed |= updateValueSet (&In[I], std::move (NewIn));
228- }
229- }
230- } while (Changed); // Until a fixed-point.
231- }
232-
233- // / Returns the set of live variables immediately before the specified
234- // / instruction.
235- std::set<Value *> getLiveVarsBefore (Instruction *I) { return In[I]; }
236- };
237-
23895void initializeYkControlPointPass (PassRegistry &);
23996} // namespace llvm
24097
@@ -273,7 +130,7 @@ class YkControlPoint : public ModulePass {
273130
274131 // Find all live variables just before the call to the control point.
275132 LivenessAnalysis LA (OldCtrlPointCall->getFunction ());
276- std::set<Value *> LiveVals = LA.getLiveVarsBefore (OldCtrlPointCall);
133+ const std::set<Value *> LiveVals = LA.getLiveVarsBefore (OldCtrlPointCall);
277134 if (LiveVals.size () == 0 ) {
278135 Context.emitError (
279136 " The interpreter loop has no live variables!\n "
0 commit comments