Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.9 KiB

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