00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef LLVM_ANALYSIS_IVUSERS_H
00016 #define LLVM_ANALYSIS_IVUSERS_H
00017
00018 #include "llvm/Analysis/LoopPass.h"
00019 #include "llvm/Support/ValueHandle.h"
00020
00021 namespace llvm {
00022
00023 class DominatorTree;
00024 class Instruction;
00025 class Value;
00026 class IVUsers;
00027 class ScalarEvolution;
00028 class SCEV;
00029
00034 class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
00035 public:
00036 IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off,
00037 Instruction* U, Value *O)
00038 : CallbackVH(U), Parent(P), Stride(S), Offset(Off),
00039 OperandValToReplace(O), IsUseOfPostIncrementedValue(false) {
00040 }
00041
00043 Instruction *getUser() const {
00044 return cast<Instruction>(getValPtr());
00045 }
00046
00048 void setUser(Instruction *NewUser) {
00049 setValPtr(NewUser);
00050 }
00051
00054 IVUsers *getParent() const { return Parent; }
00055
00057 const SCEV *getStride() const { return Stride; }
00058
00060 void setStride(const SCEV *Val) {
00061 Stride = Val;
00062 }
00063
00067 const SCEV *getOffset() const { return Offset; }
00068
00070 void setOffset(const SCEV *Val) {
00071 Offset = Val;
00072 }
00073
00076 Value *getOperandValToReplace() const {
00077 return OperandValToReplace;
00078 }
00079
00082 void setOperandValToReplace(Value *Op) {
00083 OperandValToReplace = Op;
00084 }
00085
00090 bool isUseOfPostIncrementedValue() const {
00091 return IsUseOfPostIncrementedValue;
00092 }
00093
00096 void setIsUseOfPostIncrementedValue(bool Val) {
00097 IsUseOfPostIncrementedValue = Val;
00098 }
00099
00100 private:
00102 IVUsers *Parent;
00103
00105 const SCEV *Stride;
00106
00108 const SCEV *Offset;
00109
00112 WeakVH OperandValToReplace;
00113
00116 bool IsUseOfPostIncrementedValue;
00117
00120 virtual void deleted();
00121 };
00122
00123 template<> struct ilist_traits<IVStrideUse>
00124 : public ilist_default_traits<IVStrideUse> {
00125
00126
00127
00128
00129 IVStrideUse *createSentinel() const {
00130
00131
00132
00133
00134
00135
00136
00137
00138 return static_cast<IVStrideUse*>(&Sentinel);
00139 }
00140 static void destroySentinel(IVStrideUse*) {}
00141
00142 IVStrideUse *provideInitialHead() const { return createSentinel(); }
00143 IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
00144 static void noteHead(IVStrideUse*, IVStrideUse*) {}
00145
00146 private:
00147 mutable ilist_node<IVStrideUse> Sentinel;
00148 };
00149
00150 class IVUsers : public LoopPass {
00151 friend class IVStrideUse;
00152 Loop *L;
00153 LoopInfo *LI;
00154 DominatorTree *DT;
00155 ScalarEvolution *SE;
00156 SmallPtrSet<Instruction*,16> Processed;
00157
00160 ilist<IVStrideUse> IVUses;
00161
00162 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
00163
00164 virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
00165
00166 virtual void releaseMemory();
00167
00168 public:
00169 static char ID;
00170 IVUsers();
00171
00175 bool AddUsersIfInteresting(Instruction *I);
00176
00177 IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset,
00178 Instruction *User, Value *Operand);
00179
00182 const SCEV *getReplacementExpr(const IVStrideUse &U) const;
00183
00187 const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
00188
00189 typedef ilist<IVStrideUse>::iterator iterator;
00190 typedef ilist<IVStrideUse>::const_iterator const_iterator;
00191 iterator begin() { return IVUses.begin(); }
00192 iterator end() { return IVUses.end(); }
00193 const_iterator begin() const { return IVUses.begin(); }
00194 const_iterator end() const { return IVUses.end(); }
00195 bool empty() const { return IVUses.empty(); }
00196
00197 void print(raw_ostream &OS, const Module* = 0) const;
00198
00200 void dump() const;
00201 };
00202
00203 Pass *createIVUsersPass();
00204
00205 }
00206
00207 #endif