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