IVUsers.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. #ifndef LLVM_ANALYSIS_IVUSERS_H
  15. #define LLVM_ANALYSIS_IVUSERS_H
  16. #include "llvm/Analysis/LoopPass.h"
  17. #include "llvm/Analysis/ScalarEvolutionNormalization.h"
  18. #include "llvm/IR/ValueHandle.h"
  19. namespace llvm {
  20. class AssumptionCache;
  21. class DominatorTree;
  22. class Instruction;
  23. class Value;
  24. class ScalarEvolution;
  25. class SCEV;
  26. class IVUsers;
  27. class DataLayout;
  28. /// IVStrideUse - Keep track of one use of a strided induction variable.
  29. /// The Expr member keeps track of the expression, User is the actual user
  30. /// instruction of the operand, and 'OperandValToReplace' is the operand of
  31. /// the User that is the use.
  32. class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
  33. friend class IVUsers;
  34. public:
  35. IVStrideUse(IVUsers *P, Instruction* U, Value *O)
  36. : CallbackVH(U), Parent(P), OperandValToReplace(O) {
  37. }
  38. /// getUser - Return the user instruction for this use.
  39. Instruction *getUser() const {
  40. return cast<Instruction>(getValPtr());
  41. }
  42. /// setUser - Assign a new user instruction for this use.
  43. void setUser(Instruction *NewUser) {
  44. setValPtr(NewUser);
  45. }
  46. /// getOperandValToReplace - Return the Value of the operand in the user
  47. /// instruction that this IVStrideUse is representing.
  48. Value *getOperandValToReplace() const {
  49. return OperandValToReplace;
  50. }
  51. /// setOperandValToReplace - Assign a new Value as the operand value
  52. /// to replace.
  53. void setOperandValToReplace(Value *Op) {
  54. OperandValToReplace = Op;
  55. }
  56. /// getPostIncLoops - Return the set of loops for which the expression has
  57. /// been adjusted to use post-inc mode.
  58. const PostIncLoopSet &getPostIncLoops() const {
  59. return PostIncLoops;
  60. }
  61. /// transformToPostInc - Transform the expression to post-inc form for the
  62. /// given loop.
  63. void transformToPostInc(const Loop *L);
  64. private:
  65. /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
  66. IVUsers *Parent;
  67. /// OperandValToReplace - The Value of the operand in the user instruction
  68. /// that this IVStrideUse is representing.
  69. WeakVH OperandValToReplace;
  70. /// PostIncLoops - The set of loops for which Expr has been adjusted to
  71. /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
  72. PostIncLoopSet PostIncLoops;
  73. /// Deleted - Implementation of CallbackVH virtual function to
  74. /// receive notification when the User is deleted.
  75. void deleted() override;
  76. };
  77. template<> struct ilist_traits<IVStrideUse>
  78. : public ilist_default_traits<IVStrideUse> {
  79. // createSentinel is used to get hold of a node that marks the end of
  80. // the list...
  81. // The sentinel is relative to this instance, so we use a non-static
  82. // method.
  83. IVStrideUse *createSentinel() const {
  84. // since i(p)lists always publicly derive from the corresponding
  85. // traits, placing a data member in this class will augment i(p)list.
  86. // But since the NodeTy is expected to publicly derive from
  87. // ilist_node<NodeTy>, there is a legal viable downcast from it
  88. // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
  89. // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
  90. // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
  91. // the superposition.
  92. return static_cast<IVStrideUse*>(&Sentinel);
  93. }
  94. static void destroySentinel(IVStrideUse*) {}
  95. IVStrideUse *provideInitialHead() const { return createSentinel(); }
  96. IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
  97. static void noteHead(IVStrideUse*, IVStrideUse*) {}
  98. private:
  99. mutable ilist_node<IVStrideUse> Sentinel;
  100. };
  101. class IVUsers : public LoopPass {
  102. friend class IVStrideUse;
  103. Loop *L;
  104. AssumptionCache *AC;
  105. LoopInfo *LI;
  106. DominatorTree *DT;
  107. ScalarEvolution *SE;
  108. SmallPtrSet<Instruction*, 16> Processed;
  109. /// IVUses - A list of all tracked IV uses of induction variable expressions
  110. /// we are interested in.
  111. ilist<IVStrideUse> IVUses;
  112. // Ephemeral values used by @llvm.assume in this function.
  113. SmallPtrSet<const Value *, 32> EphValues;
  114. void getAnalysisUsage(AnalysisUsage &AU) const override;
  115. bool runOnLoop(Loop *L, LPPassManager &LPM) override;
  116. void releaseMemory() override;
  117. public:
  118. static char ID; // Pass ID, replacement for typeid
  119. IVUsers();
  120. Loop *getLoop() const { return L; }
  121. /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
  122. /// reducible SCEV, recursively add its users to the IVUsesByStride set and
  123. /// return true. Otherwise, return false.
  124. bool AddUsersIfInteresting(Instruction *I);
  125. IVStrideUse &AddUser(Instruction *User, Value *Operand);
  126. /// getReplacementExpr - Return a SCEV expression which computes the
  127. /// value of the OperandValToReplace of the given IVStrideUse.
  128. const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
  129. /// getExpr - Return the expression for the use.
  130. const SCEV *getExpr(const IVStrideUse &IU) const;
  131. const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
  132. typedef ilist<IVStrideUse>::iterator iterator;
  133. typedef ilist<IVStrideUse>::const_iterator const_iterator;
  134. iterator begin() { return IVUses.begin(); }
  135. iterator end() { return IVUses.end(); }
  136. const_iterator begin() const { return IVUses.begin(); }
  137. const_iterator end() const { return IVUses.end(); }
  138. bool empty() const { return IVUses.empty(); }
  139. bool isIVUserOrOperand(Instruction *Inst) const {
  140. return Processed.count(Inst);
  141. }
  142. void print(raw_ostream &OS, const Module* = nullptr) const override;
  143. /// dump - This method is used for debugging.
  144. void dump() const;
  145. protected:
  146. bool AddUsersImpl(Instruction *I, SmallPtrSetImpl<Loop*> &SimpleLoopNests);
  147. };
  148. Pass *createIVUsersPass();
  149. }
  150. #endif