Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison include/llvm/Analysis/SparsePropagation.h @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H | 15 #ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H |
16 #define LLVM_ANALYSIS_SPARSEPROPAGATION_H | 16 #define LLVM_ANALYSIS_SPARSEPROPAGATION_H |
17 | 17 |
18 #include "llvm/ADT/DenseMap.h" | 18 #include "llvm/IR/Instructions.h" |
19 #include "llvm/ADT/SmallPtrSet.h" | 19 #include "llvm/Support/Debug.h" |
20 #include "llvm/IR/BasicBlock.h" | |
21 #include <set> | 20 #include <set> |
22 #include <vector> | 21 |
22 #define DEBUG_TYPE "sparseprop" | |
23 | 23 |
24 namespace llvm { | 24 namespace llvm { |
25 class Value; | 25 |
26 class Constant; | 26 /// A template for translating between LLVM Values and LatticeKeys. Clients must |
27 class Argument; | 27 /// provide a specialization of LatticeKeyInfo for their LatticeKey type. |
28 class Instruction; | 28 template <class LatticeKey> struct LatticeKeyInfo { |
29 class PHINode; | 29 // static inline Value *getValueFromLatticeKey(LatticeKey Key); |
30 class TerminatorInst; | 30 // static inline LatticeKey getLatticeKeyFromValue(Value *V); |
31 class BasicBlock; | 31 }; |
32 class Function; | 32 |
33 template <class LatticeKey, class LatticeVal, | |
34 class KeyInfo = LatticeKeyInfo<LatticeKey>> | |
33 class SparseSolver; | 35 class SparseSolver; |
34 class raw_ostream; | |
35 | |
36 template <typename T> class SmallVectorImpl; | |
37 | 36 |
38 /// AbstractLatticeFunction - This class is implemented by the dataflow instance | 37 /// AbstractLatticeFunction - This class is implemented by the dataflow instance |
39 /// to specify what the lattice values are and how they handle merges etc. | 38 /// to specify what the lattice values are and how they handle merges etc. This |
40 /// This gives the client the power to compute lattice values from instructions, | 39 /// gives the client the power to compute lattice values from instructions, |
41 /// constants, etc. The requirement is that lattice values must all fit into | 40 /// constants, etc. The current requirement is that lattice values must be |
42 /// a void*. If a void* is not sufficient, the implementation should use this | 41 /// copyable. At the moment, nothing tries to avoid copying. Additionally, |
43 /// pointer to be a pointer into a uniquing set or something. | 42 /// lattice keys must be able to be used as keys of a mapping data structure. |
44 /// | 43 /// Internally, the generic solver currently uses a DenseMap to map lattice keys |
45 class AbstractLatticeFunction { | 44 /// to lattice values. If the lattice key is a non-standard type, a |
46 public: | 45 /// specialization of DenseMapInfo must be provided. |
47 typedef void *LatticeVal; | 46 template <class LatticeKey, class LatticeVal> class AbstractLatticeFunction { |
48 | |
49 private: | 47 private: |
50 LatticeVal UndefVal, OverdefinedVal, UntrackedVal; | 48 LatticeVal UndefVal, OverdefinedVal, UntrackedVal; |
51 | 49 |
52 public: | 50 public: |
53 AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal, | 51 AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal, |
54 LatticeVal untrackedVal) { | 52 LatticeVal untrackedVal) { |
55 UndefVal = undefVal; | 53 UndefVal = undefVal; |
56 OverdefinedVal = overdefinedVal; | 54 OverdefinedVal = overdefinedVal; |
57 UntrackedVal = untrackedVal; | 55 UntrackedVal = untrackedVal; |
58 } | 56 } |
59 virtual ~AbstractLatticeFunction(); | 57 |
58 virtual ~AbstractLatticeFunction() = default; | |
60 | 59 |
61 LatticeVal getUndefVal() const { return UndefVal; } | 60 LatticeVal getUndefVal() const { return UndefVal; } |
62 LatticeVal getOverdefinedVal() const { return OverdefinedVal; } | 61 LatticeVal getOverdefinedVal() const { return OverdefinedVal; } |
63 LatticeVal getUntrackedVal() const { return UntrackedVal; } | 62 LatticeVal getUntrackedVal() const { return UntrackedVal; } |
64 | 63 |
65 /// IsUntrackedValue - If the specified Value is something that is obviously | 64 /// IsUntrackedValue - If the specified LatticeKey is obviously uninteresting |
66 /// uninteresting to the analysis (and would always return UntrackedVal), | 65 /// to the analysis (i.e., it would always return UntrackedVal), this |
67 /// this function can return true to avoid pointless work. | 66 /// function can return true to avoid pointless work. |
68 virtual bool IsUntrackedValue(Value *V) { return false; } | 67 virtual bool IsUntrackedValue(LatticeKey Key) { return false; } |
69 | 68 |
70 /// ComputeConstant - Given a constant value, compute and return a lattice | 69 /// ComputeLatticeVal - Compute and return a LatticeVal corresponding to the |
71 /// value corresponding to the specified constant. | 70 /// given LatticeKey. |
72 virtual LatticeVal ComputeConstant(Constant *C) { | 71 virtual LatticeVal ComputeLatticeVal(LatticeKey Key) { |
73 return getOverdefinedVal(); // always safe | 72 return getOverdefinedVal(); |
74 } | 73 } |
75 | 74 |
76 /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is | 75 /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is |
77 /// one that the we want to handle through ComputeInstructionState. | 76 /// one that the we want to handle through ComputeInstructionState. |
78 virtual bool IsSpecialCasedPHI(PHINode *PN) { return false; } | 77 virtual bool IsSpecialCasedPHI(PHINode *PN) { return false; } |
79 | |
80 /// GetConstant - If the specified lattice value is representable as an LLVM | |
81 /// constant value, return it. Otherwise return null. The returned value | |
82 /// must be in the same LLVM type as Val. | |
83 virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) { | |
84 return nullptr; | |
85 } | |
86 | |
87 /// ComputeArgument - Given a formal argument value, compute and return a | |
88 /// lattice value corresponding to the specified argument. | |
89 virtual LatticeVal ComputeArgument(Argument *I) { | |
90 return getOverdefinedVal(); // always safe | |
91 } | |
92 | 78 |
93 /// MergeValues - Compute and return the merge of the two specified lattice | 79 /// MergeValues - Compute and return the merge of the two specified lattice |
94 /// values. Merging should only move one direction down the lattice to | 80 /// values. Merging should only move one direction down the lattice to |
95 /// guarantee convergence (toward overdefined). | 81 /// guarantee convergence (toward overdefined). |
96 virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) { | 82 virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) { |
97 return getOverdefinedVal(); // always safe, never useful. | 83 return getOverdefinedVal(); // always safe, never useful. |
98 } | 84 } |
99 | 85 |
100 /// ComputeInstructionState - Given an instruction and a vector of its operand | 86 /// ComputeInstructionState - Compute the LatticeKeys that change as a result |
101 /// values, compute the result value of the instruction. | 87 /// of executing instruction \p I. Their associated LatticeVals are store in |
102 virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) { | 88 /// \p ChangedValues. |
103 return getOverdefinedVal(); // always safe, never useful. | 89 virtual void |
104 } | 90 ComputeInstructionState(Instruction &I, |
105 | 91 DenseMap<LatticeKey, LatticeVal> &ChangedValues, |
106 /// PrintValue - Render the specified lattice value to the specified stream. | 92 SparseSolver<LatticeKey, LatticeVal> &SS) = 0; |
107 virtual void PrintValue(LatticeVal V, raw_ostream &OS); | 93 |
94 /// PrintLatticeVal - Render the given LatticeVal to the specified stream. | |
95 virtual void PrintLatticeVal(LatticeVal LV, raw_ostream &OS); | |
96 | |
97 /// PrintLatticeKey - Render the given LatticeKey to the specified stream. | |
98 virtual void PrintLatticeKey(LatticeKey Key, raw_ostream &OS); | |
99 | |
100 /// GetValueFromLatticeVal - If the given LatticeVal is representable as an | |
101 /// LLVM value, return it; otherwise, return nullptr. If a type is given, the | |
102 /// returned value must have the same type. This function is used by the | |
103 /// generic solver in attempting to resolve branch and switch conditions. | |
104 virtual Value *GetValueFromLatticeVal(LatticeVal LV, Type *Ty = nullptr) { | |
105 return nullptr; | |
106 } | |
108 }; | 107 }; |
109 | 108 |
110 /// SparseSolver - This class is a general purpose solver for Sparse Conditional | 109 /// SparseSolver - This class is a general purpose solver for Sparse Conditional |
111 /// Propagation with a programmable lattice function. | 110 /// Propagation with a programmable lattice function. |
112 /// | 111 template <class LatticeKey, class LatticeVal, class KeyInfo> |
113 class SparseSolver { | 112 class SparseSolver { |
114 typedef AbstractLatticeFunction::LatticeVal LatticeVal; | 113 |
115 | 114 /// LatticeFunc - This is the object that knows the lattice and how to |
116 /// LatticeFunc - This is the object that knows the lattice and how to do | |
117 /// compute transfer functions. | 115 /// compute transfer functions. |
118 AbstractLatticeFunction *LatticeFunc; | 116 AbstractLatticeFunction<LatticeKey, LatticeVal> *LatticeFunc; |
119 | 117 |
120 DenseMap<Value *, LatticeVal> ValueState; // The state each value is in. | 118 /// ValueState - Holds the LatticeVals associated with LatticeKeys. |
121 SmallPtrSet<BasicBlock *, 16> BBExecutable; // The bbs that are executable. | 119 DenseMap<LatticeKey, LatticeVal> ValueState; |
122 | 120 |
123 std::vector<Instruction *> InstWorkList; // Worklist of insts to process. | 121 /// BBExecutable - Holds the basic blocks that are executable. |
124 | 122 SmallPtrSet<BasicBlock *, 16> BBExecutable; |
125 std::vector<BasicBlock *> BBWorkList; // The BasicBlock work list | 123 |
124 /// ValueWorkList - Holds values that should be processed. | |
125 SmallVector<Value *, 64> ValueWorkList; | |
126 | |
127 /// BBWorkList - Holds basic blocks that should be processed. | |
128 SmallVector<BasicBlock *, 64> BBWorkList; | |
129 | |
130 using Edge = std::pair<BasicBlock *, BasicBlock *>; | |
126 | 131 |
127 /// KnownFeasibleEdges - Entries in this set are edges which have already had | 132 /// KnownFeasibleEdges - Entries in this set are edges which have already had |
128 /// PHI nodes retriggered. | 133 /// PHI nodes retriggered. |
129 typedef std::pair<BasicBlock*,BasicBlock*> Edge; | |
130 std::set<Edge> KnownFeasibleEdges; | 134 std::set<Edge> KnownFeasibleEdges; |
131 | 135 |
132 SparseSolver(const SparseSolver&) = delete; | |
133 void operator=(const SparseSolver&) = delete; | |
134 | |
135 public: | 136 public: |
136 explicit SparseSolver(AbstractLatticeFunction *Lattice) | 137 explicit SparseSolver( |
138 AbstractLatticeFunction<LatticeKey, LatticeVal> *Lattice) | |
137 : LatticeFunc(Lattice) {} | 139 : LatticeFunc(Lattice) {} |
138 ~SparseSolver() { delete LatticeFunc; } | 140 SparseSolver(const SparseSolver &) = delete; |
141 SparseSolver &operator=(const SparseSolver &) = delete; | |
139 | 142 |
140 /// Solve - Solve for constants and executable blocks. | 143 /// Solve - Solve for constants and executable blocks. |
141 /// | 144 void Solve(); |
142 void Solve(Function &F); | 145 |
143 | 146 void Print(raw_ostream &OS) const; |
144 void Print(Function &F, raw_ostream &OS) const; | 147 |
145 | 148 /// getExistingValueState - Return the LatticeVal object corresponding to the |
146 /// getLatticeState - Return the LatticeVal object that corresponds to the | 149 /// given value from the ValueState map. If the value is not in the map, |
147 /// value. If an value is not in the map, it is returned as untracked, | 150 /// UntrackedVal is returned, unlike the getValueState method. |
148 /// unlike the getOrInitValueState method. | 151 LatticeVal getExistingValueState(LatticeKey Key) const { |
149 LatticeVal getLatticeState(Value *V) const { | 152 auto I = ValueState.find(Key); |
150 DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V); | |
151 return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal(); | 153 return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal(); |
152 } | 154 } |
153 | 155 |
154 /// getOrInitValueState - Return the LatticeVal object that corresponds to the | 156 /// getValueState - Return the LatticeVal object corresponding to the given |
155 /// value, initializing the value's state if it hasn't been entered into the | 157 /// value from the ValueState map. If the value is not in the map, its state |
156 /// map yet. This function is necessary because not all values should start | 158 /// is initialized. |
157 /// out in the underdefined state... Arguments should be overdefined, and | 159 LatticeVal getValueState(LatticeKey Key); |
158 /// constants should be marked as constants. | |
159 /// | |
160 LatticeVal getOrInitValueState(Value *V); | |
161 | 160 |
162 /// isEdgeFeasible - Return true if the control flow edge from the 'From' | 161 /// isEdgeFeasible - Return true if the control flow edge from the 'From' |
163 /// basic block to the 'To' basic block is currently feasible. If | 162 /// basic block to the 'To' basic block is currently feasible. If |
164 /// AggressiveUndef is true, then this treats values with unknown lattice | 163 /// AggressiveUndef is true, then this treats values with unknown lattice |
165 /// values as undefined. This is generally only useful when solving the | 164 /// values as undefined. This is generally only useful when solving the |
172 /// querying the lattice. | 171 /// querying the lattice. |
173 bool isBlockExecutable(BasicBlock *BB) const { | 172 bool isBlockExecutable(BasicBlock *BB) const { |
174 return BBExecutable.count(BB); | 173 return BBExecutable.count(BB); |
175 } | 174 } |
176 | 175 |
177 private: | |
178 /// UpdateState - When the state for some instruction is potentially updated, | |
179 /// this function notices and adds I to the worklist if needed. | |
180 void UpdateState(Instruction &Inst, LatticeVal V); | |
181 | |
182 /// MarkBlockExecutable - This method can be used by clients to mark all of | 176 /// MarkBlockExecutable - This method can be used by clients to mark all of |
183 /// the blocks that are known to be intrinsically live in the processed unit. | 177 /// the blocks that are known to be intrinsically live in the processed unit. |
184 void MarkBlockExecutable(BasicBlock *BB); | 178 void MarkBlockExecutable(BasicBlock *BB); |
179 | |
180 private: | |
181 /// UpdateState - When the state of some LatticeKey is potentially updated to | |
182 /// the given LatticeVal, this function notices and adds the LLVM value | |
183 /// corresponding the key to the work list, if needed. | |
184 void UpdateState(LatticeKey Key, LatticeVal LV); | |
185 | 185 |
186 /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB | 186 /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB |
187 /// work list if it is not already executable. | 187 /// work list if it is not already executable. |
188 void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest); | 188 void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest); |
189 | 189 |
195 void visitInst(Instruction &I); | 195 void visitInst(Instruction &I); |
196 void visitPHINode(PHINode &I); | 196 void visitPHINode(PHINode &I); |
197 void visitTerminatorInst(TerminatorInst &TI); | 197 void visitTerminatorInst(TerminatorInst &TI); |
198 }; | 198 }; |
199 | 199 |
200 //===----------------------------------------------------------------------===// | |
201 // AbstractLatticeFunction Implementation | |
202 //===----------------------------------------------------------------------===// | |
203 | |
204 template <class LatticeKey, class LatticeVal> | |
205 void AbstractLatticeFunction<LatticeKey, LatticeVal>::PrintLatticeVal( | |
206 LatticeVal V, raw_ostream &OS) { | |
207 if (V == UndefVal) | |
208 OS << "undefined"; | |
209 else if (V == OverdefinedVal) | |
210 OS << "overdefined"; | |
211 else if (V == UntrackedVal) | |
212 OS << "untracked"; | |
213 else | |
214 OS << "unknown lattice value"; | |
215 } | |
216 | |
217 template <class LatticeKey, class LatticeVal> | |
218 void AbstractLatticeFunction<LatticeKey, LatticeVal>::PrintLatticeKey( | |
219 LatticeKey Key, raw_ostream &OS) { | |
220 OS << "unknown lattice key"; | |
221 } | |
222 | |
223 //===----------------------------------------------------------------------===// | |
224 // SparseSolver Implementation | |
225 //===----------------------------------------------------------------------===// | |
226 | |
227 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
228 LatticeVal | |
229 SparseSolver<LatticeKey, LatticeVal, KeyInfo>::getValueState(LatticeKey Key) { | |
230 auto I = ValueState.find(Key); | |
231 if (I != ValueState.end()) | |
232 return I->second; // Common case, in the map | |
233 | |
234 if (LatticeFunc->IsUntrackedValue(Key)) | |
235 return LatticeFunc->getUntrackedVal(); | |
236 LatticeVal LV = LatticeFunc->ComputeLatticeVal(Key); | |
237 | |
238 // If this value is untracked, don't add it to the map. | |
239 if (LV == LatticeFunc->getUntrackedVal()) | |
240 return LV; | |
241 return ValueState[Key] = LV; | |
242 } | |
243 | |
244 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
245 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::UpdateState(LatticeKey Key, | |
246 LatticeVal LV) { | |
247 auto I = ValueState.find(Key); | |
248 if (I != ValueState.end() && I->second == LV) | |
249 return; // No change. | |
250 | |
251 // Update the state of the given LatticeKey and add its corresponding LLVM | |
252 // value to the work list. | |
253 ValueState[Key] = LV; | |
254 if (Value *V = KeyInfo::getValueFromLatticeKey(Key)) | |
255 ValueWorkList.push_back(V); | |
256 } | |
257 | |
258 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
259 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::MarkBlockExecutable( | |
260 BasicBlock *BB) { | |
261 if (!BBExecutable.insert(BB).second) | |
262 return; | |
263 DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << "\n"); | |
264 BBWorkList.push_back(BB); // Add the block to the work list! | |
265 } | |
266 | |
267 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
268 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::markEdgeExecutable( | |
269 BasicBlock *Source, BasicBlock *Dest) { | |
270 if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second) | |
271 return; // This edge is already known to be executable! | |
272 | |
273 DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName() << " -> " | |
274 << Dest->getName() << "\n"); | |
275 | |
276 if (BBExecutable.count(Dest)) { | |
277 // The destination is already executable, but we just made an edge | |
278 // feasible that wasn't before. Revisit the PHI nodes in the block | |
279 // because they have potentially new operands. | |
280 for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I) | |
281 visitPHINode(*cast<PHINode>(I)); | |
282 } else { | |
283 MarkBlockExecutable(Dest); | |
284 } | |
285 } | |
286 | |
287 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
288 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::getFeasibleSuccessors( | |
289 TerminatorInst &TI, SmallVectorImpl<bool> &Succs, bool AggressiveUndef) { | |
290 Succs.resize(TI.getNumSuccessors()); | |
291 if (TI.getNumSuccessors() == 0) | |
292 return; | |
293 | |
294 if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) { | |
295 if (BI->isUnconditional()) { | |
296 Succs[0] = true; | |
297 return; | |
298 } | |
299 | |
300 LatticeVal BCValue; | |
301 if (AggressiveUndef) | |
302 BCValue = | |
303 getValueState(KeyInfo::getLatticeKeyFromValue(BI->getCondition())); | |
304 else | |
305 BCValue = getExistingValueState( | |
306 KeyInfo::getLatticeKeyFromValue(BI->getCondition())); | |
307 | |
308 if (BCValue == LatticeFunc->getOverdefinedVal() || | |
309 BCValue == LatticeFunc->getUntrackedVal()) { | |
310 // Overdefined condition variables can branch either way. | |
311 Succs[0] = Succs[1] = true; | |
312 return; | |
313 } | |
314 | |
315 // If undefined, neither is feasible yet. | |
316 if (BCValue == LatticeFunc->getUndefVal()) | |
317 return; | |
318 | |
319 Constant *C = | |
320 dyn_cast_or_null<Constant>(LatticeFunc->GetValueFromLatticeVal( | |
321 BCValue, BI->getCondition()->getType())); | |
322 if (!C || !isa<ConstantInt>(C)) { | |
323 // Non-constant values can go either way. | |
324 Succs[0] = Succs[1] = true; | |
325 return; | |
326 } | |
327 | |
328 // Constant condition variables mean the branch can only go a single way | |
329 Succs[C->isNullValue()] = true; | |
330 return; | |
331 } | |
332 | |
333 if (TI.isExceptional()) { | |
334 Succs.assign(Succs.size(), true); | |
335 return; | |
336 } | |
337 | |
338 if (isa<IndirectBrInst>(TI)) { | |
339 Succs.assign(Succs.size(), true); | |
340 return; | |
341 } | |
342 | |
343 SwitchInst &SI = cast<SwitchInst>(TI); | |
344 LatticeVal SCValue; | |
345 if (AggressiveUndef) | |
346 SCValue = getValueState(KeyInfo::getLatticeKeyFromValue(SI.getCondition())); | |
347 else | |
348 SCValue = getExistingValueState( | |
349 KeyInfo::getLatticeKeyFromValue(SI.getCondition())); | |
350 | |
351 if (SCValue == LatticeFunc->getOverdefinedVal() || | |
352 SCValue == LatticeFunc->getUntrackedVal()) { | |
353 // All destinations are executable! | |
354 Succs.assign(TI.getNumSuccessors(), true); | |
355 return; | |
356 } | |
357 | |
358 // If undefined, neither is feasible yet. | |
359 if (SCValue == LatticeFunc->getUndefVal()) | |
360 return; | |
361 | |
362 Constant *C = dyn_cast_or_null<Constant>(LatticeFunc->GetValueFromLatticeVal( | |
363 SCValue, SI.getCondition()->getType())); | |
364 if (!C || !isa<ConstantInt>(C)) { | |
365 // All destinations are executable! | |
366 Succs.assign(TI.getNumSuccessors(), true); | |
367 return; | |
368 } | |
369 SwitchInst::CaseHandle Case = *SI.findCaseValue(cast<ConstantInt>(C)); | |
370 Succs[Case.getSuccessorIndex()] = true; | |
371 } | |
372 | |
373 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
374 bool SparseSolver<LatticeKey, LatticeVal, KeyInfo>::isEdgeFeasible( | |
375 BasicBlock *From, BasicBlock *To, bool AggressiveUndef) { | |
376 SmallVector<bool, 16> SuccFeasible; | |
377 TerminatorInst *TI = From->getTerminator(); | |
378 getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef); | |
379 | |
380 for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) | |
381 if (TI->getSuccessor(i) == To && SuccFeasible[i]) | |
382 return true; | |
383 | |
384 return false; | |
385 } | |
386 | |
387 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
388 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitTerminatorInst( | |
389 TerminatorInst &TI) { | |
390 SmallVector<bool, 16> SuccFeasible; | |
391 getFeasibleSuccessors(TI, SuccFeasible, true); | |
392 | |
393 BasicBlock *BB = TI.getParent(); | |
394 | |
395 // Mark all feasible successors executable... | |
396 for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i) | |
397 if (SuccFeasible[i]) | |
398 markEdgeExecutable(BB, TI.getSuccessor(i)); | |
399 } | |
400 | |
401 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
402 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitPHINode(PHINode &PN) { | |
403 // The lattice function may store more information on a PHINode than could be | |
404 // computed from its incoming values. For example, SSI form stores its sigma | |
405 // functions as PHINodes with a single incoming value. | |
406 if (LatticeFunc->IsSpecialCasedPHI(&PN)) { | |
407 DenseMap<LatticeKey, LatticeVal> ChangedValues; | |
408 LatticeFunc->ComputeInstructionState(PN, ChangedValues, *this); | |
409 for (auto &ChangedValue : ChangedValues) | |
410 if (ChangedValue.second != LatticeFunc->getUntrackedVal()) | |
411 UpdateState(ChangedValue.first, ChangedValue.second); | |
412 return; | |
413 } | |
414 | |
415 LatticeKey Key = KeyInfo::getLatticeKeyFromValue(&PN); | |
416 LatticeVal PNIV = getValueState(Key); | |
417 LatticeVal Overdefined = LatticeFunc->getOverdefinedVal(); | |
418 | |
419 // If this value is already overdefined (common) just return. | |
420 if (PNIV == Overdefined || PNIV == LatticeFunc->getUntrackedVal()) | |
421 return; // Quick exit | |
422 | |
423 // Super-extra-high-degree PHI nodes are unlikely to ever be interesting, | |
424 // and slow us down a lot. Just mark them overdefined. | |
425 if (PN.getNumIncomingValues() > 64) { | |
426 UpdateState(Key, Overdefined); | |
427 return; | |
428 } | |
429 | |
430 // Look at all of the executable operands of the PHI node. If any of them | |
431 // are overdefined, the PHI becomes overdefined as well. Otherwise, ask the | |
432 // transfer function to give us the merge of the incoming values. | |
433 for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { | |
434 // If the edge is not yet known to be feasible, it doesn't impact the PHI. | |
435 if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent(), true)) | |
436 continue; | |
437 | |
438 // Merge in this value. | |
439 LatticeVal OpVal = | |
440 getValueState(KeyInfo::getLatticeKeyFromValue(PN.getIncomingValue(i))); | |
441 if (OpVal != PNIV) | |
442 PNIV = LatticeFunc->MergeValues(PNIV, OpVal); | |
443 | |
444 if (PNIV == Overdefined) | |
445 break; // Rest of input values don't matter. | |
446 } | |
447 | |
448 // Update the PHI with the compute value, which is the merge of the inputs. | |
449 UpdateState(Key, PNIV); | |
450 } | |
451 | |
452 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
453 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitInst(Instruction &I) { | |
454 // PHIs are handled by the propagation logic, they are never passed into the | |
455 // transfer functions. | |
456 if (PHINode *PN = dyn_cast<PHINode>(&I)) | |
457 return visitPHINode(*PN); | |
458 | |
459 // Otherwise, ask the transfer function what the result is. If this is | |
460 // something that we care about, remember it. | |
461 DenseMap<LatticeKey, LatticeVal> ChangedValues; | |
462 LatticeFunc->ComputeInstructionState(I, ChangedValues, *this); | |
463 for (auto &ChangedValue : ChangedValues) | |
464 if (ChangedValue.second != LatticeFunc->getUntrackedVal()) | |
465 UpdateState(ChangedValue.first, ChangedValue.second); | |
466 | |
467 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(&I)) | |
468 visitTerminatorInst(*TI); | |
469 } | |
470 | |
471 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
472 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::Solve() { | |
473 // Process the work lists until they are empty! | |
474 while (!BBWorkList.empty() || !ValueWorkList.empty()) { | |
475 // Process the value work list. | |
476 while (!ValueWorkList.empty()) { | |
477 Value *V = ValueWorkList.back(); | |
478 ValueWorkList.pop_back(); | |
479 | |
480 DEBUG(dbgs() << "\nPopped off V-WL: " << *V << "\n"); | |
481 | |
482 // "V" got into the work list because it made a transition. See if any | |
483 // users are both live and in need of updating. | |
484 for (User *U : V->users()) | |
485 if (Instruction *Inst = dyn_cast<Instruction>(U)) | |
486 if (BBExecutable.count(Inst->getParent())) // Inst is executable? | |
487 visitInst(*Inst); | |
488 } | |
489 | |
490 // Process the basic block work list. | |
491 while (!BBWorkList.empty()) { | |
492 BasicBlock *BB = BBWorkList.back(); | |
493 BBWorkList.pop_back(); | |
494 | |
495 DEBUG(dbgs() << "\nPopped off BBWL: " << *BB); | |
496 | |
497 // Notify all instructions in this basic block that they are newly | |
498 // executable. | |
499 for (Instruction &I : *BB) | |
500 visitInst(I); | |
501 } | |
502 } | |
503 } | |
504 | |
505 template <class LatticeKey, class LatticeVal, class KeyInfo> | |
506 void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::Print( | |
507 raw_ostream &OS) const { | |
508 if (ValueState.empty()) | |
509 return; | |
510 | |
511 LatticeKey Key; | |
512 LatticeVal LV; | |
513 | |
514 OS << "ValueState:\n"; | |
515 for (auto &Entry : ValueState) { | |
516 std::tie(Key, LV) = Entry; | |
517 if (LV == LatticeFunc->getUntrackedVal()) | |
518 continue; | |
519 OS << "\t"; | |
520 LatticeFunc->PrintLatticeVal(LV, OS); | |
521 OS << ": "; | |
522 LatticeFunc->PrintLatticeKey(Key, OS); | |
523 OS << "\n"; | |
524 } | |
525 } | |
200 } // end namespace llvm | 526 } // end namespace llvm |
201 | 527 |
528 #undef DEBUG_TYPE | |
529 | |
202 #endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H | 530 #endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H |