const LiveRange *LR = nullptr;
LiveRange::const_iterator LRI; ///< current position in LR
ConstSegmentIter LiveUnionI; ///< current position in LiveUnion
- Optional<SmallVector<LiveInterval *, 4>> InterferingVRegs;
+ SmallVector<LiveInterval *, 4> InterferingVRegs;
bool CheckedFirstInterference = false;
bool SeenAllInterferences = false;
unsigned Tag = 0;
unsigned UserTag = 0;
+ // Count the virtual registers in this union that interfere with this
+ // query's live virtual register, up to maxInterferingRegs.
+ unsigned collectInterferingVRegs(unsigned MaxInterferingRegs);
+
+ // Was this virtual register visited during collectInterferingVRegs?
+ bool isSeenInterference(LiveInterval *VirtReg) const;
+
public:
Query() = default;
Query(const LiveRange &LR, const LiveIntervalUnion &LIU)
const LiveIntervalUnion &NewLiveUnion) {
LiveUnion = &NewLiveUnion;
LR = &NewLR;
- InterferingVRegs = None;
+ InterferingVRegs.clear();
CheckedFirstInterference = false;
SeenAllInterferences = false;
Tag = NewLiveUnion.getTag();
// Does this live virtual register interfere with the union?
bool checkInterference() { return collectInterferingVRegs(1); }
- // Count the virtual registers in this union that interfere with this
- // query's live virtual register, up to maxInterferingRegs.
- unsigned collectInterferingVRegs(
- unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max());
-
- // Was this virtual register visited during collectInterferingVRegs?
- bool isSeenInterference(LiveInterval *VirtReg) const;
-
- // Did collectInterferingVRegs collect all interferences?
- bool seenAllInterferences() const { return SeenAllInterferences; }
-
// Vector generated by collectInterferingVRegs.
- const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
- return *InterferingVRegs;
+ const SmallVectorImpl<LiveInterval *> &interferingVRegs(
+ unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max()) {
+ if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size())
+ collectInterferingVRegs(MaxInterferingRegs);
+ return InterferingVRegs;
}
};
// Scan the vector of interfering virtual registers in this union. Assume it's
// quite small.
bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
- return is_contained(*InterferingVRegs, VirtReg);
+ return is_contained(InterferingVRegs, VirtReg);
}
// Collect virtual registers in this union that interfere with this
// 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused.
// 3. Iterators left at the last seen intersection.
//
-unsigned LiveIntervalUnion::Query::
-collectInterferingVRegs(unsigned MaxInterferingRegs) {
- if (!InterferingVRegs)
- InterferingVRegs.emplace();
-
+unsigned
+LiveIntervalUnion::Query::collectInterferingVRegs(unsigned MaxInterferingRegs) {
// Fast path return if we already have the desired information.
- if (SeenAllInterferences || InterferingVRegs->size() >= MaxInterferingRegs)
- return InterferingVRegs->size();
+ if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
+ return InterferingVRegs.size();
// Set up iterators on the first call.
if (!CheckedFirstInterference) {
LiveInterval *VReg = LiveUnionI.value();
if (VReg != RecentReg && !isSeenInterference(VReg)) {
RecentReg = VReg;
- InterferingVRegs->push_back(VReg);
- if (InterferingVRegs->size() >= MaxInterferingRegs)
- return InterferingVRegs->size();
+ InterferingVRegs.push_back(VReg);
+ if (InterferingVRegs.size() >= MaxInterferingRegs)
+ return InterferingVRegs.size();
}
// This LiveUnion segment is no longer interesting.
if (!(++LiveUnionI).valid()) {
SeenAllInterferences = true;
- return InterferingVRegs->size();
+ return InterferingVRegs.size();
}
}
LiveUnionI.advanceTo(LRI->start);
}
SeenAllInterferences = true;
- return InterferingVRegs->size();
+ return InterferingVRegs.size();
}
void LiveIntervalUnion::Array::init(LiveIntervalUnion::Allocator &Alloc,
// Collect interferences assigned to any alias of the physical register.
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
- Q.collectInterferingVRegs();
- for (unsigned i = Q.interferingVRegs().size(); i; --i) {
- LiveInterval *Intf = Q.interferingVRegs()[i - 1];
+ for (auto *Intf : reverse(Q.interferingVRegs())) {
if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())
return false;
Intfs.push_back(Intf);
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
// If there is 10 or more interferences, chances are one is heavier.
- if (Q.collectInterferingVRegs(10) >= 10)
+ const auto &Interferences = Q.interferingVRegs(10);
+ if (Interferences.size() >= 10)
return false;
// Check if any interfering live range is heavier than MaxWeight.
- for (LiveInterval *Intf : reverse(Q.interferingVRegs())) {
+ for (LiveInterval *Intf : reverse(Interferences)) {
assert(Register::isVirtualRegister(Intf->reg()) &&
"Only expecting virtual register interference from query");
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
- Q.collectInterferingVRegs();
// Check if any interfering live range is heavier than MaxWeight.
for (const LiveInterval *Intf : reverse(Q.interferingVRegs())) {
// should be fast, we may need to recalculate if when different physregs
// overlap the same register unit so we had different SubRanges queried
// against it.
- Q.collectInterferingVRegs();
ArrayRef<LiveInterval*> IVR = Q.interferingVRegs();
Intfs.append(IVR.begin(), IVR.end());
}
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
// If there is LastChanceRecoloringMaxInterference or more interferences,
// chances are one would not be recolorable.
- if (Q.collectInterferingVRegs(LastChanceRecoloringMaxInterference) >=
- LastChanceRecoloringMaxInterference && !ExhaustiveSearch) {
+ if (Q.interferingVRegs(LastChanceRecoloringMaxInterference).size() >=
+ LastChanceRecoloringMaxInterference &&
+ !ExhaustiveSearch) {
LLVM_DEBUG(dbgs() << "Early abort: too many interferences.\n");
CutOffInfo |= CO_Interf;
return false;