StackLifetime.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- StackLifetime.h - Alloca Lifetime Analysis --------------*- 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. #ifndef LLVM_ANALYSIS_STACKLIFETIME_H
  14. #define LLVM_ANALYSIS_STACKLIFETIME_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/BitVector.h"
  17. #include "llvm/ADT/DenseMap.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/ADT/StringExtras.h"
  20. #include "llvm/IR/IntrinsicInst.h"
  21. #include "llvm/IR/PassManager.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. #include <cassert>
  24. #include <utility>
  25. namespace llvm {
  26. class AllocaInst;
  27. class BasicBlock;
  28. class Function;
  29. class Instruction;
  30. /// Compute live ranges of allocas.
  31. /// Live ranges are represented as sets of "interesting" instructions, which are
  32. /// defined as instructions that may start or end an alloca's lifetime. These
  33. /// are:
  34. /// * lifetime.start and lifetime.end intrinsics
  35. /// * first instruction of any basic block
  36. /// Interesting instructions are numbered in the depth-first walk of the CFG,
  37. /// and in the program order inside each basic block.
  38. class StackLifetime {
  39. /// A class representing liveness information for a single basic block.
  40. /// Each bit in the BitVector represents the liveness property
  41. /// for a different stack slot.
  42. struct BlockLifetimeInfo {
  43. explicit BlockLifetimeInfo(unsigned Size)
  44. : Begin(Size), End(Size), LiveIn(Size), LiveOut(Size) {}
  45. /// Which slots BEGINs in each basic block.
  46. BitVector Begin;
  47. /// Which slots ENDs in each basic block.
  48. BitVector End;
  49. /// Which slots are marked as LIVE_IN, coming into each basic block.
  50. BitVector LiveIn;
  51. /// Which slots are marked as LIVE_OUT, coming out of each basic block.
  52. BitVector LiveOut;
  53. };
  54. public:
  55. class LifetimeAnnotationWriter;
  56. /// This class represents a set of interesting instructions where an alloca is
  57. /// live.
  58. class LiveRange {
  59. BitVector Bits;
  60. friend raw_ostream &operator<<(raw_ostream &OS,
  61. const StackLifetime::LiveRange &R);
  62. public:
  63. LiveRange(unsigned Size, bool Set = false) : Bits(Size, Set) {}
  64. void addRange(unsigned Start, unsigned End) { Bits.set(Start, End); }
  65. bool overlaps(const LiveRange &Other) const {
  66. return Bits.anyCommon(Other.Bits);
  67. }
  68. void join(const LiveRange &Other) { Bits |= Other.Bits; }
  69. bool test(unsigned Idx) const { return Bits.test(Idx); }
  70. };
  71. // Controls what is "alive" if control flow may reach the instruction
  72. // with a different liveness of the alloca.
  73. enum class LivenessType {
  74. May, // May be alive on some path.
  75. Must, // Must be alive on every path.
  76. };
  77. private:
  78. const Function &F;
  79. LivenessType Type;
  80. /// Maps active slots (per bit) for each basic block.
  81. using LivenessMap = DenseMap<const BasicBlock *, BlockLifetimeInfo>;
  82. LivenessMap BlockLiveness;
  83. /// Interesting instructions. Instructions of the same block are adjustent
  84. /// preserve in-block order.
  85. SmallVector<const IntrinsicInst *, 64> Instructions;
  86. /// A range [Start, End) of instruction ids for each basic block.
  87. /// Instructions inside each BB have monotonic and consecutive ids.
  88. DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
  89. ArrayRef<const AllocaInst *> Allocas;
  90. unsigned NumAllocas;
  91. DenseMap<const AllocaInst *, unsigned> AllocaNumbering;
  92. /// LiveRange for allocas.
  93. SmallVector<LiveRange, 8> LiveRanges;
  94. /// The set of allocas that have at least one lifetime.start. All other
  95. /// allocas get LiveRange that corresponds to the entire function.
  96. BitVector InterestingAllocas;
  97. struct Marker {
  98. unsigned AllocaNo;
  99. bool IsStart;
  100. };
  101. /// List of {InstNo, {AllocaNo, IsStart}} for each BB, ordered by InstNo.
  102. DenseMap<const BasicBlock *, SmallVector<std::pair<unsigned, Marker>, 4>>
  103. BBMarkers;
  104. bool HasUnknownLifetimeStartOrEnd = false;
  105. void dumpAllocas() const;
  106. void dumpBlockLiveness() const;
  107. void dumpLiveRanges() const;
  108. void collectMarkers();
  109. void calculateLocalLiveness();
  110. void calculateLiveIntervals();
  111. public:
  112. StackLifetime(const Function &F, ArrayRef<const AllocaInst *> Allocas,
  113. LivenessType Type);
  114. void run();
  115. iterator_range<
  116. filter_iterator<ArrayRef<const IntrinsicInst *>::const_iterator,
  117. std::function<bool(const IntrinsicInst *)>>>
  118. getMarkers() const {
  119. std::function<bool(const IntrinsicInst *)> NotNull(
  120. [](const IntrinsicInst *I) -> bool { return I; });
  121. return make_filter_range(Instructions, NotNull);
  122. }
  123. /// Returns a set of "interesting" instructions where the given alloca is
  124. /// live. Not all instructions in a function are interesting: we pick a set
  125. /// that is large enough for LiveRange::Overlaps to be correct.
  126. const LiveRange &getLiveRange(const AllocaInst *AI) const;
  127. /// Returns true if instruction is reachable from entry.
  128. bool isReachable(const Instruction *I) const;
  129. /// Returns true if the alloca is alive after the instruction.
  130. bool isAliveAfter(const AllocaInst *AI, const Instruction *I) const;
  131. /// Returns a live range that represents an alloca that is live throughout the
  132. /// entire function.
  133. LiveRange getFullLiveRange() const {
  134. return LiveRange(Instructions.size(), true);
  135. }
  136. void print(raw_ostream &O);
  137. };
  138. static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) {
  139. OS << "{";
  140. ListSeparator LS;
  141. for (int Idx = V.find_first(); Idx >= 0; Idx = V.find_next(Idx))
  142. OS << LS << Idx;
  143. OS << "}";
  144. return OS;
  145. }
  146. inline raw_ostream &operator<<(raw_ostream &OS,
  147. const StackLifetime::LiveRange &R) {
  148. return OS << R.Bits;
  149. }
  150. /// Printer pass for testing.
  151. class StackLifetimePrinterPass
  152. : public PassInfoMixin<StackLifetimePrinterPass> {
  153. StackLifetime::LivenessType Type;
  154. raw_ostream &OS;
  155. public:
  156. StackLifetimePrinterPass(raw_ostream &OS, StackLifetime::LivenessType Type)
  157. : Type(Type), OS(OS) {}
  158. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  159. void printPipeline(raw_ostream &OS,
  160. function_ref<StringRef(StringRef)> MapClassName2PassName);
  161. };
  162. } // end namespace llvm
  163. #endif // LLVM_ANALYSIS_STACKLIFETIME_H
  164. #ifdef __GNUC__
  165. #pragma GCC diagnostic pop
  166. #endif