/// multiple LiveIntervals.
void ConnectedVNInfoEqClasses::Connect(unsigned a, unsigned b) {
- unsigned eqa = eqClass_[a];
- unsigned eqb = eqClass_[b];
- if (eqa == eqb)
- return;
- // Make sure a and b are in the same class while maintaining eqClass_[i] <= i.
- if (eqa > eqb)
- eqClass_[a] = eqb;
- else
- eqClass_[b] = eqa;
+ while (eqClass_[a] != eqClass_[b]) {
+ if (eqClass_[a] > eqClass_[b])
+ std::swap(a, b);
+ unsigned t = eqClass_[b];
+ assert(t <= b && "Invariant broken");
+ eqClass_[b] = eqClass_[a];
+ b = t;
+ }
}
unsigned ConnectedVNInfoEqClasses::Renumber() {
for (unsigned i = 0, e = LI->getNumValNums(); i != e; ++i)
eqClass_.push_back(i);
+ const VNInfo *used = 0, *unused = 0;
+
// Determine connections.
for (LiveInterval::const_vni_iterator I = LI->vni_begin(), E = LI->vni_end();
I != E; ++I) {
const VNInfo *VNI = *I;
- if (VNI->id == eqClass_.size())
- eqClass_.push_back(VNI->id);
- assert(!VNI->isUnused() && "Cannot handle unused values");
+ // Group all unused values into one class.
+ if (VNI->isUnused()) {
+ if (unused)
+ Connect(unused->id, VNI->id);
+ unused = VNI;
+ continue;
+ }
+ used = VNI;
if (VNI->isPHIDef()) {
const MachineBasicBlock *MBB = lis_.getMBBFromIndex(VNI->def);
assert(MBB && "Phi-def has no defining MBB");
Connect(VNI->id, UVNI->id);
}
}
+
+ // Lump all the unused values in with the last used value.
+ if (used && unused)
+ Connect(used->id, unused->id);
+
return Renumber();
}
++J;
for (LiveInterval::iterator I = J; I != E; ++I) {
if (unsigned eq = eqClass_[I->valno->id]) {
- assert(LIV[eq]->empty() || LIV[eq]->expiredAt(I->start) &&
+ assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) &&
"New intervals should be empty");
LIV[eq]->ranges.push_back(*I);
} else