00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef LLVM_ANALYSIS_SPARSE_PROPAGATION_H
00016 #define LLVM_ANALYSIS_SPARSE_PROPAGATION_H
00017
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/ADT/SmallPtrSet.h"
00020 #include <vector>
00021 #include <set>
00022
00023 namespace llvm {
00024 class Value;
00025 class Constant;
00026 class Argument;
00027 class Instruction;
00028 class PHINode;
00029 class TerminatorInst;
00030 class BasicBlock;
00031 class Function;
00032 class SparseSolver;
00033 class raw_ostream;
00034
00035 template<typename T> class SmallVectorImpl;
00036
00044 class AbstractLatticeFunction {
00045 public:
00046 typedef void *LatticeVal;
00047 private:
00048 LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
00049 public:
00050 AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal,
00051 LatticeVal untrackedVal) {
00052 UndefVal = undefVal;
00053 OverdefinedVal = overdefinedVal;
00054 UntrackedVal = untrackedVal;
00055 }
00056 virtual ~AbstractLatticeFunction();
00057
00058 LatticeVal getUndefVal() const { return UndefVal; }
00059 LatticeVal getOverdefinedVal() const { return OverdefinedVal; }
00060 LatticeVal getUntrackedVal() const { return UntrackedVal; }
00061
00065 virtual bool IsUntrackedValue(Value *V) {
00066 return false;
00067 }
00068
00071 virtual LatticeVal ComputeConstant(Constant *C) {
00072 return getOverdefinedVal();
00073 }
00074
00077 virtual bool IsSpecialCasedPHI(PHINode *PN) {
00078 return false;
00079 }
00080
00084 virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) {
00085 return 0;
00086 }
00087
00090 virtual LatticeVal ComputeArgument(Argument *I) {
00091 return getOverdefinedVal();
00092 }
00093
00097 virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) {
00098 return getOverdefinedVal();
00099 }
00100
00103 virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) {
00104 return getOverdefinedVal();
00105 }
00106
00108 virtual void PrintValue(LatticeVal V, raw_ostream &OS);
00109 };
00110
00111
00115 class SparseSolver {
00116 typedef AbstractLatticeFunction::LatticeVal LatticeVal;
00117
00120 AbstractLatticeFunction *LatticeFunc;
00121
00122 DenseMap<Value*, LatticeVal> ValueState;
00123 SmallPtrSet<BasicBlock*, 16> BBExecutable;
00124
00125 std::vector<Instruction*> InstWorkList;
00126
00127 std::vector<BasicBlock*> BBWorkList;
00128
00131 typedef std::pair<BasicBlock*,BasicBlock*> Edge;
00132 std::set<Edge> KnownFeasibleEdges;
00133
00134 SparseSolver(const SparseSolver&);
00135 void operator=(const SparseSolver&);
00136 public:
00137 explicit SparseSolver(AbstractLatticeFunction *Lattice)
00138 : LatticeFunc(Lattice) {}
00139 ~SparseSolver() {
00140 delete LatticeFunc;
00141 }
00142
00145 void Solve(Function &F);
00146
00147 void Print(Function &F, raw_ostream &OS) const;
00148
00152 LatticeVal getLatticeState(Value *V) const {
00153 DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V);
00154 return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
00155 }
00156
00163 LatticeVal getOrInitValueState(Value *V);
00164
00170 bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
00171 bool AggressiveUndef = false);
00172
00176 bool isBlockExecutable(BasicBlock *BB) const {
00177 return BBExecutable.count(BB);
00178 }
00179
00180 private:
00183 void UpdateState(Instruction &Inst, LatticeVal V);
00184
00187 void MarkBlockExecutable(BasicBlock *BB);
00188
00191 void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
00192
00195 void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
00196 bool AggressiveUndef);
00197
00198 void visitInst(Instruction &I);
00199 void visitPHINode(PHINode &I);
00200 void visitTerminatorInst(TerminatorInst &TI);
00201
00202 };
00203
00204 }
00205
00206 #endif // LLVM_ANALYSIS_SPARSE_PROPAGATION_H