class SparseSolver;
/// AbstractLatticeFunction - This class is implemented by the dataflow instance
-/// to specify what the lattice values are and what how they handle merges etc.
+/// to specify what the lattice values are and how they handle merges etc.
/// This gives the client the power to compute lattice values from instructions,
/// constants, etc. The requirement is that lattice values must all fit into
/// a void*. If a void* is not sufficient, the implementation should use this
SparseSolver(const SparseSolver&); // DO NOT IMPLEMENT
void operator=(const SparseSolver&); // DO NOT IMPLEMENT
public:
- SparseSolver(AbstractLatticeFunction *Lattice) : LatticeFunc(Lattice) {}
+ explicit SparseSolver(AbstractLatticeFunction *Lattice)
+ : LatticeFunc(Lattice) {}
~SparseSolver() {
delete LatticeFunc;
}
LatticeVal getOrInitValueState(Value *V);
/// isEdgeFeasible - Return true if the control flow edge from the 'From'
- /// basic block to the 'To' basic block is currently feasible...
- bool isEdgeFeasible(BasicBlock *From, BasicBlock *To);
+ /// basic block to the 'To' basic block is currently feasible. If
+ /// AggressiveUndef is true, then this treats values with unknown lattice
+ /// values as undefined. This is generally only useful when solving the
+ /// lattice, not when querying it.
+ bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
+ bool AggressiveUndef = false);
private:
/// UpdateState - When the state for some instruction is potentially updated,
/// getFeasibleSuccessors - Return a vector of booleans to indicate which
/// successors are reachable from a given terminator instruction.
- void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs);
+ void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
+ bool AggressiveUndef);
void visitInst(Instruction &I);
void visitPHINode(PHINode &I);