/// isInOneLiveRange - Return true if the range specified is entirely in /// a single LiveRange of the live interval. bool LiveInterval::isInOneLiveRange(SlotIndex Start, SlotIndex End) { Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); if (I == ranges.begin()) return false; --I; return I->containsRange(Start, End); }
/// removeRange - Remove the specified range from this interval. Note that /// the range must already be in this interval in its entirety. void LiveInterval::removeRange(unsigned Start, unsigned End) { // 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->contains(Start) && I->contains(End-1) && "Range is not entirely in interval!"); // If the span we are removing is at the start of the LiveRange, adjust it. if (I->start == Start) { if (I->end == End) 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) { I->end = Start; return; } // Otherwise, we are splitting the LiveRange into two pieces. unsigned OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId)); }
/// isInOneLiveRange - Return true if the range specified is entirely in the /// a single LiveRange of the live interval. bool LiveInterval::isInOneLiveRange(unsigned Start, unsigned End) { Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); if (I == ranges.begin()) return false; --I; return I->contains(Start) && I->contains(End-1); }
/// removeRange - Remove the specified range from this interval. Note that /// the range must be in a single LiveRange in its entirety. void LiveInterval::removeRange(unsigned Start, unsigned 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->contains(Start) && I->contains(End-1) && "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) { removeKills(I->valno, 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 { VNInfo *VNI = valnos.back(); valnos.pop_back(); VNI->~VNInfo(); } while (!valnos.empty() && valnos.back()->def == ~1U); } else { ValNo->def = ~1U; } } } 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) { removeKills(ValNo, Start, End); I->end = Start; return; } // Otherwise, we are splitting the LiveRange into two pieces. unsigned OldEnd = I->end; I->end = Start; // Trim the old interval. // Insert the new one. ranges.insert(next(I), LiveRange(End, OldEnd, ValNo)); }
/// 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) { 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. markValNoForDeletion(ValNo); } } 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) { 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(llvm::next(I), LiveRange(End, OldEnd, ValNo)); }
/** Adds a new number range. The range describes a mapping from c to v(c), where * \f$c \in [cmin,cmax]\f$ and \f$v(cmin):=vmin, v(c):=vmin+c-cmin\f$. * @param[in] cmin smallest number in the range * @param[in] cmax largest number in the range * @param[in] vmin map value of cmin */ void RangeMap::addRange (UInt32 cmin, UInt32 cmax, UInt32 vmin) { if (cmin > cmax) swap(cmin, cmax); Range range(cmin, cmax, vmin); if (_ranges.empty()) _ranges.push_back(range); else { // check for simple cases that can be handled pretty fast Range &lrange = *_ranges.begin(); Range &rrange = *_ranges.rbegin(); if (cmin > rrange.max()) { // non-overlapping range at end of vector? if (!rrange.join(range)) _ranges.push_back(range); } else if (cmax < lrange.min()) { // non-overlapping range at begin of vector? if (!lrange.join(range)) _ranges.insert(_ranges.begin(), range); } else { // ranges overlap and/or must be inserted somewhere inside the vector Ranges::iterator it = lower_bound(_ranges.begin(), _ranges.end(), range); const bool at_end = (it == _ranges.end()); if (at_end) --it; if (!it->join(range) && (it == _ranges.begin() || !(it-1)->join(range))) { if (it->min() < cmin && it->max() > cmax) { // new range completely inside an existing range? //split existing range UInt32 itmax = it->max(); it->max(cmin-1); it = _ranges.insert(it+1, Range(cmax+1, itmax, it->valueAt(cmax+1))); } else if (at_end) // does new range overlap right side of last range in vector? it = _ranges.end(); // => append new range at end of vector it = _ranges.insert(it, range); } adaptNeighbors(it); // resolve overlaps } } }
/** Adapts the left and right neighbor elements of a newly inserted range. * The new range could overlap ranges in the neighborhood so that those must be * adapted or removed. All ranges in the range vector are ordered ascendingly, i.e. * [min_1, max_1],...,[min_n, max_n] where min_i < min_j for all i < j. * @param[in] it pointer to the newly inserted range */ void RangeMap::adaptNeighbors (Ranges::iterator it) { if (it != _ranges.end()) { // adapt left neighbor Ranges::iterator lit = it-1; // points to left neighbor if (it != _ranges.begin() && it->min() <= lit->max()) { bool left_neighbor_valid = (it->min() > 0 && it->min()-1 >= lit->min()); if (left_neighbor_valid) // is adapted left neighbor valid? lit->max(it->min()-1); // => assign new max value if (!left_neighbor_valid || it->join(*lit)) it = _ranges.erase(lit); } // remove right neighbors completely overlapped by *it Ranges::iterator rit = it+1; // points to right neighbor while (rit != _ranges.end() && it->max() >= rit->max()) { // complete overlap? _ranges.erase(rit); rit = it+1; } // adapt rightmost range partially overlapped by *it if (rit != _ranges.end()) { if (it->max() >= rit->min()) rit->setMinAndAdaptValue(it->max()+1); // try to merge right neighbor into *this if (it->join(*rit)) _ranges.erase(rit); // remove merged neighbor } } }