return r->end == I;
}
+/// killedAt - Return true if a live range ends at index. Note that the kill
+/// point is not contained in the half-open live range. It is usually the
+/// getDefIndex() slot following its last use.
+bool LiveInterval::killedAt(SlotIndex I) const {
+ Ranges::const_iterator r = std::lower_bound(ranges.begin(), ranges.end(), I);
+
+ // Now r points to the first interval with start >= I, or ranges.end().
+ if (r == ranges.begin())
+ return false;
+
+ --r;
+ // Now r points to the last interval with end <= I.
+ // r->end is the kill point.
+ return r->end == I;
+}
+
+/// killedInRange - Return true if the interval has kills in [Start,End).
+bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const {
+ Ranges::const_iterator r =
+ std::lower_bound(ranges.begin(), ranges.end(), End);
+
+ // Now r points to the first interval with start >= End, or ranges.end().
+ if (r == ranges.begin())
+ return false;
+
+ --r;
+ // Now r points to the last interval with end <= End.
+ // r->end is the kill point.
+ return r->end >= Start && r->end < End;
+}
+
// overlaps - Return true if the intersection of the two live intervals is
// not empty.
//
//
bool LiveInterval::overlapsFrom(const LiveInterval& other,
const_iterator StartPos) const {
+ assert(!empty() && "empty interval");
const_iterator i = begin();
const_iterator ie = end();
const_iterator j = StartPos;
/// by [Start, End).
bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const {
assert(Start < End && "Invalid range");
- const_iterator I = begin();
- const_iterator E = end();
- const_iterator si = std::upper_bound(I, E, Start);
- const_iterator ei = std::upper_bound(I, E, End);
- if (si != ei)
- return true;
- if (si == I)
- return false;
- --si;
- return si->contains(Start);
+ const_iterator I = std::lower_bound(begin(), end(), End);
+ return I != begin() && (--I)->end > Start;
+}
+
+
+/// 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.
+void LiveInterval::markValNoForDeletion(VNInfo *ValNo) {
+ if (ValNo->id == getNumValNums()-1) {
+ do {
+ valnos.pop_back();
+ } while (!valnos.empty() && valnos.back()->isUnused());
+ } else {
+ ValNo->setIsUnused(true);
+ }
+}
+
+/// RenumberValues - Renumber all values in order of appearance and delete the
+/// remaining unused values.
+void LiveInterval::RenumberValues() {
+ SmallPtrSet<VNInfo*, 8> Seen;
+ valnos.clear();
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ VNInfo *VNI = I->valno;
+ if (!Seen.insert(VNI))
+ continue;
+ assert(!VNI->isUnused() && "Unused valno used by live range");
+ VNI->id = (unsigned)valnos.size();
+ valnos.push_back(VNI);
+ }
}
/// extendIntervalEndTo - This method is used when we want to extend the range
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);
+ Ranges::iterator MergeTo = llvm::next(I);
for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) {
assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
}
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());
+ ranges.erase(llvm::next(I), MergeTo);
// 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);
+ Ranges::iterator Next = llvm::next(I);
if (Next != ranges.end() && Next->start <= I->end && Next->valno == ValNo) {
I->end = Next->end;
ranges.erase(Next);
MergeTo->end = I->end;
}
- ranges.erase(next(MergeTo), next(I));
+ ranges.erase(llvm::next(MergeTo), llvm::next(I));
return MergeTo;
}
// endpoint as well.
if (End > it->end)
extendIntervalEndTo(it, End);
- else if (End < it->end)
- // Overlapping intervals, there might have been a kill here.
- it->valno->removeKill(End);
return it;
}
} else {
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;
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);
}
+ if (isDead) {
+ // Now that ValNo is dead, remove it.
+ markValNoForDeletion(ValNo);
}
}
// 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;
}
I->end = Start; // Trim the old interval.
// Insert the new one.
- ranges.insert(next(I), LiveRange(End, OldEnd, ValNo));
+ ranges.insert(llvm::next(I), LiveRange(End, OldEnd, ValNo));
}
/// removeValNo - Remove all the ranges defined by the specified value#.
if (I->valno == ValNo)
ranges.erase(I);
} while (I != E);
- // 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);
- }
+ // Now that ValNo is dead, remove it.
+ markValNoForDeletion(ValNo);
}
/// getLiveRangeContaining - Return the live range that contains the
I->valno = NewVNInfo[OtherAssignments[RangeNo]];
assert(I->valno && "Adding a dead range?");
InsertPos = addRangeFrom(*I, InsertPos);
- InsertPos->valno->removeKills(InsertPos->start,
- InsertPos->end.getPrevSlot());
}
ComputeJoinedWeight(Other);
break;
}
if (isDead) {
- // Now that V1 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 (V1->id == getNumValNums()-1) {
- do {
- valnos.pop_back();
- } while (!valnos.empty() && valnos.back()->isUnused());
- } else {
- V1->setIsUnused(true);
- }
+ // Now that V1 is dead, remove it.
+ markValNoForDeletion(V1);
}
}
}
}
}
- // Now that V1 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 (V1->id == getNumValNums()-1) {
- do {
- valnos.pop_back();
- } while (valnos.back()->isUnused());
- } else {
- V1->setIsUnused(true);
- }
+ // Now that V1 is dead, remove it.
+ markValNoForDeletion(V1);
return V2;
}
assert(I->valno == getValNumInfo(I->valno->id) && "Bad VNInfo");
}
}
-
+
// Print value number info.
if (getNumValNums()) {
OS << " ";
OS << "?";
else
OS << vni->def;
- unsigned ee = vni->kills.size();
- if (ee || vni->hasPHIKill()) {
- OS << "-(";
- for (unsigned j = 0; j != ee; ++j) {
- OS << vni->kills[j];
- if (j != ee-1)
- OS << " ";
- }
- if (vni->hasPHIKill()) {
- if (ee)
- OS << " ";
- OS << "phi";
- }
- OS << ")";
- }
+ if (vni->hasPHIKill())
+ OS << "-phikill";
+ if (vni->hasRedefByEC())
+ OS << "-ec";
}
}
}