1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements bookkeeping for "interesting" users of expressions 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// computed from induction variables. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_ANALYSIS_IVUSERS_H 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_ANALYSIS_IVUSERS_H 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Analysis/LoopPass.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Analysis/ScalarEvolutionNormalization.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ValueHandle.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm { 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass DominatorTree; 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass Instruction; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass Value; 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass IVUsers; 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ScalarEvolution; 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass SCEV; 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass IVUsers; 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass TargetData; 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// IVStrideUse - Keep track of one use of a strided induction variable. 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The Expr member keeps track of the expression, User is the actual user 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// instruction of the operand, and 'OperandValToReplace' is the operand of 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the User that is the use. 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman friend class IVUsers; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVStrideUse(IVUsers *P, Instruction* U, Value *O) 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : CallbackVH(U), Parent(P), OperandValToReplace(O) { 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getUser - Return the user instruction for this use. 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Instruction *getUser() const { 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return cast<Instruction>(getValPtr()); 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// setUser - Assign a new user instruction for this use. 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void setUser(Instruction *NewUser) { 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman setValPtr(NewUser); 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getOperandValToReplace - Return the Value of the operand in the user 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// instruction that this IVStrideUse is representing. 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value *getOperandValToReplace() const { 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return OperandValToReplace; 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// setOperandValToReplace - Assign a new Value as the operand value 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// to replace. 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void setOperandValToReplace(Value *Op) { 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OperandValToReplace = Op; 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getPostIncLoops - Return the set of loops for which the expression has 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// been adjusted to use post-inc mode. 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const PostIncLoopSet &getPostIncLoops() const { 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return PostIncLoops; 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// transformToPostInc - Transform the expression to post-inc form for the 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// given loop. 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void transformToPostInc(const Loop *L); 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate: 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Parent - a pointer to the IVUsers that owns this IVStrideUse. 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVUsers *Parent; 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// OperandValToReplace - The Value of the operand in the user instruction 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// that this IVStrideUse is representing. 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman WeakVH OperandValToReplace; 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// PostIncLoops - The set of loops for which Expr has been adjusted to 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PostIncLoopSet PostIncLoops; 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Deleted - Implementation of CallbackVH virtual function to 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// receive notification when the User is deleted. 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void deleted(); 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> struct ilist_traits<IVStrideUse> 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public ilist_default_traits<IVStrideUse> { 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // createSentinel is used to get hold of a node that marks the end of 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the list... 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The sentinel is relative to this instance, so we use a non-static 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // method. 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVStrideUse *createSentinel() const { 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // since i(p)lists always publicly derive from the corresponding 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // traits, placing a data member in this class will augment i(p)list. 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // But since the NodeTy is expected to publicly derive from 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ilist_node<NodeTy>, there is a legal viable downcast from it 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to NodeTy. We use this trick to superpose i(p)list with a "ghostly" 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NodeTy, which becomes the sentinel. Dereferencing the sentinel is 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // forbidden (save the ilist_node<NodeTy>) so no one will ever notice 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the superposition. 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return static_cast<IVStrideUse*>(&Sentinel); 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void destroySentinel(IVStrideUse*) {} 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVStrideUse *provideInitialHead() const { return createSentinel(); } 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); } 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void noteHead(IVStrideUse*, IVStrideUse*) {} 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate: 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mutable ilist_node<IVStrideUse> Sentinel; 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass IVUsers : public LoopPass { 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman friend class IVStrideUse; 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Loop *L; 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoopInfo *LI; 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DominatorTree *DT; 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ScalarEvolution *SE; 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetData *TD; 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallPtrSet<Instruction*,16> Processed; 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// IVUses - A list of all tracked IV uses of induction variable expressions 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// we are interested in. 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ilist<IVStrideUse> IVUses; 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void getAnalysisUsage(AnalysisUsage &AU) const; 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual bool runOnLoop(Loop *L, LPPassManager &LPM); 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void releaseMemory(); 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static char ID; // Pass ID, replacement for typeid 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVUsers(); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Loop *getLoop() const { return L; } 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// reducible SCEV, recursively add its users to the IVUsesByStride set and 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// return true. Otherwise, return false. 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AddUsersIfInteresting(Instruction *I); 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IVStrideUse &AddUser(Instruction *User, Value *Operand); 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getReplacementExpr - Return a SCEV expression which computes the 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// value of the OperandValToReplace of the given IVStrideUse. 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SCEV *getReplacementExpr(const IVStrideUse &IU) const; 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getExpr - Return the expression for the use. 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SCEV *getExpr(const IVStrideUse &IU) const; 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const; 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef ilist<IVStrideUse>::iterator iterator; 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typedef ilist<IVStrideUse>::const_iterator const_iterator; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman iterator begin() { return IVUses.begin(); } 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman iterator end() { return IVUses.end(); } 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const_iterator begin() const { return IVUses.begin(); } 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const_iterator end() const { return IVUses.end(); } 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool empty() const { return IVUses.empty(); } 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void print(raw_ostream &OS, const Module* = 0) const; 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// dump - This method is used for debugging. 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void dump() const; 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanPass *createIVUsersPass(); 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 180