23 #define DEBUG_TYPE "sparseprop"
35 else if (V == OverdefinedVal)
37 else if (V == UntrackedVal)
40 OS <<
"unknown lattice value";
55 if (I != ValueState.end())
return I->second;
60 else if (
Constant *
C = dyn_cast<Constant>(V))
62 else if (
Argument *
A = dyn_cast<Argument>(V))
64 else if (!isa<Instruction>(V))
74 return ValueState[V] = LV;
79 void SparseSolver::UpdateState(
Instruction &Inst, LatticeVal V) {
81 if (I != ValueState.end() && I->second == V)
85 ValueState[&Inst] = V;
86 InstWorkList.push_back(&Inst);
91 void SparseSolver::MarkBlockExecutable(
BasicBlock *BB) {
93 BBExecutable.insert(BB);
94 BBWorkList.push_back(BB);
100 if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
104 <<
" -> " << Dest->
getName() <<
"\n");
106 if (BBExecutable.count(Dest)) {
111 visitPHINode(*cast<PHINode>(I));
114 MarkBlockExecutable(Dest);
123 bool AggressiveUndef) {
127 if (
BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
128 if (BI->isUnconditional()) {
142 Succs[0] = Succs[1] =
true;
151 if (!C || !isa<ConstantInt>(C)) {
153 Succs[0] = Succs[1] =
true;
162 if (isa<InvokeInst>(TI)) {
165 Succs[0] = Succs[1] =
true;
169 if (isa<IndirectBrInst>(TI)) {
193 if (!C || !isa<ConstantInt>(C)) {
206 bool AggressiveUndef) {
209 getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef);
220 getFeasibleSuccessors(TI, SuccFeasible,
true);
225 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++i)
230 void SparseSolver::visitPHINode(
PHINode &PN) {
251 UpdateState(PN, Overdefined);
268 if (PNIV == Overdefined)
273 UpdateState(PN, PNIV);
280 if (
PHINode *PN = dyn_cast<PHINode>(&I))
281 return visitPHINode(*PN);
290 visitTerminatorInst(*TI);
297 while (!BBWorkList.empty() || !InstWorkList.empty()) {
299 while (!InstWorkList.empty()) {
301 InstWorkList.pop_back();
303 DEBUG(
dbgs() <<
"\nPopped off I-WL: " << *I <<
"\n");
315 while (!BBWorkList.empty()) {
317 BBWorkList.pop_back();
319 DEBUG(
dbgs() <<
"\nPopped off BBWL: " << *BB);
330 OS <<
"\nFUNCTION: " << F.
getName() <<
"\n";
332 if (!BBExecutable.count(BB))
333 OS <<
"INFEASIBLE: ";
LatticeVal getOrInitValueState(Value *V)
getOrInitValueState - Return the LatticeVal object that corresponds to the value, initializing the va...
LLVM Argument representation.
void Solve(Function &F)
Solve - Solve for constants and executable blocks.
LatticeVal getUndefVal() const
virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS)
ComputeInstructionState - Given an instruction and a vector of its operand values, compute the result value of the instruction.
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 getSuccessorIndex() const
Returns TerminatorInst's successor index for current case successor.
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
virtual bool IsSpecialCasedPHI(PHINode *PN)
IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is one that the we want to hand...
virtual bool IsUntrackedValue(Value *V)
IsUntrackedValue - If the specified Value is something that is obviously uninteresting to the analysi...
void assign(size_type NumElts, const T &Elt)
virtual LatticeVal ComputeConstant(Constant *C)
ComputeConstant - Given a constant value, compute and return a lattice value corresponding to the spe...
virtual ~AbstractLatticeFunction()
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
LatticeVal getUntrackedVal() const
Subclasses of this class are all able to terminate a basic block.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
BranchInst - Conditional or Unconditional Branch instruction.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
LatticeVal getLatticeState(Value *V) const
getLatticeState - Return the LatticeVal object that corresponds to the value.
virtual Constant * GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS)
GetConstant - If the specified lattice value is representable as an LLVM constant value...
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
virtual LatticeVal ComputeArgument(Argument *I)
ComputeArgument - Given a formal argument value, compute and return a lattice value corresponding to ...
void Print(Function &F, raw_ostream &OS) const
Value * getIncomingValue(unsigned i) const
getIncomingValue - Return incoming value number x
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const BasicBlock & getEntryBlock() const
bool isNullValue() const
isNullValue - Return true if this is the value that would be returned by getNullValue.
CaseIt findCaseValue(const ConstantInt *C)
findCaseValue - 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.
virtual void PrintValue(LatticeVal V, raw_ostream &OS)
PrintValue - Render the specified lattice value to the specified stream.
iterator_range< user_iterator > users()
Value * getCondition() const
virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y)
MergeValues - Compute and return the merge of the two specified lattice values.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
SwitchInst - Multiway switch.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
LatticeVal getOverdefinedVal() const
const BasicBlock * getParent() const