IVUsers.h revision 3f46a3abeedba8d517b4182de34c821d752db058
1//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements bookkeeping for "interesting" users of expressions 11// computed from induction variables. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_ANALYSIS_IVUSERS_H 16#define LLVM_ANALYSIS_IVUSERS_H 17 18#include "llvm/Analysis/LoopPass.h" 19#include "llvm/Support/ValueHandle.h" 20 21namespace llvm { 22 23class DominatorTree; 24class Instruction; 25class Value; 26class IVUsers; 27class ScalarEvolution; 28class SCEV; 29 30/// IVStrideUse - Keep track of one use of a strided induction variable. 31/// The Expr member keeps track of the expression, User is the actual user 32/// instruction of the operand, and 'OperandValToReplace' is the operand of 33/// the User that is the use. 34class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { 35public: 36 IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off, 37 Instruction* U, Value *O) 38 : CallbackVH(U), Parent(P), Stride(S), Offset(Off), 39 OperandValToReplace(O), IsUseOfPostIncrementedValue(false) { 40 } 41 42 /// getUser - Return the user instruction for this use. 43 Instruction *getUser() const { 44 return cast<Instruction>(getValPtr()); 45 } 46 47 /// setUser - Assign a new user instruction for this use. 48 void setUser(Instruction *NewUser) { 49 setValPtr(NewUser); 50 } 51 52 /// getParent - Return a pointer to the IVUsers that owns 53 /// this IVStrideUse. 54 IVUsers *getParent() const { return Parent; } 55 56 /// getStride - Return the expression for the stride for the use. 57 const SCEV *getStride() const { return Stride; } 58 59 /// setStride - Assign a new stride to this use. 60 void setStride(const SCEV *Val) { 61 Stride = Val; 62 } 63 64 /// getOffset - Return the offset to add to a theoretical induction 65 /// variable that starts at zero and counts up by the stride to compute 66 /// the value for the use. This always has the same type as the stride. 67 const SCEV *getOffset() const { return Offset; } 68 69 /// setOffset - Assign a new offset to this use. 70 void setOffset(const SCEV *Val) { 71 Offset = Val; 72 } 73 74 /// getOperandValToReplace - Return the Value of the operand in the user 75 /// instruction that this IVStrideUse is representing. 76 Value *getOperandValToReplace() const { 77 return OperandValToReplace; 78 } 79 80 /// setOperandValToReplace - Assign a new Value as the operand value 81 /// to replace. 82 void setOperandValToReplace(Value *Op) { 83 OperandValToReplace = Op; 84 } 85 86 /// isUseOfPostIncrementedValue - True if this should use the 87 /// post-incremented version of this IV, not the preincremented version. 88 /// This can only be set in special cases, such as the terminating setcc 89 /// instruction for a loop or uses dominated by the loop. 90 bool isUseOfPostIncrementedValue() const { 91 return IsUseOfPostIncrementedValue; 92 } 93 94 /// setIsUseOfPostIncrmentedValue - set the flag that indicates whether 95 /// this is a post-increment use. 96 void setIsUseOfPostIncrementedValue(bool Val) { 97 IsUseOfPostIncrementedValue = Val; 98 } 99 100private: 101 /// Parent - a pointer to the IVUsers that owns this IVStrideUse. 102 IVUsers *Parent; 103 104 /// Stride - The stride for this use. 105 const SCEV *Stride; 106 107 /// Offset - The offset to add to the base induction expression. 108 const SCEV *Offset; 109 110 /// OperandValToReplace - The Value of the operand in the user instruction 111 /// that this IVStrideUse is representing. 112 WeakVH OperandValToReplace; 113 114 /// IsUseOfPostIncrementedValue - True if this should use the 115 /// post-incremented version of this IV, not the preincremented version. 116 bool IsUseOfPostIncrementedValue; 117 118 /// Deleted - Implementation of CallbackVH virtual function to 119 /// receive notification when the User is deleted. 120 virtual void deleted(); 121}; 122 123template<> struct ilist_traits<IVStrideUse> 124 : public ilist_default_traits<IVStrideUse> { 125 // createSentinel is used to get hold of a node that marks the end of 126 // the list... 127 // The sentinel is relative to this instance, so we use a non-static 128 // method. 129 IVStrideUse *createSentinel() const { 130 // since i(p)lists always publicly derive from the corresponding 131 // traits, placing a data member in this class will augment i(p)list. 132 // But since the NodeTy is expected to publicly derive from 133 // ilist_node<NodeTy>, there is a legal viable downcast from it 134 // to NodeTy. We use this trick to superpose i(p)list with a "ghostly" 135 // NodeTy, which becomes the sentinel. Dereferencing the sentinel is 136 // forbidden (save the ilist_node<NodeTy>) so no one will ever notice 137 // the superposition. 138 return static_cast<IVStrideUse*>(&Sentinel); 139 } 140 static void destroySentinel(IVStrideUse*) {} 141 142 IVStrideUse *provideInitialHead() const { return createSentinel(); } 143 IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); } 144 static void noteHead(IVStrideUse*, IVStrideUse*) {} 145 146private: 147 mutable ilist_node<IVStrideUse> Sentinel; 148}; 149 150class IVUsers : public LoopPass { 151 friend class IVStrideUse; 152 Loop *L; 153 LoopInfo *LI; 154 DominatorTree *DT; 155 ScalarEvolution *SE; 156 SmallPtrSet<Instruction*,16> Processed; 157 158 /// IVUses - A list of all tracked IV uses of induction variable expressions 159 /// we are interested in. 160 ilist<IVStrideUse> IVUses; 161 162 virtual void getAnalysisUsage(AnalysisUsage &AU) const; 163 164 virtual bool runOnLoop(Loop *L, LPPassManager &LPM); 165 166 virtual void releaseMemory(); 167 168public: 169 static char ID; // Pass ID, replacement for typeid 170 IVUsers(); 171 172 /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a 173 /// reducible SCEV, recursively add its users to the IVUsesByStride set and 174 /// return true. Otherwise, return false. 175 bool AddUsersIfInteresting(Instruction *I); 176 177 IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset, 178 Instruction *User, Value *Operand); 179 180 /// getReplacementExpr - Return a SCEV expression which computes the 181 /// value of the OperandValToReplace of the given IVStrideUse. 182 const SCEV *getReplacementExpr(const IVStrideUse &U) const; 183 184 /// getCanonicalExpr - Return a SCEV expression which computes the 185 /// value of the SCEV of the given IVStrideUse, ignoring the 186 /// isUseOfPostIncrementedValue flag. 187 const SCEV *getCanonicalExpr(const IVStrideUse &U) const; 188 189 typedef ilist<IVStrideUse>::iterator iterator; 190 typedef ilist<IVStrideUse>::const_iterator const_iterator; 191 iterator begin() { return IVUses.begin(); } 192 iterator end() { return IVUses.end(); } 193 const_iterator begin() const { return IVUses.begin(); } 194 const_iterator end() const { return IVUses.end(); } 195 bool empty() const { return IVUses.empty(); } 196 197 void print(raw_ostream &OS, const Module* = 0) const; 198 199 /// dump - This method is used for debugging. 200 void dump() const; 201}; 202 203Pass *createIVUsersPass(); 204 205} 206 207#endif 208