SSAUpdater.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SSAUpdater.h - Unstructured SSA Update Tool --------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file declares the SSAUpdater class.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
  18. #define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
  19. #include "llvm/ADT/ArrayRef.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include <string>
  22. namespace llvm {
  23. class BasicBlock;
  24. class Instruction;
  25. class LoadInst;
  26. class PHINode;
  27. template <typename T> class SmallVectorImpl;
  28. template <typename T> class SSAUpdaterTraits;
  29. class Type;
  30. class Use;
  31. class Value;
  32. /// Helper class for SSA formation on a set of values defined in
  33. /// multiple blocks.
  34. ///
  35. /// This is used when code duplication or another unstructured
  36. /// transformation wants to rewrite a set of uses of one value with uses of a
  37. /// set of values.
  38. class SSAUpdater {
  39. friend class SSAUpdaterTraits<SSAUpdater>;
  40. private:
  41. /// This keeps track of which value to use on a per-block basis. When we
  42. /// insert PHI nodes, we keep track of them here.
  43. void *AV = nullptr;
  44. /// ProtoType holds the type of the values being rewritten.
  45. Type *ProtoType = nullptr;
  46. /// PHI nodes are given a name based on ProtoName.
  47. std::string ProtoName;
  48. /// If this is non-null, the SSAUpdater adds all PHI nodes that it creates to
  49. /// the vector.
  50. SmallVectorImpl<PHINode *> *InsertedPHIs;
  51. public:
  52. /// If InsertedPHIs is specified, it will be filled
  53. /// in with all PHI Nodes created by rewriting.
  54. explicit SSAUpdater(SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
  55. SSAUpdater(const SSAUpdater &) = delete;
  56. SSAUpdater &operator=(const SSAUpdater &) = delete;
  57. ~SSAUpdater();
  58. /// Reset this object to get ready for a new set of SSA updates with
  59. /// type 'Ty'.
  60. ///
  61. /// PHI nodes get a name based on 'Name'.
  62. void Initialize(Type *Ty, StringRef Name);
  63. /// Indicate that a rewritten value is available in the specified block
  64. /// with the specified value.
  65. void AddAvailableValue(BasicBlock *BB, Value *V);
  66. /// Return true if the SSAUpdater already has a value for the specified
  67. /// block.
  68. bool HasValueForBlock(BasicBlock *BB) const;
  69. /// Return the value for the specified block if the SSAUpdater has one,
  70. /// otherwise return nullptr.
  71. Value *FindValueForBlock(BasicBlock *BB) const;
  72. /// Construct SSA form, materializing a value that is live at the end
  73. /// of the specified block.
  74. Value *GetValueAtEndOfBlock(BasicBlock *BB);
  75. /// Construct SSA form, materializing a value that is live in the
  76. /// middle of the specified block.
  77. ///
  78. /// \c GetValueInMiddleOfBlock is the same as \c GetValueAtEndOfBlock except
  79. /// in one important case: if there is a definition of the rewritten value
  80. /// after the 'use' in BB. Consider code like this:
  81. ///
  82. /// \code
  83. /// X1 = ...
  84. /// SomeBB:
  85. /// use(X)
  86. /// X2 = ...
  87. /// br Cond, SomeBB, OutBB
  88. /// \endcode
  89. ///
  90. /// In this case, there are two values (X1 and X2) added to the AvailableVals
  91. /// set by the client of the rewriter, and those values are both live out of
  92. /// their respective blocks. However, the use of X happens in the *middle* of
  93. /// a block. Because of this, we need to insert a new PHI node in SomeBB to
  94. /// merge the appropriate values, and this value isn't live out of the block.
  95. Value *GetValueInMiddleOfBlock(BasicBlock *BB);
  96. /// Rewrite a use of the symbolic value.
  97. ///
  98. /// This handles PHI nodes, which use their value in the corresponding
  99. /// predecessor. Note that this will not work if the use is supposed to be
  100. /// rewritten to a value defined in the same block as the use, but above it.
  101. /// Any 'AddAvailableValue's added for the use's block will be considered to
  102. /// be below it.
  103. void RewriteUse(Use &U);
  104. /// Rewrite a use like \c RewriteUse but handling in-block definitions.
  105. ///
  106. /// This version of the method can rewrite uses in the same block as
  107. /// a definition, because it assumes that all uses of a value are below any
  108. /// inserted values.
  109. void RewriteUseAfterInsertions(Use &U);
  110. private:
  111. Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
  112. };
  113. /// Helper class for promoting a collection of loads and stores into SSA
  114. /// Form using the SSAUpdater.
  115. ///
  116. /// This handles complexities that SSAUpdater doesn't, such as multiple loads
  117. /// and stores in one block.
  118. ///
  119. /// Clients of this class are expected to subclass this and implement the
  120. /// virtual methods.
  121. class LoadAndStorePromoter {
  122. protected:
  123. SSAUpdater &SSA;
  124. public:
  125. LoadAndStorePromoter(ArrayRef<const Instruction *> Insts,
  126. SSAUpdater &S, StringRef Name = StringRef());
  127. virtual ~LoadAndStorePromoter() = default;
  128. /// This does the promotion.
  129. ///
  130. /// Insts is a list of loads and stores to promote, and Name is the basename
  131. /// for the PHIs to insert. After this is complete, the loads and stores are
  132. /// removed from the code.
  133. void run(const SmallVectorImpl<Instruction *> &Insts);
  134. /// Return true if the specified instruction is in the Inst list.
  135. ///
  136. /// The Insts list is the one passed into the constructor. Clients should
  137. /// implement this with a more efficient version if possible.
  138. virtual bool isInstInList(Instruction *I,
  139. const SmallVectorImpl<Instruction *> &Insts) const;
  140. /// This hook is invoked after all the stores are found and inserted as
  141. /// available values.
  142. virtual void doExtraRewritesBeforeFinalDeletion() {}
  143. /// Clients can choose to implement this to get notified right before
  144. /// a load is RAUW'd another value.
  145. virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {}
  146. /// Called before each instruction is deleted.
  147. virtual void instructionDeleted(Instruction *I) const {}
  148. /// Called to update debug info associated with the instruction.
  149. virtual void updateDebugInfo(Instruction *I) const {}
  150. /// Return false if a sub-class wants to keep one of the loads/stores
  151. /// after the SSA construction.
  152. virtual bool shouldDelete(Instruction *I) const { return true; }
  153. };
  154. } // end namespace llvm
  155. #endif // LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
  156. #ifdef __GNUC__
  157. #pragma GCC diagnostic pop
  158. #endif