// Remove a live virtual register's segments from this union. void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) { if (Range.empty()) return; ++Tag; // Remove each of the virtual register's live segments from the map. LiveRange::const_iterator RegPos = Range.begin(); LiveRange::const_iterator RegEnd = Range.end(); SegmentIter SegPos = Segments.find(RegPos->start); while (true) { assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval"); SegPos.erase(); if (!SegPos.valid()) return; // Skip all segments that may have been coalesced. RegPos = Range.advanceTo(RegPos, SegPos.start()); if (RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } }
void InterferenceCache::Entry::update(unsigned MBBNum) { SlotIndex Start, Stop; tie(Start, Stop) = Indexes->getMBBRange(MBBNum); // Use advanceTo only when possible. if (PrevPos != Start) { if (!PrevPos.isValid() || Start < PrevPos) { for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { RegUnitInfo &RUI = RegUnits[i]; RUI.VirtI.find(Start); RUI.FixedI = RUI.Fixed->find(Start); } } else { for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { RegUnitInfo &RUI = RegUnits[i]; RUI.VirtI.advanceTo(Start); if (RUI.FixedI != RUI.Fixed->end()) RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start); } } PrevPos = Start; } MachineFunction::const_iterator MFI = MF->getBlockNumbered(MBBNum); BlockInterference *BI = &Blocks[MBBNum]; ArrayRef<SlotIndex> RegMaskSlots; ArrayRef<const uint32_t*> RegMaskBits; for (;;) { BI->Tag = Tag; BI->First = BI->Last = SlotIndex(); // Check for first interference from virtregs. for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI; if (!I.valid()) continue; SlotIndex StartI = I.start(); if (StartI >= Stop) continue; if (!BI->First.isValid() || StartI < BI->First) BI->First = StartI; } // Same thing for fixed interference. for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { LiveInterval::const_iterator I = RegUnits[i].FixedI; LiveInterval::const_iterator E = RegUnits[i].Fixed->end(); if (I == E) continue; SlotIndex StartI = I->start; if (StartI >= Stop) continue; if (!BI->First.isValid() || StartI < BI->First) BI->First = StartI; } // Also check for register mask interference. RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum); RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum); SlotIndex Limit = BI->First.isValid() ? BI->First : Stop; for (unsigned i = 0, e = RegMaskSlots.size(); i != e && RegMaskSlots[i] < Limit; ++i) if (MachineOperand::clobbersPhysReg(RegMaskBits[i], PhysReg)) { // Register mask i clobbers PhysReg before the LIU interference. BI->First = RegMaskSlots[i]; break; } PrevPos = Stop; if (BI->First.isValid()) break; // No interference in this block? Go ahead and precompute the next block. if (++MFI == MF->end()) return; MBBNum = MFI->getNumber(); BI = &Blocks[MBBNum]; if (BI->Tag == Tag) return; tie(Start, Stop) = Indexes->getMBBRange(MBBNum); } // Check for last interference in block. for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI; if (!I.valid() || I.start() >= Stop) continue; I.advanceTo(Stop); bool Backup = !I.valid() || I.start() >= Stop; if (Backup) --I; SlotIndex StopI = I.stop(); if (!BI->Last.isValid() || StopI > BI->Last) BI->Last = StopI; if (Backup) ++I; } // Fixed interference. for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { LiveInterval::iterator &I = RegUnits[i].FixedI; LiveRange *LR = RegUnits[i].Fixed; if (I == LR->end() || I->start >= Stop) continue; I = LR->advanceTo(I, Stop); bool Backup = I == LR->end() || I->start >= Stop; if (Backup) --I; SlotIndex StopI = I->end; if (!BI->Last.isValid() || StopI > BI->Last) BI->Last = StopI; if (Backup) ++I; } // Also check for register mask interference. SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start; for (unsigned i = RegMaskSlots.size(); i && RegMaskSlots[i-1].getDeadSlot() > Limit; --i) if (MachineOperand::clobbersPhysReg(RegMaskBits[i-1], PhysReg)) { // Register mask i-1 clobbers PhysReg after the LIU interference. // Model the regmask clobber as a dead def. BI->Last = RegMaskSlots[i-1].getDeadSlot(); break; } }