/// removeRange - Remove the specified range from this interval. Note that /// the range must be in a single LiveRange in its entirety. void LiveInterval::removeRange(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo) { // Find the LiveRange containing this span. Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); assert(I != ranges.begin() && "Range is not in interval!"); --I; assert(I->containsRange(Start, End) && "Range is not entirely in interval!"); // If the span we are removing is at the start of the LiveRange, adjust it. VNInfo *ValNo = I->valno; if (I->start == Start) { if (I->end == End) { ValNo->removeKills(Start, End); if (RemoveDeadValNo) { // Check if val# is dead. bool isDead = true; for (const_iterator II = begin(), EE = end(); II != EE; ++II) if (II != I && II->valno == ValNo) { isDead = false; break; } if (isDead) { // Now that ValNo is dead, remove it. If it is the largest value // number, just nuke it (and any other deleted values neighboring it), // otherwise mark it as ~1U so it can be nuked later. if (ValNo->id == getNumValNums()-1) { do { valnos.pop_back(); } while (!valnos.empty() && valnos.back()->isUnused()); } else { ValNo->setIsUnused(true); } } } ranges.erase(I); // Removed the whole LiveRange. } else I->start = End; return; } // Otherwise if the span we are removing is at the end of the LiveRange, // adjust the other way. if (I->end == End) { ValNo->removeKills(Start, End); I->end = Start; return; } // Otherwise, we are splitting the LiveRange into two pieces. SlotIndex OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. ranges.insert(next(I), LiveRange(End, OldEnd, ValNo)); }
/// extendIntervalEndTo - This method is used when we want to extend the range /// specified by I to end at the specified endpoint. To do this, we should /// merge and eliminate all ranges that this will overlap with. The iterator is /// not invalidated. void LiveInterval::extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd) { assert(I != ranges.end() && "Not a valid interval!"); VNInfo *ValNo = I->valno; SlotIndex OldEnd = I->end; // Search for the first interval that we can't merge with. Ranges::iterator MergeTo = next(I); for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) { assert(MergeTo->valno == ValNo && "Cannot merge with differing values!"); } // If NewEnd was in the middle of an interval, make sure to get its endpoint. I->end = std::max(NewEnd, prior(MergeTo)->end); // Erase any dead ranges. ranges.erase(next(I), MergeTo); // Update kill info. ValNo->removeKills(OldEnd, I->end.getPrevSlot()); // If the newly formed range now touches the range after it and if they have // the same value number, merge the two ranges into one range. Ranges::iterator Next = next(I); if (Next != ranges.end() && Next->start <= I->end && Next->valno == ValNo) { I->end = Next->end; ranges.erase(Next); } }