예제 #1
0
파일: LiveInterval.cpp 프로젝트: CPFL/guc
/// 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);
}
예제 #2
0
/// 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));
}
예제 #3
0
/// 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);
}
예제 #4
0
/// 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));
}
예제 #5
0
파일: LiveInterval.cpp 프로젝트: CPFL/guc
/// 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));
}
예제 #6
0
/** 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
		}
	}
}
예제 #7
0
/** 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
		}
	}
}