forked from OSchip/llvm-project
Link to the live DomainValue after merging.
When merging two uncollapsed DomainValues, place a link to the active DomainValue from the passive DomainValue. This allows old stale references to the passive DomainValue to be updated to point to the active DomainValue. The new resolve() function finds the active DomainValue and updates the pointer. This change makes old live-out lists more useful since they may contain uncollapsed DomainValues that have since been merged into other DomainValues. llvm-svn: 144149
This commit is contained in:
parent
d5930ca99d
commit
53ec977cd2
|
@ -60,6 +60,11 @@ struct DomainValue {
|
||||||
// Position of the last defining instruction.
|
// Position of the last defining instruction.
|
||||||
unsigned Dist;
|
unsigned Dist;
|
||||||
|
|
||||||
|
// Pointer to the next DomainValue in a chain. When two DomainValues are
|
||||||
|
// merged, Victim.Next is set to point to Victor, so old DomainValue
|
||||||
|
// references can be updated by folowing the chain.
|
||||||
|
DomainValue *Next;
|
||||||
|
|
||||||
// Twiddleable instructions using or defining these registers.
|
// Twiddleable instructions using or defining these registers.
|
||||||
SmallVector<MachineInstr*, 8> Instrs;
|
SmallVector<MachineInstr*, 8> Instrs;
|
||||||
|
|
||||||
|
@ -94,8 +99,10 @@ struct DomainValue {
|
||||||
|
|
||||||
DomainValue() : Refs(0) { clear(); }
|
DomainValue() : Refs(0) { clear(); }
|
||||||
|
|
||||||
|
// Clear this DomainValue and point to next which has all its data.
|
||||||
void clear() {
|
void clear() {
|
||||||
AvailableDomains = Dist = 0;
|
AvailableDomains = Dist = 0;
|
||||||
|
Next = 0;
|
||||||
Instrs.clear();
|
Instrs.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -139,7 +146,12 @@ private:
|
||||||
|
|
||||||
// DomainValue allocation.
|
// DomainValue allocation.
|
||||||
DomainValue *alloc(int domain = -1);
|
DomainValue *alloc(int domain = -1);
|
||||||
|
DomainValue *retain(DomainValue *DV) {
|
||||||
|
if (DV) ++DV->Refs;
|
||||||
|
return DV;
|
||||||
|
}
|
||||||
void release(DomainValue*);
|
void release(DomainValue*);
|
||||||
|
DomainValue *resolve(DomainValue*&);
|
||||||
|
|
||||||
// LiveRegs manipulations.
|
// LiveRegs manipulations.
|
||||||
void setLiveReg(int rx, DomainValue *DV);
|
void setLiveReg(int rx, DomainValue *DV);
|
||||||
|
@ -174,22 +186,46 @@ DomainValue *ExeDepsFix::alloc(int domain) {
|
||||||
if (domain >= 0)
|
if (domain >= 0)
|
||||||
dv->addDomain(domain);
|
dv->addDomain(domain);
|
||||||
assert(dv->Refs == 0 && "Reference count wasn't cleared");
|
assert(dv->Refs == 0 && "Reference count wasn't cleared");
|
||||||
|
assert(!dv->Next && "Chained DomainValue shouldn't have been recycled");
|
||||||
return dv;
|
return dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// release - Release a reference to DV. When the last reference is released,
|
/// release - Release a reference to DV. When the last reference is released,
|
||||||
/// collapse if needed.
|
/// collapse if needed.
|
||||||
void ExeDepsFix::release(DomainValue *DV) {
|
void ExeDepsFix::release(DomainValue *DV) {
|
||||||
assert(DV && DV->Refs && "Bad DomainValue");
|
while (DV) {
|
||||||
if (--DV->Refs)
|
assert(DV->Refs && "Bad DomainValue");
|
||||||
return;
|
if (--DV->Refs)
|
||||||
|
return;
|
||||||
|
|
||||||
// There are no more DV references. Collapse any contained instructions.
|
// There are no more DV references. Collapse any contained instructions.
|
||||||
if (DV->AvailableDomains && !DV->isCollapsed())
|
if (DV->AvailableDomains && !DV->isCollapsed())
|
||||||
collapse(DV, DV->getFirstDomain());
|
collapse(DV, DV->getFirstDomain());
|
||||||
|
|
||||||
DV->clear();
|
DomainValue *Next = DV->Next;
|
||||||
Avail.push_back(DV);
|
DV->clear();
|
||||||
|
Avail.push_back(DV);
|
||||||
|
// Also release the next DomainValue in the chain.
|
||||||
|
DV = Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// resolve - Follow the chain of dead DomainValues until a live DomainValue is
|
||||||
|
/// reached. Update the referenced pointer when necessary.
|
||||||
|
DomainValue *ExeDepsFix::resolve(DomainValue *&DVRef) {
|
||||||
|
DomainValue *DV = DVRef;
|
||||||
|
if (!DV || !DV->Next)
|
||||||
|
return DV;
|
||||||
|
|
||||||
|
// DV has a chain. Find the end.
|
||||||
|
do DV = DV->Next;
|
||||||
|
while (DV->Next);
|
||||||
|
|
||||||
|
// Update DVRef to point to DV.
|
||||||
|
retain(DV);
|
||||||
|
release(DVRef);
|
||||||
|
DVRef = DV;
|
||||||
|
return DV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set LiveRegs[rx] = dv, updating reference counts.
|
/// Set LiveRegs[rx] = dv, updating reference counts.
|
||||||
|
@ -204,8 +240,7 @@ void ExeDepsFix::setLiveReg(int rx, DomainValue *dv) {
|
||||||
return;
|
return;
|
||||||
if (LiveRegs[rx])
|
if (LiveRegs[rx])
|
||||||
release(LiveRegs[rx]);
|
release(LiveRegs[rx]);
|
||||||
LiveRegs[rx] = dv;
|
LiveRegs[rx] = retain(dv);
|
||||||
if (dv) ++dv->Refs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill register rx, recycle or collapse any DomainValue.
|
// Kill register rx, recycle or collapse any DomainValue.
|
||||||
|
@ -273,6 +308,8 @@ bool ExeDepsFix::merge(DomainValue *A, DomainValue *B) {
|
||||||
|
|
||||||
// Clear the old DomainValue so we won't try to swizzle instructions twice.
|
// Clear the old DomainValue so we won't try to swizzle instructions twice.
|
||||||
B->clear();
|
B->clear();
|
||||||
|
// All uses of B are referred to A.
|
||||||
|
B->Next = retain(A);
|
||||||
|
|
||||||
for (unsigned rx = 0; rx != NumRegs; ++rx)
|
for (unsigned rx = 0; rx != NumRegs; ++rx)
|
||||||
if (LiveRegs[rx] == B)
|
if (LiveRegs[rx] == B)
|
||||||
|
@ -290,8 +327,8 @@ void ExeDepsFix::enterBasicBlock(MachineBasicBlock *MBB) {
|
||||||
pe = MBB->pred_end(); pi != pe; ++pi) {
|
pe = MBB->pred_end(); pi != pe; ++pi) {
|
||||||
LiveOutMap::const_iterator fi = LiveOuts.find(*pi);
|
LiveOutMap::const_iterator fi = LiveOuts.find(*pi);
|
||||||
if (fi == LiveOuts.end()) continue;
|
if (fi == LiveOuts.end()) continue;
|
||||||
DomainValue *pdv = fi->second[rx];
|
DomainValue *pdv = resolve(fi->second[rx]);
|
||||||
if (!pdv || !pdv->AvailableDomains) continue;
|
if (!pdv) continue;
|
||||||
if (!LiveRegs || !LiveRegs[rx]) {
|
if (!LiveRegs || !LiveRegs[rx]) {
|
||||||
setLiveReg(rx, pdv);
|
setLiveReg(rx, pdv);
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue