LiveIntervalUnion.h [plain text]
#ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H
#define LLVM_CODEGEN_LIVEINTERVALUNION_H
#include "llvm/ADT/IntervalMap.h"
#include "llvm/CodeGen/LiveInterval.h"
namespace llvm {
class TargetRegisterInfo;
#ifndef NDEBUG
template <unsigned Element> class SparseBitVector;
typedef SparseBitVector<128> LiveVirtRegBitSet;
#endif
inline bool
overlap(const LiveInterval::Segment &VRSeg,
const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
}
class LiveIntervalUnion {
typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments;
public:
typedef LiveSegments::iterator SegmentIter;
typedef LiveSegments::Allocator Allocator;
class Query;
private:
unsigned Tag; LiveSegments Segments;
public:
explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {}
SegmentIter begin() { return Segments.begin(); }
SegmentIter end() { return Segments.end(); }
SegmentIter find(SlotIndex x) { return Segments.find(x); }
bool empty() const { return Segments.empty(); }
SlotIndex startIndex() const { return Segments.start(); }
typedef LiveSegments Map;
const Map &getMap() { return Segments; }
unsigned getTag() const { return Tag; }
bool changedSince(unsigned tag) const { return tag != Tag; }
void unify(LiveInterval &VirtReg, const LiveRange &Range);
void unify(LiveInterval &VirtReg) {
unify(VirtReg, VirtReg);
}
void extract(LiveInterval &VirtReg, const LiveRange &Range);
void extract(LiveInterval &VirtReg) {
extract(VirtReg, VirtReg);
}
void clear() { Segments.clear(); ++Tag; }
void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const;
#ifndef NDEBUG
void verify(LiveVirtRegBitSet& VisitedVRegs);
#endif
class Query {
LiveIntervalUnion *LiveUnion;
LiveInterval *VirtReg;
LiveInterval::iterator VirtRegI; SegmentIter LiveUnionI; SmallVector<LiveInterval*,4> InterferingVRegs;
bool CheckedFirstInterference;
bool SeenAllInterferences;
bool SeenUnspillableVReg;
unsigned Tag, UserTag;
public:
Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),
SeenAllInterferences(false), SeenUnspillableVReg(false)
{}
void clear() {
LiveUnion = nullptr;
VirtReg = nullptr;
InterferingVRegs.clear();
CheckedFirstInterference = false;
SeenAllInterferences = false;
SeenUnspillableVReg = false;
Tag = 0;
UserTag = 0;
}
void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) {
assert(VReg && LIU && "Invalid arguments");
if (UserTag == UTag && VirtReg == VReg &&
LiveUnion == LIU && !LIU->changedSince(Tag)) {
return;
}
clear();
LiveUnion = LIU;
VirtReg = VReg;
Tag = LIU->getTag();
UserTag = UTag;
}
LiveInterval &virtReg() const {
assert(VirtReg && "uninitialized");
return *VirtReg;
}
bool checkInterference() { return collectInterferingVRegs(1); }
unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX);
bool isSeenInterference(LiveInterval *VReg) const;
bool seenAllInterferences() const { return SeenAllInterferences; }
bool seenUnspillableVReg() const { return SeenUnspillableVReg; }
const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
return InterferingVRegs;
}
private:
Query(const Query&) LLVM_DELETED_FUNCTION;
void operator=(const Query&) LLVM_DELETED_FUNCTION;
};
class Array {
unsigned Size;
LiveIntervalUnion *LIUs;
public:
Array() : Size(0), LIUs(nullptr) {}
~Array() { clear(); }
void init(LiveIntervalUnion::Allocator&, unsigned Size);
unsigned size() const { return Size; }
void clear();
LiveIntervalUnion& operator[](unsigned idx) {
assert(idx < Size && "idx out of bounds");
return LIUs[idx];
}
};
};
}
#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION_H)