// Merge a LiveInterval's segments. Guarantee no overlaps. void LiveIntervalUnion::unify(LiveInterval &VirtReg) { if (VirtReg.empty()) return; ++Tag; // Insert each of the virtual register's live segments into the map. LiveInterval::iterator RegPos = VirtReg.begin(); LiveInterval::iterator RegEnd = VirtReg.end(); SegmentIter SegPos = Segments.find(RegPos->start); while (SegPos.valid()) { SegPos.insert(RegPos->start, RegPos->end, &VirtReg); if (++RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } // We have reached the end of Segments, so it is no longer necessary to search // for the insertion position. // It is faster to insert the end first. --RegEnd; SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg); for (; RegPos != RegEnd; ++RegPos, ++SegPos) SegPos.insert(RegPos->start, RegPos->end, &VirtReg); }
// Remove a live virtual register's segments from this union. void LiveIntervalUnion::extract(LiveInterval &VirtReg) { if (VirtReg.empty()) return; // Remove each of the virtual register's live segments from the map. LiveInterval::iterator RegPos = VirtReg.begin(); LiveInterval::iterator RegEnd = VirtReg.end(); SegmentIter SegPos = Segments.find(RegPos->start); for (;;) { assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval"); SegPos.erase(); if (!SegPos.valid()) return; // Skip all segments that may have been coalesced. RegPos = VirtReg.advanceTo(RegPos, SegPos.start()); if (RegPos == RegEnd) return; SegPos.advanceTo(RegPos->start); } }
// 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); } }
// Verify the live intervals in this union and add them to the visited set. void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) { for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI) VisitedVRegs.set(SI.value()->reg); }