File indexing completed on 2026-05-10 08:43:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H
0017 #define LLVM_CODEGEN_LIVEINTERVALUNION_H
0018
0019 #include "llvm/ADT/IntervalMap.h"
0020 #include "llvm/ADT/SmallVector.h"
0021 #include "llvm/CodeGen/LiveInterval.h"
0022 #include "llvm/CodeGen/SlotIndexes.h"
0023 #include <cassert>
0024 #include <limits>
0025
0026 namespace llvm {
0027
0028 class raw_ostream;
0029 class TargetRegisterInfo;
0030
0031 #ifndef NDEBUG
0032
0033 template <unsigned Element> class SparseBitVector;
0034
0035 using LiveVirtRegBitSet = SparseBitVector<128>;
0036 #endif
0037
0038
0039
0040
0041
0042 class LiveIntervalUnion {
0043
0044
0045
0046 using LiveSegments = IntervalMap<SlotIndex, const LiveInterval *>;
0047
0048 public:
0049
0050
0051
0052 using SegmentIter = LiveSegments::iterator;
0053
0054
0055 using ConstSegmentIter = LiveSegments::const_iterator;
0056
0057
0058 using Allocator = LiveSegments::Allocator;
0059
0060 private:
0061 unsigned Tag = 0;
0062 LiveSegments Segments;
0063
0064 public:
0065 explicit LiveIntervalUnion(Allocator &a) : Segments(a) {}
0066
0067
0068
0069 SegmentIter begin() { return Segments.begin(); }
0070 SegmentIter end() { return Segments.end(); }
0071 SegmentIter find(SlotIndex x) { return Segments.find(x); }
0072 ConstSegmentIter begin() const { return Segments.begin(); }
0073 ConstSegmentIter end() const { return Segments.end(); }
0074 ConstSegmentIter find(SlotIndex x) const { return Segments.find(x); }
0075
0076 bool empty() const { return Segments.empty(); }
0077 SlotIndex startIndex() const { return Segments.start(); }
0078 SlotIndex endIndex() const { return Segments.stop(); }
0079
0080
0081 using Map = LiveSegments;
0082 const Map &getMap() const { return Segments; }
0083
0084
0085 unsigned getTag() const { return Tag; }
0086
0087
0088 bool changedSince(unsigned tag) const { return tag != Tag; }
0089
0090
0091 void unify(const LiveInterval &VirtReg, const LiveRange &Range);
0092
0093
0094 void extract(const LiveInterval &VirtReg, const LiveRange &Range);
0095
0096
0097 void clear() { Segments.clear(); ++Tag; }
0098
0099
0100 void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const;
0101
0102 #ifndef NDEBUG
0103
0104 void verify(LiveVirtRegBitSet& VisitedVRegs);
0105 #endif
0106
0107
0108 const LiveInterval *getOneVReg() const;
0109
0110
0111
0112 class Query {
0113 const LiveIntervalUnion *LiveUnion = nullptr;
0114 const LiveRange *LR = nullptr;
0115 LiveRange::const_iterator LRI;
0116 ConstSegmentIter LiveUnionI;
0117 SmallVector<const LiveInterval *, 4> InterferingVRegs;
0118 bool CheckedFirstInterference = false;
0119 bool SeenAllInterferences = false;
0120 unsigned Tag = 0;
0121 unsigned UserTag = 0;
0122
0123
0124
0125 unsigned collectInterferingVRegs(unsigned MaxInterferingRegs);
0126
0127
0128 bool isSeenInterference(const LiveInterval *VirtReg) const;
0129
0130 public:
0131 Query() = default;
0132 Query(const LiveRange &LR, const LiveIntervalUnion &LIU)
0133 : LiveUnion(&LIU), LR(&LR) {}
0134 Query(const Query &) = delete;
0135 Query &operator=(const Query &) = delete;
0136
0137 void reset(unsigned NewUserTag, const LiveRange &NewLR,
0138 const LiveIntervalUnion &NewLiveUnion) {
0139 LiveUnion = &NewLiveUnion;
0140 LR = &NewLR;
0141 InterferingVRegs.clear();
0142 CheckedFirstInterference = false;
0143 SeenAllInterferences = false;
0144 Tag = NewLiveUnion.getTag();
0145 UserTag = NewUserTag;
0146 }
0147
0148 void init(unsigned NewUserTag, const LiveRange &NewLR,
0149 const LiveIntervalUnion &NewLiveUnion) {
0150 if (UserTag == NewUserTag && LR == &NewLR && LiveUnion == &NewLiveUnion &&
0151 !NewLiveUnion.changedSince(Tag)) {
0152
0153 return;
0154 }
0155 reset(NewUserTag, NewLR, NewLiveUnion);
0156 }
0157
0158
0159 bool checkInterference() { return collectInterferingVRegs(1); }
0160
0161
0162 const SmallVectorImpl<const LiveInterval *> &interferingVRegs(
0163 unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max()) {
0164 if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size())
0165 collectInterferingVRegs(MaxInterferingRegs);
0166 return InterferingVRegs;
0167 }
0168 };
0169
0170
0171 class Array {
0172 unsigned Size = 0;
0173 LiveIntervalUnion *LIUs = nullptr;
0174
0175 public:
0176 Array() = default;
0177 ~Array() { clear(); }
0178
0179 Array(Array &&Other) : Size(Other.Size), LIUs(Other.LIUs) {
0180 Other.Size = 0;
0181 Other.LIUs = nullptr;
0182 }
0183
0184 Array(const Array &) = delete;
0185
0186
0187
0188 void init(LiveIntervalUnion::Allocator&, unsigned Size);
0189
0190 unsigned size() const { return Size; }
0191
0192 void clear();
0193
0194 LiveIntervalUnion& operator[](unsigned idx) {
0195 assert(idx < Size && "idx out of bounds");
0196 return LIUs[idx];
0197 }
0198
0199 const LiveIntervalUnion& operator[](unsigned Idx) const {
0200 assert(Idx < Size && "Idx out of bounds");
0201 return LIUs[Idx];
0202 }
0203 };
0204 };
0205
0206 }
0207
0208 #endif