LLVM: include/llvm/Analysis/SparsePropagation.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H
15#define LLVM_ANALYSIS_SPARSEPROPAGATION_H
16
21#include
22
23#define DEBUG_TYPE "sparseprop"
24
25namespace llvm {
26
27
28
33
34template <class LatticeKey, class LatticeVal,
37
38
39
40
41
42
43
44
45
46
48private:
49 LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
50
51public:
53 LatticeVal untrackedVal) {
54 UndefVal = undefVal;
55 OverdefinedVal = overdefinedVal;
56 UntrackedVal = untrackedVal;
57 }
58
60
61 LatticeVal getUndefVal() const { return UndefVal; }
64
65
66
67
69
70
71
75
76
77
79
80
81
82
86
87
88
89
93
94
96
97
99
100
101
102
103
105 return nullptr;
106 }
107};
108
109
110
111template <class LatticeKey, class LatticeVal, class KeyInfo>
113
114
115
117
118
120
121
123
124
126
127
129
130 using Edge = std::pair<BasicBlock *, BasicBlock *>;
131
132
133
134 std::set KnownFeasibleEdges;
135
136public:
139 : LatticeFunc(Lattice) {}
142
143
145
147
148
149
150
152 auto I = ValueState.find(Key);
153 return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
154 }
155
156
157
158
160
161
162
163
164
165
167 bool AggressiveUndef = false);
168
169
170
171
173 return BBExecutable.count(BB);
174 }
175
176
177
179
180private:
181
182
183
184 void UpdateState(LatticeKey Key, LatticeVal LV);
185
186
187
189
190
191
193 bool AggressiveUndef);
194
196 void visitPHINode(PHINode &I);
198};
199
200
201
202
203
204template <class LatticeKey, class LatticeVal>
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
217template <class LatticeKey, class LatticeVal>
220 OS << "unknown lattice key";
221}
222
223
224
225
226
227template <class LatticeKey, class LatticeVal, class KeyInfo>
228LatticeVal
230 auto I = ValueState.find(Key);
231 if (I != ValueState.end())
232 return I->second;
233
234 if (LatticeFunc->IsUntrackedValue(Key))
235 return LatticeFunc->getUntrackedVal();
236 LatticeVal LV = LatticeFunc->ComputeLatticeVal(Key);
237
238
239 if (LV == LatticeFunc->getUntrackedVal())
240 return LV;
241 return ValueState[Key] = std::move(LV);
242}
243
244template <class LatticeKey, class LatticeVal, class KeyInfo>
245void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::UpdateState(LatticeKey Key,
246 LatticeVal LV) {
247 auto [I, Inserted] = ValueState.try_emplace(Key);
248 if (!Inserted && I->second == LV)
249 return;
250
251
252
253 I->second = std::move(LV);
254 if (Value *V = KeyInfo::getValueFromLatticeKey(Key))
255 ValueWorkList.push_back(V);
256}
257
258template <class LatticeKey, class LatticeVal, class KeyInfo>
261 if (!BBExecutable.insert(BB).second)
262 return;
264 BBWorkList.push_back(BB);
265}
266
267template <class LatticeKey, class LatticeVal, class KeyInfo>
268void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::markEdgeExecutable(
270 if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
271 return;
272
273 LLVM_DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName()
274 << " -> " << Dest->getName() << "\n");
275
276 if (BBExecutable.count(Dest)) {
277
278
279
282 } else {
283 MarkBlockExecutable(Dest);
284 }
285}
286
287template <class LatticeKey, class LatticeVal, class KeyInfo>
288void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::getFeasibleSuccessors(
290 Succs.resize(TI.getNumSuccessors());
291 if (TI.getNumSuccessors() == 0)
292 return;
293
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
311 Succs[0] = Succs[1] = true;
312 return;
313 }
314
315
316 if (BCValue == LatticeFunc->getUndefVal())
317 return;
318
321 std::move(BCValue), BI->getCondition()->getType()));
323
324 Succs[0] = Succs[1] = true;
325 return;
326 }
327
328
329 Succs[C->isNullValue()] = true;
330 return;
331 }
332
334
335 Succs.assign(Succs.size(), true);
336 return;
337 }
338
340 LatticeVal SCValue;
341 if (AggressiveUndef)
342 SCValue = getValueState(KeyInfo::getLatticeKeyFromValue(SI.getCondition()));
343 else
344 SCValue = getExistingValueState(
345 KeyInfo::getLatticeKeyFromValue(SI.getCondition()));
346
347 if (SCValue == LatticeFunc->getOverdefinedVal() ||
348 SCValue == LatticeFunc->getUntrackedVal()) {
349
350 Succs.assign(TI.getNumSuccessors(), true);
351 return;
352 }
353
354
355 if (SCValue == LatticeFunc->getUndefVal())
356 return;
357
359 std::move(SCValue), SI.getCondition()->getType()));
361
362 Succs.assign(TI.getNumSuccessors(), true);
363 return;
364 }
366 Succs[Case.getSuccessorIndex()] = true;
367}
368
369template <class LatticeKey, class LatticeVal, class KeyInfo>
374 getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef);
375
376 for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
377 if (TI->getSuccessor(i) == To && SuccFeasible[i])
378 return true;
379
380 return false;
381}
382
383template <class LatticeKey, class LatticeVal, class KeyInfo>
384void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitTerminator(
387 getFeasibleSuccessors(TI, SuccFeasible, true);
388
390
391
392 for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
393 if (SuccFeasible[i])
395}
396
397template <class LatticeKey, class LatticeVal, class KeyInfo>
398void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitPHINode(PHINode &PN) {
399
400
401
402 if (LatticeFunc->IsSpecialCasedPHI(&PN)) {
403 SmallDenseMap<LatticeKey, LatticeVal, 16> ChangedValues;
404 LatticeFunc->ComputeInstructionState(PN, ChangedValues, *this);
405 for (auto &ChangedValue : ChangedValues)
406 if (ChangedValue.second != LatticeFunc->getUntrackedVal())
407 UpdateState(std::move(ChangedValue.first),
408 std::move(ChangedValue.second));
409 return;
410 }
411
412 LatticeKey Key = KeyInfo::getLatticeKeyFromValue(&PN);
413 LatticeVal PNIV = getValueState(Key);
414 LatticeVal Overdefined = LatticeFunc->getOverdefinedVal();
415
416
417 if (PNIV == Overdefined || PNIV == LatticeFunc->getUntrackedVal())
418 return;
419
420
421
422 if (PN.getNumIncomingValues() > 64) {
423 UpdateState(Key, Overdefined);
424 return;
425 }
426
427
428
429
430 for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
431
432 if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent(), true))
433 continue;
434
435
436 LatticeVal OpVal =
437 getValueState(KeyInfo::getLatticeKeyFromValue(PN.getIncomingValue(i)));
438 if (OpVal != PNIV)
439 PNIV = LatticeFunc->MergeValues(PNIV, OpVal);
440
441 if (PNIV == Overdefined)
442 break;
443 }
444
445
446 UpdateState(Key, PNIV);
447}
448
449template <class LatticeKey, class LatticeVal, class KeyInfo>
450void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::visitInst(Instruction &I) {
451
452
454 return visitPHINode(*PN);
455
456
457
459 LatticeFunc->ComputeInstructionState(I, ChangedValues, *this);
460 for (auto &ChangedValue : ChangedValues)
461 if (ChangedValue.second != LatticeFunc->getUntrackedVal())
462 UpdateState(ChangedValue.first, ChangedValue.second);
463
464 if (I.isTerminator())
465 visitTerminator(I);
466}
467
468template <class LatticeKey, class LatticeVal, class KeyInfo>
470
471 while (!BBWorkList.empty() || !ValueWorkList.empty()) {
472
473 while (!ValueWorkList.empty()) {
474 Value *V = ValueWorkList.pop_back_val();
475
476 LLVM_DEBUG(dbgs() << "\nPopped off V-WL: " << *V << "\n");
477
478
479
482 if (BBExecutable.count(Inst->getParent()))
483 visitInst(*Inst);
484 }
485
486
487 while (!BBWorkList.empty()) {
488 BasicBlock *BB = BBWorkList.pop_back_val();
489
491
492
493
495 visitInst(I);
496 }
497 }
498}
499
500template <class LatticeKey, class LatticeVal, class KeyInfo>
503 if (ValueState.empty())
504 return;
505
506 LatticeKey Key;
507 LatticeVal LV;
508
509 OS << "ValueState:\n";
510 for (auto &Entry : ValueState) {
511 std::tie(Key, LV) = Entry;
512 if (LV == LatticeFunc->getUntrackedVal())
513 continue;
514 OS << "\t";
515 LatticeFunc->PrintLatticeVal(LV, OS);
516 OS << ": ";
517 LatticeFunc->PrintLatticeKey(Key, OS);
518 OS << "\n";
519 }
520}
521}
522
523#undef DEBUG_TYPE
524
525#endif
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the SmallPtrSet class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
AbstractLatticeFunction - This class is implemented by the dataflow instance to specify what the latt...
Definition SparsePropagation.h:47
LatticeVal getOverdefinedVal() const
Definition SparsePropagation.h:62
AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal, LatticeVal untrackedVal)
Definition SparsePropagation.h:52
virtual void ComputeInstructionState(Instruction &I, SmallDenseMap< LatticeKey, LatticeVal, 16 > &ChangedValues, SparseSolver< LatticeKey, LatticeVal > &SS)=0
ComputeInstructionState - Compute the LatticeKeys that change as a result of executing instruction I.
virtual void PrintLatticeKey(LatticeKey Key, raw_ostream &OS)
PrintLatticeKey - Render the given LatticeKey to the specified stream.
Definition SparsePropagation.h:218
virtual Value * GetValueFromLatticeVal(LatticeVal LV, Type *Ty=nullptr)
GetValueFromLatticeVal - If the given LatticeVal is representable as an LLVM value,...
Definition SparsePropagation.h:104
virtual bool IsUntrackedValue(LatticeKey Key)
IsUntrackedValue - If the specified LatticeKey is obviously uninteresting to the analysis (i....
Definition SparsePropagation.h:68
virtual void PrintLatticeVal(LatticeVal LV, raw_ostream &OS)
PrintLatticeVal - Render the given LatticeVal to the specified stream.
Definition SparsePropagation.h:205
LatticeVal getUntrackedVal() const
Definition SparsePropagation.h:63
virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y)
MergeValues - Compute and return the merge of the two specified lattice values.
Definition SparsePropagation.h:83
virtual LatticeVal ComputeLatticeVal(LatticeKey Key)
ComputeLatticeVal - Compute and return a LatticeVal corresponding to the given LatticeKey.
Definition SparsePropagation.h:72
virtual ~AbstractLatticeFunction()=default
LatticeVal getUndefVal() const
Definition SparsePropagation.h:61
virtual bool IsSpecialCasedPHI(PHINode *PN)
IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is one that the we want to hand...
Definition SparsePropagation.h:78
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Conditional or Unconditional Branch instruction.
This is an important base class in LLVM.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseSolver - This class is a general purpose solver for Sparse Conditional Propagation with a progr...
Definition SparsePropagation.h:112
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To, bool AggressiveUndef=false)
isEdgeFeasible - Return true if the control flow edge from the 'From' basic block to the 'To' basic b...
Definition SparsePropagation.h:370
void Print(raw_ostream &OS) const
Definition SparsePropagation.h:501
LatticeVal getValueState(LatticeKey Key)
getValueState - Return the LatticeVal object corresponding to the given value from the ValueState map...
Definition SparsePropagation.h:229
SparseSolver(AbstractLatticeFunction< LatticeKey, LatticeVal > *Lattice)
Definition SparsePropagation.h:137
SparseSolver(const SparseSolver &)=delete
void MarkBlockExecutable(BasicBlock *BB)
MarkBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
Definition SparsePropagation.h:259
void Solve()
Solve - Solve for constants and executable blocks.
Definition SparsePropagation.h:469
LatticeVal getExistingValueState(LatticeKey Key) const
getExistingValueState - Return the LatticeVal object corresponding to the given value from the ValueS...
Definition SparsePropagation.h:151
bool isBlockExecutable(BasicBlock *BB) const
isBlockExecutable - Return true if there are any known feasible edges into the basic block.
Definition SparsePropagation.h:172
SparseSolver & operator=(const SparseSolver &)=delete
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
A template for translating between LLVM Values and LatticeKeys.
Definition SparsePropagation.h:29