mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-28 19:25:00 +00:00
Represent RegUnit liveness with LiveRange instance
Previously LiveInterval has been used, but having a spill weight and register number is unnecessary for a register unit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -95,9 +95,9 @@ void LiveIntervals::releaseMemory() {
|
||||
RegMaskBits.clear();
|
||||
RegMaskBlocks.clear();
|
||||
|
||||
for (unsigned i = 0, e = RegUnitIntervals.size(); i != e; ++i)
|
||||
delete RegUnitIntervals[i];
|
||||
RegUnitIntervals.clear();
|
||||
for (unsigned i = 0, e = RegUnitRanges.size(); i != e; ++i)
|
||||
delete RegUnitRanges[i];
|
||||
RegUnitRanges.clear();
|
||||
|
||||
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
|
||||
VNInfoAllocator.Reset();
|
||||
@@ -139,9 +139,9 @@ void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
|
||||
OS << "********** INTERVALS **********\n";
|
||||
|
||||
// Dump the regunits.
|
||||
for (unsigned i = 0, e = RegUnitIntervals.size(); i != e; ++i)
|
||||
if (LiveInterval *LI = RegUnitIntervals[i])
|
||||
OS << PrintRegUnit(i, TRI) << " = " << *LI << '\n';
|
||||
for (unsigned i = 0, e = RegUnitRanges.size(); i != e; ++i)
|
||||
if (LiveRange *LR = RegUnitRanges[i])
|
||||
OS << PrintRegUnit(i, TRI) << " = " << *LR << '\n';
|
||||
|
||||
// Dump the virtregs.
|
||||
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
||||
@@ -227,12 +227,10 @@ void LiveIntervals::computeRegMasks() {
|
||||
// interference.
|
||||
//
|
||||
|
||||
/// computeRegUnitInterval - Compute the live interval of a register unit, based
|
||||
/// on the uses and defs of aliasing registers. The interval should be empty,
|
||||
/// computeRegUnitInterval - Compute the live range of a register unit, based
|
||||
/// on the uses and defs of aliasing registers. The range should be empty,
|
||||
/// or contain only dead phi-defs from ABI blocks.
|
||||
void LiveIntervals::computeRegUnitInterval(LiveInterval &LI) {
|
||||
unsigned Unit = LI.reg;
|
||||
|
||||
void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) {
|
||||
assert(LRCalc && "LRCalc not initialized.");
|
||||
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
|
||||
|
||||
@@ -245,18 +243,18 @@ void LiveIntervals::computeRegUnitInterval(LiveInterval &LI) {
|
||||
for (MCSuperRegIterator Supers(*Roots, TRI, /*IncludeSelf=*/true);
|
||||
Supers.isValid(); ++Supers) {
|
||||
if (!MRI->reg_empty(*Supers))
|
||||
LRCalc->createDeadDefs(LI, *Supers);
|
||||
LRCalc->createDeadDefs(LR, *Supers);
|
||||
}
|
||||
}
|
||||
|
||||
// Now extend LI to reach all uses.
|
||||
// Now extend LR to reach all uses.
|
||||
// Ignore uses of reserved registers. We only track defs of those.
|
||||
for (MCRegUnitRootIterator Roots(Unit, TRI); Roots.isValid(); ++Roots) {
|
||||
for (MCSuperRegIterator Supers(*Roots, TRI, /*IncludeSelf=*/true);
|
||||
Supers.isValid(); ++Supers) {
|
||||
unsigned Reg = *Supers;
|
||||
if (!MRI->isReserved(Reg) && !MRI->reg_empty(Reg))
|
||||
LRCalc->extendToUses(LI, Reg);
|
||||
LRCalc->extendToUses(LR, Reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,11 +265,11 @@ void LiveIntervals::computeRegUnitInterval(LiveInterval &LI) {
|
||||
/// without a corresponding def when entering the entry block or a landing pad.
|
||||
///
|
||||
void LiveIntervals::computeLiveInRegUnits() {
|
||||
RegUnitIntervals.resize(TRI->getNumRegUnits());
|
||||
RegUnitRanges.resize(TRI->getNumRegUnits());
|
||||
DEBUG(dbgs() << "Computing live-in reg-units in ABI blocks.\n");
|
||||
|
||||
// Keep track of the intervals allocated.
|
||||
SmallVector<LiveInterval*, 8> NewIntvs;
|
||||
// Keep track of the live range sets allocated.
|
||||
SmallVector<unsigned, 8> NewRanges;
|
||||
|
||||
// Check all basic blocks for live-ins.
|
||||
for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
|
||||
@@ -289,23 +287,25 @@ void LiveIntervals::computeLiveInRegUnits() {
|
||||
LIE = MBB->livein_end(); LII != LIE; ++LII) {
|
||||
for (MCRegUnitIterator Units(*LII, TRI); Units.isValid(); ++Units) {
|
||||
unsigned Unit = *Units;
|
||||
LiveInterval *Intv = RegUnitIntervals[Unit];
|
||||
if (!Intv) {
|
||||
Intv = RegUnitIntervals[Unit] = new LiveInterval(Unit, HUGE_VALF);
|
||||
NewIntvs.push_back(Intv);
|
||||
LiveRange *LR = RegUnitRanges[Unit];
|
||||
if (!LR) {
|
||||
LR = RegUnitRanges[Unit] = new LiveRange();
|
||||
NewRanges.push_back(Unit);
|
||||
}
|
||||
VNInfo *VNI = Intv->createDeadDef(Begin, getVNInfoAllocator());
|
||||
VNInfo *VNI = LR->createDeadDef(Begin, getVNInfoAllocator());
|
||||
(void)VNI;
|
||||
DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI) << '#' << VNI->id);
|
||||
}
|
||||
}
|
||||
DEBUG(dbgs() << '\n');
|
||||
}
|
||||
DEBUG(dbgs() << "Created " << NewIntvs.size() << " new intervals.\n");
|
||||
DEBUG(dbgs() << "Created " << NewRanges.size() << " new intervals.\n");
|
||||
|
||||
// Compute the 'normal' part of the intervals.
|
||||
for (unsigned i = 0, e = NewIntvs.size(); i != e; ++i)
|
||||
computeRegUnitInterval(*NewIntvs[i]);
|
||||
// Compute the 'normal' part of the ranges.
|
||||
for (unsigned i = 0, e = NewRanges.size(); i != e; ++i) {
|
||||
unsigned Unit = NewRanges[i];
|
||||
computeRegUnitRange(*RegUnitRanges[Unit], Unit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -514,7 +514,7 @@ void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
|
||||
|
||||
void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
// Keep track of regunit ranges.
|
||||
SmallVector<std::pair<LiveInterval*, LiveInterval::iterator>, 8> RU;
|
||||
SmallVector<std::pair<LiveRange*, LiveRange::iterator>, 8> RU;
|
||||
|
||||
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||
@@ -529,10 +529,10 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
RU.clear();
|
||||
for (MCRegUnitIterator Units(VRM->getPhys(Reg), TRI); Units.isValid();
|
||||
++Units) {
|
||||
LiveInterval *RUInt = &getRegUnit(*Units);
|
||||
if (RUInt->empty())
|
||||
LiveRange &RURanges = getRegUnit(*Units);
|
||||
if (RURanges.empty())
|
||||
continue;
|
||||
RU.push_back(std::make_pair(RUInt, RUInt->find(LI->begin()->end)));
|
||||
RU.push_back(std::make_pair(&RURanges, RURanges.find(LI->begin()->end)));
|
||||
}
|
||||
|
||||
// Every instruction that kills Reg corresponds to a segment range end
|
||||
@@ -556,12 +556,12 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
// There should be no kill flag on FOO when %vreg5 is rewritten as %EAX.
|
||||
bool CancelKill = false;
|
||||
for (unsigned u = 0, e = RU.size(); u != e; ++u) {
|
||||
LiveInterval *RInt = RU[u].first;
|
||||
LiveInterval::iterator &I = RU[u].second;
|
||||
if (I == RInt->end())
|
||||
LiveRange &RRanges = *RU[u].first;
|
||||
LiveRange::iterator &I = RU[u].second;
|
||||
if (I == RRanges.end())
|
||||
continue;
|
||||
I = RInt->advanceTo(I, RI->end);
|
||||
if (I == RInt->end() || I->start >= RI->end)
|
||||
I = RRanges.advanceTo(I, RI->end);
|
||||
if (I == RRanges.end() || I->start >= RI->end)
|
||||
continue;
|
||||
// I is overlapping RI.
|
||||
CancelKill = true;
|
||||
@@ -710,7 +710,7 @@ private:
|
||||
const TargetRegisterInfo& TRI;
|
||||
SlotIndex OldIdx;
|
||||
SlotIndex NewIdx;
|
||||
SmallPtrSet<LiveInterval*, 8> Updated;
|
||||
SmallPtrSet<LiveRange*, 8> Updated;
|
||||
bool UpdateFlags;
|
||||
|
||||
public:
|
||||
@@ -724,7 +724,7 @@ public:
|
||||
// physregs, even those that aren't needed for regalloc, in order to update
|
||||
// kill flags. This is wasteful. Eventually, LiveVariables will strip all kill
|
||||
// flags, and postRA passes will use a live register utility instead.
|
||||
LiveInterval *getRegUnitLI(unsigned Unit) {
|
||||
LiveRange *getRegUnitLI(unsigned Unit) {
|
||||
if (UpdateFlags)
|
||||
return &LIS.getRegUnit(Unit);
|
||||
return LIS.getCachedRegUnit(Unit);
|
||||
@@ -749,15 +749,16 @@ public:
|
||||
if (!Reg)
|
||||
continue;
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
updateRange(LIS.getInterval(Reg));
|
||||
LiveInterval &LI = LIS.getInterval(Reg);
|
||||
updateRange(LI, Reg);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For physregs, only update the regunits that actually have a
|
||||
// precomputed live range.
|
||||
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
|
||||
if (LiveInterval *LI = getRegUnitLI(*Units))
|
||||
updateRange(*LI);
|
||||
if (LiveRange *LR = getRegUnitLI(*Units))
|
||||
updateRange(*LR, *Units);
|
||||
}
|
||||
if (hasRegMask)
|
||||
updateRegMaskSlots();
|
||||
@@ -766,26 +767,26 @@ public:
|
||||
private:
|
||||
/// Update a single live range, assuming an instruction has been moved from
|
||||
/// OldIdx to NewIdx.
|
||||
void updateRange(LiveInterval &LI) {
|
||||
if (!Updated.insert(&LI))
|
||||
void updateRange(LiveRange &LR, unsigned Reg) {
|
||||
if (!Updated.insert(&LR))
|
||||
return;
|
||||
DEBUG({
|
||||
dbgs() << " ";
|
||||
if (TargetRegisterInfo::isVirtualRegister(LI.reg))
|
||||
dbgs() << PrintReg(LI.reg);
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
dbgs() << PrintReg(Reg);
|
||||
else
|
||||
dbgs() << PrintRegUnit(LI.reg, &TRI);
|
||||
dbgs() << ":\t" << LI << '\n';
|
||||
dbgs() << PrintRegUnit(Reg, &TRI);
|
||||
dbgs() << ":\t" << LR << '\n';
|
||||
});
|
||||
if (SlotIndex::isEarlierInstr(OldIdx, NewIdx))
|
||||
handleMoveDown(LI);
|
||||
handleMoveDown(LR);
|
||||
else
|
||||
handleMoveUp(LI);
|
||||
DEBUG(dbgs() << " -->\t" << LI << '\n');
|
||||
LI.verify();
|
||||
handleMoveUp(LR, Reg);
|
||||
DEBUG(dbgs() << " -->\t" << LR << '\n');
|
||||
LR.verify();
|
||||
}
|
||||
|
||||
/// Update LI to reflect an instruction has been moved downwards from OldIdx
|
||||
/// Update LR to reflect an instruction has been moved downwards from OldIdx
|
||||
/// to NewIdx.
|
||||
///
|
||||
/// 1. Live def at OldIdx:
|
||||
@@ -805,11 +806,11 @@ private:
|
||||
/// 5. Value read at OldIdx, killed before NewIdx:
|
||||
/// Extend kill to NewIdx.
|
||||
///
|
||||
void handleMoveDown(LiveInterval &LI) {
|
||||
void handleMoveDown(LiveRange &LR) {
|
||||
// First look for a kill at OldIdx.
|
||||
LiveInterval::iterator I = LI.find(OldIdx.getBaseIndex());
|
||||
LiveInterval::iterator E = LI.end();
|
||||
// Is LI even live at OldIdx?
|
||||
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
|
||||
LiveRange::iterator E = LR.end();
|
||||
// Is LR even live at OldIdx?
|
||||
if (I == E || SlotIndex::isEarlierInstr(OldIdx, I->start))
|
||||
return;
|
||||
|
||||
@@ -826,7 +827,7 @@ private:
|
||||
for (MIBundleOperands MO(KillMI); MO.isValid(); ++MO)
|
||||
if (MO->isReg() && MO->isUse())
|
||||
MO->setIsKill(false);
|
||||
// Adjust I->end to reach NewIdx. This may temporarily make LI invalid by
|
||||
// Adjust I->end to reach NewIdx. This may temporarily make LR invalid by
|
||||
// overlapping ranges. Case 5 above.
|
||||
I->end = NewIdx.getRegSlot(I->end.isEarlyClobber());
|
||||
// If this was a kill, there may also be a def. Otherwise we're done.
|
||||
@@ -855,16 +856,16 @@ private:
|
||||
assert((I->end == OldIdx.getDeadSlot() ||
|
||||
SlotIndex::isSameInstr(I->end, NewIdx)) &&
|
||||
"Cannot move def below kill");
|
||||
LiveInterval::iterator NewI = LI.advanceTo(I, NewIdx.getRegSlot());
|
||||
LiveRange::iterator NewI = LR.advanceTo(I, NewIdx.getRegSlot());
|
||||
if (NewI != E && SlotIndex::isSameInstr(NewI->start, NewIdx)) {
|
||||
// There is an existing def at NewIdx, case 4 above. The def at OldIdx is
|
||||
// coalesced into that value.
|
||||
assert(NewI->valno != DefVNI && "Multiple defs of value?");
|
||||
LI.removeValNo(DefVNI);
|
||||
LR.removeValNo(DefVNI);
|
||||
return;
|
||||
}
|
||||
// There was no existing def at NewIdx. Turn *I into a dead def at NewIdx.
|
||||
// If the def at OldIdx was dead, we allow it to be moved across other LI
|
||||
// If the def at OldIdx was dead, we allow it to be moved across other LR
|
||||
// values. The new range should be placed immediately before NewI, move any
|
||||
// intermediate ranges up.
|
||||
assert(NewI != I && "Inconsistent iterators");
|
||||
@@ -873,7 +874,7 @@ private:
|
||||
= LiveRange::Segment(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
|
||||
}
|
||||
|
||||
/// Update LI to reflect an instruction has been moved upwards from OldIdx
|
||||
/// Update LR to reflect an instruction has been moved upwards from OldIdx
|
||||
/// to NewIdx.
|
||||
///
|
||||
/// 1. Live def at OldIdx:
|
||||
@@ -893,11 +894,11 @@ private:
|
||||
/// Hoist kill to NewIdx, then scan for last kill between NewIdx and
|
||||
/// OldIdx.
|
||||
///
|
||||
void handleMoveUp(LiveInterval &LI) {
|
||||
void handleMoveUp(LiveRange &LR, unsigned Reg) {
|
||||
// First look for a kill at OldIdx.
|
||||
LiveInterval::iterator I = LI.find(OldIdx.getBaseIndex());
|
||||
LiveInterval::iterator E = LI.end();
|
||||
// Is LI even live at OldIdx?
|
||||
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
|
||||
LiveRange::iterator E = LR.end();
|
||||
// Is LR even live at OldIdx?
|
||||
if (I == E || SlotIndex::isEarlierInstr(OldIdx, I->start))
|
||||
return;
|
||||
|
||||
@@ -914,7 +915,7 @@ private:
|
||||
if (I == E || !SlotIndex::isSameInstr(I->start, OldIdx)) {
|
||||
// No def, search for the new kill.
|
||||
// This can never be an early clobber kill since there is no def.
|
||||
llvm::prior(I)->end = findLastUseBefore(LI.reg).getRegSlot();
|
||||
llvm::prior(I)->end = findLastUseBefore(Reg).getRegSlot();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -926,18 +927,18 @@ private:
|
||||
DefVNI->def = NewIdx.getRegSlot(I->start.isEarlyClobber());
|
||||
|
||||
// Check for an existing def at NewIdx.
|
||||
LiveInterval::iterator NewI = LI.find(NewIdx.getRegSlot());
|
||||
LiveRange::iterator NewI = LR.find(NewIdx.getRegSlot());
|
||||
if (SlotIndex::isSameInstr(NewI->start, NewIdx)) {
|
||||
assert(NewI->valno != DefVNI && "Same value defined more than once?");
|
||||
// There is an existing def at NewIdx.
|
||||
if (I->end.isDead()) {
|
||||
// Case 3: Remove the dead def at OldIdx.
|
||||
LI.removeValNo(DefVNI);
|
||||
LR.removeValNo(DefVNI);
|
||||
return;
|
||||
}
|
||||
// Case 4: Replace def at NewIdx with live def at OldIdx.
|
||||
I->start = DefVNI->def;
|
||||
LI.removeValNo(NewI->valno);
|
||||
LR.removeValNo(NewI->valno);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -948,7 +949,7 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
// DefVNI is a dead def. It may have been moved across other values in LI,
|
||||
// DefVNI is a dead def. It may have been moved across other values in LR,
|
||||
// so move I up to NewI. Slide [NewI;I) down one position.
|
||||
std::copy_backward(NewI, I, llvm::next(I));
|
||||
*NewI = LiveRange::Segment(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
|
||||
|
Reference in New Issue
Block a user