15 #ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H 16 #define LLVM_ANALYSIS_SPARSEPROPAGATION_H 22 #define DEBUG_TYPE "sparseprop" 33 template <
class LatticeKey,
class LatticeVal,
48 LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
52 LatticeVal untrackedVal) {
54 OverdefinedVal = overdefinedVal;
55 UntrackedVal = untrackedVal;
72 return getOverdefinedVal();
83 return getOverdefinedVal();
95 virtual void PrintLatticeVal(LatticeVal LV,
raw_ostream &OS);
111 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
130 using Edge = std::pair<BasicBlock *, BasicBlock *>;
134 std::set<Edge> KnownFeasibleEdges;
139 : LatticeFunc(Lattice) {}
152 auto I = ValueState.
find(Key);
159 LatticeVal getValueState(LatticeKey
Key);
167 bool AggressiveUndef =
false);
173 return BBExecutable.
count(BB);
184 void UpdateState(LatticeKey Key, LatticeVal LV);
193 bool AggressiveUndef);
204 template <
class LatticeKey,
class LatticeVal>
209 else if (V == OverdefinedVal)
211 else if (V == UntrackedVal)
214 OS <<
"unknown lattice value";
217 template <
class LatticeKey,
class LatticeVal>
220 OS <<
"unknown lattice key";
227 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
230 auto I = ValueState.find(Key);
231 if (
I != ValueState.end())
234 if (LatticeFunc->IsUntrackedValue(Key))
235 return LatticeFunc->getUntrackedVal();
236 LatticeVal LV = LatticeFunc->ComputeLatticeVal(Key);
239 if (LV == LatticeFunc->getUntrackedVal())
241 return ValueState[
Key] = std::move(LV);
244 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
247 auto I = ValueState.find(Key);
248 if (
I != ValueState.end() &&
I->second == LV)
253 ValueState[
Key] = std::move(LV);
254 if (
Value *V = KeyInfo::getValueFromLatticeKey(Key))
255 ValueWorkList.push_back(V);
258 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
261 if (!BBExecutable.insert(BB).second)
264 BBWorkList.push_back(BB);
267 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
270 if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
274 <<
" -> " << Dest->
getName() <<
"\n");
276 if (BBExecutable.count(Dest)) {
281 visitPHINode(*cast<PHINode>(
I));
283 MarkBlockExecutable(Dest);
287 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
294 if (
BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
295 if (BI->isUnconditional()) {
303 getValueState(KeyInfo::getLatticeKeyFromValue(BI->getCondition()));
305 BCValue = getExistingValueState(
306 KeyInfo::getLatticeKeyFromValue(BI->getCondition()));
308 if (BCValue == LatticeFunc->getOverdefinedVal() ||
309 BCValue == LatticeFunc->getUntrackedVal()) {
311 Succs[0] = Succs[1] =
true;
316 if (BCValue == LatticeFunc->getUndefVal())
320 dyn_cast_or_null<Constant>(LatticeFunc->GetValueFromLatticeVal(
321 std::move(BCValue), BI->getCondition()->getType()));
322 if (!C || !isa<ConstantInt>(C)) {
324 Succs[0] = Succs[1] =
true;
338 if (isa<IndirectBrInst>(TI)) {
346 SCValue = getValueState(KeyInfo::getLatticeKeyFromValue(SI.
getCondition()));
348 SCValue = getExistingValueState(
351 if (SCValue == LatticeFunc->getOverdefinedVal() ||
352 SCValue == LatticeFunc->getUntrackedVal()) {
359 if (SCValue == LatticeFunc->getUndefVal())
362 Constant *
C = dyn_cast_or_null<Constant>(LatticeFunc->GetValueFromLatticeVal(
364 if (!C || !isa<ConstantInt>(C)) {
373 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
378 getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef);
387 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
391 getFeasibleSuccessors(TI, SuccFeasible,
true);
396 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++i)
401 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
406 if (LatticeFunc->IsSpecialCasedPHI(&PN)) {
408 LatticeFunc->ComputeInstructionState(PN, ChangedValues, *
this);
409 for (
auto &ChangedValue : ChangedValues)
410 if (ChangedValue.second != LatticeFunc->getUntrackedVal())
411 UpdateState(std::move(ChangedValue.first),
412 std::move(ChangedValue.second));
416 LatticeKey Key = KeyInfo::getLatticeKeyFromValue(&PN);
417 LatticeVal PNIV = getValueState(Key);
418 LatticeVal Overdefined = LatticeFunc->getOverdefinedVal();
421 if (PNIV == Overdefined || PNIV == LatticeFunc->getUntrackedVal())
427 UpdateState(Key, Overdefined);
443 PNIV = LatticeFunc->MergeValues(PNIV, OpVal);
445 if (PNIV == Overdefined)
450 UpdateState(Key, PNIV);
453 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
457 if (
PHINode *PN = dyn_cast<PHINode>(&I))
458 return visitPHINode(*PN);
463 LatticeFunc->ComputeInstructionState(I, ChangedValues, *
this);
464 for (
auto &ChangedValue : ChangedValues)
465 if (ChangedValue.second != LatticeFunc->getUntrackedVal())
466 UpdateState(ChangedValue.first, ChangedValue.second);
472 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
475 while (!BBWorkList.empty() || !ValueWorkList.empty()) {
477 while (!ValueWorkList.empty()) {
478 Value *V = ValueWorkList.back();
479 ValueWorkList.pop_back();
487 if (BBExecutable.count(Inst->getParent()))
492 while (!BBWorkList.empty()) {
494 BBWorkList.pop_back();
506 template <
class LatticeKey,
class LatticeVal,
class KeyInfo>
509 if (ValueState.empty())
515 OS <<
"ValueState:\n";
516 for (
auto &Entry : ValueState) {
517 std::tie(Key, LV) = Entry;
518 if (LV == LatticeFunc->getUntrackedVal())
521 LatticeFunc->PrintLatticeVal(LV, OS);
523 LatticeFunc->PrintLatticeKey(Key, OS);
531 #endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H
void Print(raw_ostream &OS) const
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y)
MergeValues - Compute and return the merge of the two specified lattice values.
SparseSolver(AbstractLatticeFunction< LatticeKey, LatticeVal > *Lattice)
This class represents lattice values for constants.
virtual void PrintLatticeVal(LatticeVal LV, raw_ostream &OS)
PrintLatticeVal - Render the given LatticeVal to the specified stream.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
Value * getCondition() const
bool isTerminator() const
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...
virtual Value * GetValueFromLatticeVal(LatticeVal LV, Type *Ty=nullptr)
GetValueFromLatticeVal - If the given LatticeVal is representable as an LLVM value, return it; otherwise, return nullptr.
iterator begin()
Instruction iterator methods.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
void assign(size_type NumElts, const T &Elt)
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
void Solve()
Solve - Solve for constants and executable blocks.
Type * getType() const
All values are typed, get the type of this value.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
iterator find(const_arg_type_t< KeyT > Val)
virtual void PrintLatticeKey(LatticeKey Key, raw_ostream &OS)
PrintLatticeKey - Render the given LatticeKey to the specified stream.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Conditional or Unconditional Branch instruction.
This is an important base class in LLVM.
LatticeVal getUntrackedVal() const
const Instruction & back() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
SparseSolver - This class is a general purpose solver for Sparse Conditional Propagation with a progr...
bool isExceptionalTerminator() const
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
AbstractLatticeFunction - This class is implemented by the dataflow instance to specify what the latt...
LatticeVal getExistingValueState(LatticeKey Key) const
getExistingValueState - Return the LatticeVal object corresponding to the given value from the ValueS...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
BlockVerifier::State From
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
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...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
CaseIt findCaseValue(const ConstantInt *C)
Search all of the case values for the specified constant.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LatticeVal getValueState(LatticeKey Key)
getValueState - Return the LatticeVal object corresponding to the given value from the ValueState map...
iterator_range< user_iterator > users()
InstListType::iterator iterator
Instruction iterators...
unsigned getSuccessorIndex() const
Returns successor index for current case successor.
virtual bool IsSpecialCasedPHI(PHINode *PN)
IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is one that the we want to hand...
LatticeVal getUndefVal() const
AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal, LatticeVal untrackedVal)
bool isBlockExecutable(BasicBlock *BB) const
isBlockExecutable - Return true if there are any known feasible edges into the basic block...
virtual bool IsUntrackedValue(LatticeKey Key)
IsUntrackedValue - If the specified LatticeKey is obviously uninteresting to the analysis (i...
StringRef getName() const
Return a constant reference to the value's name.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
LatticeVal getOverdefinedVal() const
void MarkBlockExecutable(BasicBlock *BB)
MarkBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
virtual LatticeVal ComputeLatticeVal(LatticeKey Key)
ComputeLatticeVal - Compute and return a LatticeVal corresponding to the given LatticeKey.
const BasicBlock * getParent() const
A template for translating between LLVM Values and LatticeKeys.