StackLifetime.h 6.4 KB

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