LLVM API Documentation
00001 //===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements bookkeeping for "interesting" users of expressions 00011 // computed from induction variables. 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/Analysis/ScalarEvolutionNormalization.h" 00020 #include "llvm/IR/ValueHandle.h" 00021 00022 namespace llvm { 00023 00024 class DominatorTree; 00025 class Instruction; 00026 class Value; 00027 class ScalarEvolution; 00028 class SCEV; 00029 class IVUsers; 00030 class DataLayout; 00031 00032 /// IVStrideUse - Keep track of one use of a strided induction variable. 00033 /// The Expr member keeps track of the expression, User is the actual user 00034 /// instruction of the operand, and 'OperandValToReplace' is the operand of 00035 /// the User that is the use. 00036 class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { 00037 friend class IVUsers; 00038 public: 00039 IVStrideUse(IVUsers *P, Instruction* U, Value *O) 00040 : CallbackVH(U), Parent(P), OperandValToReplace(O) { 00041 } 00042 00043 /// getUser - Return the user instruction for this use. 00044 Instruction *getUser() const { 00045 return cast<Instruction>(getValPtr()); 00046 } 00047 00048 /// setUser - Assign a new user instruction for this use. 00049 void setUser(Instruction *NewUser) { 00050 setValPtr(NewUser); 00051 } 00052 00053 /// getOperandValToReplace - Return the Value of the operand in the user 00054 /// instruction that this IVStrideUse is representing. 00055 Value *getOperandValToReplace() const { 00056 return OperandValToReplace; 00057 } 00058 00059 /// setOperandValToReplace - Assign a new Value as the operand value 00060 /// to replace. 00061 void setOperandValToReplace(Value *Op) { 00062 OperandValToReplace = Op; 00063 } 00064 00065 /// getPostIncLoops - Return the set of loops for which the expression has 00066 /// been adjusted to use post-inc mode. 00067 const PostIncLoopSet &getPostIncLoops() const { 00068 return PostIncLoops; 00069 } 00070 00071 /// transformToPostInc - Transform the expression to post-inc form for the 00072 /// given loop. 00073 void transformToPostInc(const Loop *L); 00074 00075 private: 00076 /// Parent - a pointer to the IVUsers that owns this IVStrideUse. 00077 IVUsers *Parent; 00078 00079 /// OperandValToReplace - The Value of the operand in the user instruction 00080 /// that this IVStrideUse is representing. 00081 WeakVH OperandValToReplace; 00082 00083 /// PostIncLoops - The set of loops for which Expr has been adjusted to 00084 /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. 00085 PostIncLoopSet PostIncLoops; 00086 00087 /// Deleted - Implementation of CallbackVH virtual function to 00088 /// receive notification when the User is deleted. 00089 void deleted() override; 00090 }; 00091 00092 template<> struct ilist_traits<IVStrideUse> 00093 : public ilist_default_traits<IVStrideUse> { 00094 // createSentinel is used to get hold of a node that marks the end of 00095 // the list... 00096 // The sentinel is relative to this instance, so we use a non-static 00097 // method. 00098 IVStrideUse *createSentinel() const { 00099 // since i(p)lists always publicly derive from the corresponding 00100 // traits, placing a data member in this class will augment i(p)list. 00101 // But since the NodeTy is expected to publicly derive from 00102 // ilist_node<NodeTy>, there is a legal viable downcast from it 00103 // to NodeTy. We use this trick to superpose i(p)list with a "ghostly" 00104 // NodeTy, which becomes the sentinel. Dereferencing the sentinel is 00105 // forbidden (save the ilist_node<NodeTy>) so no one will ever notice 00106 // the superposition. 00107 return static_cast<IVStrideUse*>(&Sentinel); 00108 } 00109 static void destroySentinel(IVStrideUse*) {} 00110 00111 IVStrideUse *provideInitialHead() const { return createSentinel(); } 00112 IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); } 00113 static void noteHead(IVStrideUse*, IVStrideUse*) {} 00114 00115 private: 00116 mutable ilist_node<IVStrideUse> Sentinel; 00117 }; 00118 00119 class IVUsers : public LoopPass { 00120 friend class IVStrideUse; 00121 Loop *L; 00122 LoopInfo *LI; 00123 DominatorTree *DT; 00124 ScalarEvolution *SE; 00125 const DataLayout *DL; 00126 SmallPtrSet<Instruction*,16> Processed; 00127 00128 /// IVUses - A list of all tracked IV uses of induction variable expressions 00129 /// we are interested in. 00130 ilist<IVStrideUse> IVUses; 00131 00132 void getAnalysisUsage(AnalysisUsage &AU) const override; 00133 00134 bool runOnLoop(Loop *L, LPPassManager &LPM) override; 00135 00136 void releaseMemory() override; 00137 00138 public: 00139 static char ID; // Pass ID, replacement for typeid 00140 IVUsers(); 00141 00142 Loop *getLoop() const { return L; } 00143 00144 /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a 00145 /// reducible SCEV, recursively add its users to the IVUsesByStride set and 00146 /// return true. Otherwise, return false. 00147 bool AddUsersIfInteresting(Instruction *I); 00148 00149 IVStrideUse &AddUser(Instruction *User, Value *Operand); 00150 00151 /// getReplacementExpr - Return a SCEV expression which computes the 00152 /// value of the OperandValToReplace of the given IVStrideUse. 00153 const SCEV *getReplacementExpr(const IVStrideUse &IU) const; 00154 00155 /// getExpr - Return the expression for the use. 00156 const SCEV *getExpr(const IVStrideUse &IU) const; 00157 00158 const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const; 00159 00160 typedef ilist<IVStrideUse>::iterator iterator; 00161 typedef ilist<IVStrideUse>::const_iterator const_iterator; 00162 iterator begin() { return IVUses.begin(); } 00163 iterator end() { return IVUses.end(); } 00164 const_iterator begin() const { return IVUses.begin(); } 00165 const_iterator end() const { return IVUses.end(); } 00166 bool empty() const { return IVUses.empty(); } 00167 00168 bool isIVUserOrOperand(Instruction *Inst) const { 00169 return Processed.count(Inst); 00170 } 00171 00172 void print(raw_ostream &OS, const Module* = nullptr) const override; 00173 00174 /// dump - This method is used for debugging. 00175 void dump() const; 00176 protected: 00177 bool AddUsersImpl(Instruction *I, SmallPtrSetImpl<Loop*> &SimpleLoopNests); 00178 }; 00179 00180 Pass *createIVUsersPass(); 00181 00182 } 00183 00184 #endif