LiveIntervalUnion.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- LiveIntervalUnion.h - Live interval union data struct ---*- 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. // LiveIntervalUnion is a union of live segments across multiple live virtual
  15. // registers. This may be used during coalescing to represent a congruence
  16. // class, or during register allocation to model liveness of a physical
  17. // register.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H
  21. #define LLVM_CODEGEN_LIVEINTERVALUNION_H
  22. #include "llvm/ADT/IntervalMap.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. #include "llvm/CodeGen/LiveInterval.h"
  25. #include "llvm/CodeGen/SlotIndexes.h"
  26. #include <cassert>
  27. #include <limits>
  28. namespace llvm {
  29. class raw_ostream;
  30. class TargetRegisterInfo;
  31. #ifndef NDEBUG
  32. // forward declaration
  33. template <unsigned Element> class SparseBitVector;
  34. using LiveVirtRegBitSet = SparseBitVector<128>;
  35. #endif
  36. /// Union of live intervals that are strong candidates for coalescing into a
  37. /// single register (either physical or virtual depending on the context). We
  38. /// expect the constituent live intervals to be disjoint, although we may
  39. /// eventually make exceptions to handle value-based interference.
  40. class LiveIntervalUnion {
  41. // A set of live virtual register segments that supports fast insertion,
  42. // intersection, and removal.
  43. // Mapping SlotIndex intervals to virtual register numbers.
  44. using LiveSegments = IntervalMap<SlotIndex, LiveInterval*>;
  45. public:
  46. // SegmentIter can advance to the next segment ordered by starting position
  47. // which may belong to a different live virtual register. We also must be able
  48. // to reach the current segment's containing virtual register.
  49. using SegmentIter = LiveSegments::iterator;
  50. /// Const version of SegmentIter.
  51. using ConstSegmentIter = LiveSegments::const_iterator;
  52. // LiveIntervalUnions share an external allocator.
  53. using Allocator = LiveSegments::Allocator;
  54. private:
  55. unsigned Tag = 0; // unique tag for current contents.
  56. LiveSegments Segments; // union of virtual reg segments
  57. public:
  58. explicit LiveIntervalUnion(Allocator &a) : Segments(a) {}
  59. // Iterate over all segments in the union of live virtual registers ordered
  60. // by their starting position.
  61. SegmentIter begin() { return Segments.begin(); }
  62. SegmentIter end() { return Segments.end(); }
  63. SegmentIter find(SlotIndex x) { return Segments.find(x); }
  64. ConstSegmentIter begin() const { return Segments.begin(); }
  65. ConstSegmentIter end() const { return Segments.end(); }
  66. ConstSegmentIter find(SlotIndex x) const { return Segments.find(x); }
  67. bool empty() const { return Segments.empty(); }
  68. SlotIndex startIndex() const { return Segments.start(); }
  69. SlotIndex endIndex() const { return Segments.stop(); }
  70. // Provide public access to the underlying map to allow overlap iteration.
  71. using Map = LiveSegments;
  72. const Map &getMap() const { return Segments; }
  73. /// getTag - Return an opaque tag representing the current state of the union.
  74. unsigned getTag() const { return Tag; }
  75. /// changedSince - Return true if the union change since getTag returned tag.
  76. bool changedSince(unsigned tag) const { return tag != Tag; }
  77. // Add a live virtual register to this union and merge its segments.
  78. void unify(LiveInterval &VirtReg, const LiveRange &Range);
  79. // Remove a live virtual register's segments from this union.
  80. void extract(LiveInterval &VirtReg, const LiveRange &Range);
  81. // Remove all inserted virtual registers.
  82. void clear() { Segments.clear(); ++Tag; }
  83. // Print union, using TRI to translate register names
  84. void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const;
  85. #ifndef NDEBUG
  86. // Verify the live intervals in this union and add them to the visited set.
  87. void verify(LiveVirtRegBitSet& VisitedVRegs);
  88. #endif
  89. // Get any virtual register that is assign to this physical unit
  90. LiveInterval *getOneVReg() const;
  91. /// Query interferences between a single live virtual register and a live
  92. /// interval union.
  93. class Query {
  94. const LiveIntervalUnion *LiveUnion = nullptr;
  95. const LiveRange *LR = nullptr;
  96. LiveRange::const_iterator LRI; ///< current position in LR
  97. ConstSegmentIter LiveUnionI; ///< current position in LiveUnion
  98. SmallVector<LiveInterval *, 4> InterferingVRegs;
  99. bool CheckedFirstInterference = false;
  100. bool SeenAllInterferences = false;
  101. unsigned Tag = 0;
  102. unsigned UserTag = 0;
  103. // Count the virtual registers in this union that interfere with this
  104. // query's live virtual register, up to maxInterferingRegs.
  105. unsigned collectInterferingVRegs(unsigned MaxInterferingRegs);
  106. // Was this virtual register visited during collectInterferingVRegs?
  107. bool isSeenInterference(LiveInterval *VirtReg) const;
  108. public:
  109. Query() = default;
  110. Query(const LiveRange &LR, const LiveIntervalUnion &LIU)
  111. : LiveUnion(&LIU), LR(&LR) {}
  112. Query(const Query &) = delete;
  113. Query &operator=(const Query &) = delete;
  114. void reset(unsigned NewUserTag, const LiveRange &NewLR,
  115. const LiveIntervalUnion &NewLiveUnion) {
  116. LiveUnion = &NewLiveUnion;
  117. LR = &NewLR;
  118. InterferingVRegs.clear();
  119. CheckedFirstInterference = false;
  120. SeenAllInterferences = false;
  121. Tag = NewLiveUnion.getTag();
  122. UserTag = NewUserTag;
  123. }
  124. void init(unsigned NewUserTag, const LiveRange &NewLR,
  125. const LiveIntervalUnion &NewLiveUnion) {
  126. if (UserTag == NewUserTag && LR == &NewLR && LiveUnion == &NewLiveUnion &&
  127. !NewLiveUnion.changedSince(Tag)) {
  128. // Retain cached results, e.g. firstInterference.
  129. return;
  130. }
  131. reset(NewUserTag, NewLR, NewLiveUnion);
  132. }
  133. // Does this live virtual register interfere with the union?
  134. bool checkInterference() { return collectInterferingVRegs(1); }
  135. // Vector generated by collectInterferingVRegs.
  136. const SmallVectorImpl<LiveInterval *> &interferingVRegs(
  137. unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max()) {
  138. if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size())
  139. collectInterferingVRegs(MaxInterferingRegs);
  140. return InterferingVRegs;
  141. }
  142. };
  143. // Array of LiveIntervalUnions.
  144. class Array {
  145. unsigned Size = 0;
  146. LiveIntervalUnion *LIUs = nullptr;
  147. public:
  148. Array() = default;
  149. ~Array() { clear(); }
  150. // Initialize the array to have Size entries.
  151. // Reuse an existing allocation if the size matches.
  152. void init(LiveIntervalUnion::Allocator&, unsigned Size);
  153. unsigned size() const { return Size; }
  154. void clear();
  155. LiveIntervalUnion& operator[](unsigned idx) {
  156. assert(idx < Size && "idx out of bounds");
  157. return LIUs[idx];
  158. }
  159. const LiveIntervalUnion& operator[](unsigned Idx) const {
  160. assert(Idx < Size && "Idx out of bounds");
  161. return LIUs[Idx];
  162. }
  163. };
  164. };
  165. } // end namespace llvm
  166. #endif // LLVM_CODEGEN_LIVEINTERVALUNION_H
  167. #ifdef __GNUC__
  168. #pragma GCC diagnostic pop
  169. #endif