SROA.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SROA.h - Scalar Replacement Of Aggregates ----------------*- 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. /// \file
  14. /// This file provides the interface for LLVM's Scalar Replacement of
  15. /// Aggregates pass. This pass provides both aggregate splitting and the
  16. /// primary SSA formation used in the compiler.
  17. ///
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_TRANSFORMS_SCALAR_SROA_H
  20. #define LLVM_TRANSFORMS_SCALAR_SROA_H
  21. #include "llvm/ADT/MapVector.h"
  22. #include "llvm/ADT/PointerIntPair.h"
  23. #include "llvm/ADT/SetVector.h"
  24. #include "llvm/ADT/SmallVector.h"
  25. #include "llvm/IR/PassManager.h"
  26. #include "llvm/IR/ValueHandle.h"
  27. #include <vector>
  28. namespace llvm {
  29. class AllocaInst;
  30. class LoadInst;
  31. class StoreInst;
  32. class AssumptionCache;
  33. class DominatorTree;
  34. class DomTreeUpdater;
  35. class Function;
  36. class LLVMContext;
  37. class PHINode;
  38. class SelectInst;
  39. class Use;
  40. /// A private "module" namespace for types and utilities used by SROA. These
  41. /// are implementation details and should not be used by clients.
  42. namespace sroa LLVM_LIBRARY_VISIBILITY {
  43. class AllocaSliceRewriter;
  44. class AllocaSlices;
  45. class Partition;
  46. class SROALegacyPass;
  47. class SelectHandSpeculativity {
  48. unsigned char Storage = 0; // None are speculatable by default.
  49. using TrueVal = Bitfield::Element<bool, 0, 1>; // Low 0'th bit.
  50. using FalseVal = Bitfield::Element<bool, 1, 1>; // Low 1'th bit.
  51. public:
  52. SelectHandSpeculativity() = default;
  53. SelectHandSpeculativity &setAsSpeculatable(bool isTrueVal);
  54. bool isSpeculatable(bool isTrueVal) const;
  55. bool areAllSpeculatable() const;
  56. bool areAnySpeculatable() const;
  57. bool areNoneSpeculatable() const;
  58. // For interop as int half of PointerIntPair.
  59. explicit operator intptr_t() const { return static_cast<intptr_t>(Storage); }
  60. explicit SelectHandSpeculativity(intptr_t Storage_) : Storage(Storage_) {}
  61. };
  62. static_assert(sizeof(SelectHandSpeculativity) == sizeof(unsigned char));
  63. using PossiblySpeculatableLoad =
  64. PointerIntPair<LoadInst *, 2, sroa::SelectHandSpeculativity>;
  65. using UnspeculatableStore = StoreInst *;
  66. using RewriteableMemOp =
  67. std::variant<PossiblySpeculatableLoad, UnspeculatableStore>;
  68. using RewriteableMemOps = SmallVector<RewriteableMemOp, 2>;
  69. } // end namespace sroa
  70. enum class SROAOptions : bool { ModifyCFG, PreserveCFG };
  71. /// An optimization pass providing Scalar Replacement of Aggregates.
  72. ///
  73. /// This pass takes allocations which can be completely analyzed (that is, they
  74. /// don't escape) and tries to turn them into scalar SSA values. There are
  75. /// a few steps to this process.
  76. ///
  77. /// 1) It takes allocations of aggregates and analyzes the ways in which they
  78. /// are used to try to split them into smaller allocations, ideally of
  79. /// a single scalar data type. It will split up memcpy and memset accesses
  80. /// as necessary and try to isolate individual scalar accesses.
  81. /// 2) It will transform accesses into forms which are suitable for SSA value
  82. /// promotion. This can be replacing a memset with a scalar store of an
  83. /// integer value, or it can involve speculating operations on a PHI or
  84. /// select to be a PHI or select of the results.
  85. /// 3) Finally, this will try to detect a pattern of accesses which map cleanly
  86. /// onto insert and extract operations on a vector value, and convert them to
  87. /// this form. By doing so, it will enable promotion of vector aggregates to
  88. /// SSA vector values.
  89. class SROAPass : public PassInfoMixin<SROAPass> {
  90. LLVMContext *C = nullptr;
  91. DomTreeUpdater *DTU = nullptr;
  92. AssumptionCache *AC = nullptr;
  93. const bool PreserveCFG;
  94. /// Worklist of alloca instructions to simplify.
  95. ///
  96. /// Each alloca in the function is added to this. Each new alloca formed gets
  97. /// added to it as well to recursively simplify unless that alloca can be
  98. /// directly promoted. Finally, each time we rewrite a use of an alloca other
  99. /// the one being actively rewritten, we add it back onto the list if not
  100. /// already present to ensure it is re-visited.
  101. SetVector<AllocaInst *, SmallVector<AllocaInst *, 16>> Worklist;
  102. /// A collection of instructions to delete.
  103. /// We try to batch deletions to simplify code and make things a bit more
  104. /// efficient. We also make sure there is no dangling pointers.
  105. SmallVector<WeakVH, 8> DeadInsts;
  106. /// Post-promotion worklist.
  107. ///
  108. /// Sometimes we discover an alloca which has a high probability of becoming
  109. /// viable for SROA after a round of promotion takes place. In those cases,
  110. /// the alloca is enqueued here for re-processing.
  111. ///
  112. /// Note that we have to be very careful to clear allocas out of this list in
  113. /// the event they are deleted.
  114. SetVector<AllocaInst *, SmallVector<AllocaInst *, 16>> PostPromotionWorklist;
  115. /// A collection of alloca instructions we can directly promote.
  116. std::vector<AllocaInst *> PromotableAllocas;
  117. /// A worklist of PHIs to speculate prior to promoting allocas.
  118. ///
  119. /// All of these PHIs have been checked for the safety of speculation and by
  120. /// being speculated will allow promoting allocas currently in the promotable
  121. /// queue.
  122. SetVector<PHINode *, SmallVector<PHINode *, 8>> SpeculatablePHIs;
  123. /// A worklist of select instructions to rewrite prior to promoting
  124. /// allocas.
  125. SmallMapVector<SelectInst *, sroa::RewriteableMemOps, 8> SelectsToRewrite;
  126. /// Select instructions that use an alloca and are subsequently loaded can be
  127. /// rewritten to load both input pointers and then select between the result,
  128. /// allowing the load of the alloca to be promoted.
  129. /// From this:
  130. /// %P2 = select i1 %cond, ptr %Alloca, ptr %Other
  131. /// %V = load <type>, ptr %P2
  132. /// to:
  133. /// %V1 = load <type>, ptr %Alloca -> will be mem2reg'd
  134. /// %V2 = load <type>, ptr %Other
  135. /// %V = select i1 %cond, <type> %V1, <type> %V2
  136. ///
  137. /// We can do this to a select if its only uses are loads
  138. /// and if either the operand to the select can be loaded unconditionally,
  139. /// or if we are allowed to perform CFG modifications.
  140. /// If found an intervening bitcast with a single use of the load,
  141. /// allow the promotion.
  142. static std::optional<sroa::RewriteableMemOps>
  143. isSafeSelectToSpeculate(SelectInst &SI, bool PreserveCFG);
  144. public:
  145. /// If \p PreserveCFG is set, then the pass is not allowed to modify CFG
  146. /// in any way, even if it would update CFG analyses.
  147. SROAPass(SROAOptions PreserveCFG);
  148. /// Run the pass over the function.
  149. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  150. void printPipeline(raw_ostream &OS,
  151. function_ref<StringRef(StringRef)> MapClassName2PassName);
  152. private:
  153. friend class sroa::AllocaSliceRewriter;
  154. friend class sroa::SROALegacyPass;
  155. /// Helper used by both the public run method and by the legacy pass.
  156. PreservedAnalyses runImpl(Function &F, DomTreeUpdater &RunDTU,
  157. AssumptionCache &RunAC);
  158. PreservedAnalyses runImpl(Function &F, DominatorTree &RunDT,
  159. AssumptionCache &RunAC);
  160. bool presplitLoadsAndStores(AllocaInst &AI, sroa::AllocaSlices &AS);
  161. AllocaInst *rewritePartition(AllocaInst &AI, sroa::AllocaSlices &AS,
  162. sroa::Partition &P);
  163. bool splitAlloca(AllocaInst &AI, sroa::AllocaSlices &AS);
  164. std::pair<bool /*Changed*/, bool /*CFGChanged*/> runOnAlloca(AllocaInst &AI);
  165. void clobberUse(Use &U);
  166. bool deleteDeadInstructions(SmallPtrSetImpl<AllocaInst *> &DeletedAllocas);
  167. bool promoteAllocas(Function &F);
  168. };
  169. } // end namespace llvm
  170. #endif // LLVM_TRANSFORMS_SCALAR_SROA_H
  171. #ifdef __GNUC__
  172. #pragma GCC diagnostic pop
  173. #endif