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:
Matthias Braun
2013-10-10 21:29:02 +00:00
parent e25dde550b
commit 4f3b5e8c92
13 changed files with 132 additions and 129 deletions

View File

@@ -90,9 +90,9 @@ namespace llvm {
/// block. /// block.
SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks; SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
/// RegUnitIntervals - Keep a live interval for each register unit as a way /// Keeps a live range set for each register unit to track fixed physreg
/// of tracking fixed physreg interference. /// interference.
SmallVector<LiveInterval*, 0> RegUnitIntervals; SmallVector<LiveRange*, 0> RegUnitRanges;
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
@@ -364,24 +364,24 @@ namespace llvm {
/// getRegUnit - Return the live range for Unit. /// getRegUnit - Return the live range for Unit.
/// It will be computed if it doesn't exist. /// It will be computed if it doesn't exist.
LiveInterval &getRegUnit(unsigned Unit) { LiveRange &getRegUnit(unsigned Unit) {
LiveInterval *LI = RegUnitIntervals[Unit]; LiveRange *LR = RegUnitRanges[Unit];
if (!LI) { if (!LR) {
// Compute missing ranges on demand. // Compute missing ranges on demand.
RegUnitIntervals[Unit] = LI = new LiveInterval(Unit, HUGE_VALF); RegUnitRanges[Unit] = LR = new LiveRange();
computeRegUnitInterval(*LI); computeRegUnitRange(*LR, Unit);
} }
return *LI; return *LR;
} }
/// getCachedRegUnit - Return the live range for Unit if it has already /// getCachedRegUnit - Return the live range for Unit if it has already
/// been computed, or NULL if it hasn't been computed yet. /// been computed, or NULL if it hasn't been computed yet.
LiveInterval *getCachedRegUnit(unsigned Unit) { LiveRange *getCachedRegUnit(unsigned Unit) {
return RegUnitIntervals[Unit]; return RegUnitRanges[Unit];
} }
const LiveInterval *getCachedRegUnit(unsigned Unit) const { const LiveRange *getCachedRegUnit(unsigned Unit) const {
return RegUnitIntervals[Unit]; return RegUnitRanges[Unit];
} }
private: private:
@@ -397,7 +397,7 @@ namespace llvm {
void dumpInstrs() const; void dumpInstrs() const;
void computeLiveInRegUnits(); void computeLiveInRegUnits();
void computeRegUnitInterval(LiveInterval&); void computeRegUnitRange(LiveRange&, unsigned Unit);
void computeVirtRegInterval(LiveInterval&); void computeVirtRegInterval(LiveInterval&);
class HMEditor; class HMEditor;

View File

@@ -22,7 +22,7 @@
namespace llvm { namespace llvm {
class LiveIntervals; class LiveIntervals;
class LiveInterval; class LiveRange;
class RegisterClassInfo; class RegisterClassInfo;
class MachineInstr; class MachineInstr;
@@ -424,7 +424,7 @@ public:
void dump() const; void dump() const;
protected: protected:
const LiveInterval *getInterval(unsigned Reg) const; const LiveRange *getLiveRange(unsigned Reg) const;
void increaseRegPressure(ArrayRef<unsigned> Regs); void increaseRegPressure(ArrayRef<unsigned> Regs);
void decreaseRegPressure(ArrayRef<unsigned> Regs); void decreaseRegPressure(ArrayRef<unsigned> Regs);

View File

@@ -1106,10 +1106,10 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
// FoldMI does not define this physreg. Remove the LI segment. // FoldMI does not define this physreg. Remove the LI segment.
assert(MO->isDead() && "Cannot fold physreg def"); assert(MO->isDead() && "Cannot fold physreg def");
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units) { for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units) {
if (LiveInterval *LI = LIS.getCachedRegUnit(*Units)) { if (LiveRange *LR = LIS.getCachedRegUnit(*Units)) {
SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot(); SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot();
if (VNInfo *VNI = LI->getVNInfoAt(Idx)) if (VNInfo *VNI = LR->getVNInfoAt(Idx))
LI->removeValNo(VNI); LR->removeValNo(VNI);
} }
} }
} }

View File

@@ -204,11 +204,11 @@ void InterferenceCache::Entry::update(unsigned MBBNum) {
// Fixed interference. // Fixed interference.
for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) { for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
LiveInterval::iterator &I = RegUnits[i].FixedI; LiveInterval::iterator &I = RegUnits[i].FixedI;
LiveInterval *LI = RegUnits[i].Fixed; LiveRange *LR = RegUnits[i].Fixed;
if (I == LI->end() || I->start >= Stop) if (I == LR->end() || I->start >= Stop)
continue; continue;
I = LI->advanceTo(I, Stop); I = LR->advanceTo(I, Stop);
bool Backup = I == LI->end() || I->start >= Stop; bool Backup = I == LR->end() || I->start >= Stop;
if (Backup) if (Backup)
--I; --I;
SlotIndex StopI = I->end; SlotIndex StopI = I->end;

View File

@@ -72,7 +72,7 @@ class InterferenceCache {
unsigned VirtTag; unsigned VirtTag;
/// Fixed interference in RegUnit. /// Fixed interference in RegUnit.
LiveInterval *Fixed; LiveRange *Fixed;
/// Iterator pointing into the fixed RegUnit interference. /// Iterator pointing into the fixed RegUnit interference.
LiveInterval::iterator FixedI; LiveInterval::iterator FixedI;

View File

@@ -220,13 +220,13 @@ public:
/// End points where VNI is no longer live are added to Kills. /// End points where VNI is no longer live are added to Kills.
/// @param Idx Starting point for the definition. /// @param Idx Starting point for the definition.
/// @param LocNo Location number to propagate. /// @param LocNo Location number to propagate.
/// @param LI Restrict liveness to where LI has the value VNI. May be null. /// @param LR Restrict liveness to where LR has the value VNI. May be null.
/// @param VNI When LI is not null, this is the value to restrict to. /// @param VNI When LR is not null, this is the value to restrict to.
/// @param Kills Append end points of VNI's live range to Kills. /// @param Kills Append end points of VNI's live range to Kills.
/// @param LIS Live intervals analysis. /// @param LIS Live intervals analysis.
/// @param MDT Dominator tree. /// @param MDT Dominator tree.
void extendDef(SlotIndex Idx, unsigned LocNo, void extendDef(SlotIndex Idx, unsigned LocNo,
LiveInterval *LI, const VNInfo *VNI, LiveRange *LR, const VNInfo *VNI,
SmallVectorImpl<SlotIndex> *Kills, SmallVectorImpl<SlotIndex> *Kills,
LiveIntervals &LIS, MachineDominatorTree &MDT, LiveIntervals &LIS, MachineDominatorTree &MDT,
UserValueScopes &UVS); UserValueScopes &UVS);
@@ -495,7 +495,7 @@ bool LDVImpl::collectDebugValues(MachineFunction &mf) {
} }
void UserValue::extendDef(SlotIndex Idx, unsigned LocNo, void UserValue::extendDef(SlotIndex Idx, unsigned LocNo,
LiveInterval *LI, const VNInfo *VNI, LiveRange *LR, const VNInfo *VNI,
SmallVectorImpl<SlotIndex> *Kills, SmallVectorImpl<SlotIndex> *Kills,
LiveIntervals &LIS, MachineDominatorTree &MDT, LiveIntervals &LIS, MachineDominatorTree &MDT,
UserValueScopes &UVS) { UserValueScopes &UVS) {
@@ -509,8 +509,8 @@ void UserValue::extendDef(SlotIndex Idx, unsigned LocNo,
// Limit to VNI's live range. // Limit to VNI's live range.
bool ToEnd = true; bool ToEnd = true;
if (LI && VNI) { if (LR && VNI) {
LiveInterval::Segment *Segment = LI->getSegmentContaining(Start); LiveInterval::Segment *Segment = LR->getSegmentContaining(Start);
if (!Segment || Segment->valno != VNI) { if (!Segment || Segment->valno != VNI) {
if (Kills) if (Kills)
Kills->push_back(Start); Kills->push_back(Start);
@@ -669,10 +669,10 @@ UserValue::computeIntervals(MachineRegisterInfo &MRI,
// For physregs, use the live range of the first regunit as a guide. // For physregs, use the live range of the first regunit as a guide.
unsigned Unit = *MCRegUnitIterator(Loc.getReg(), &TRI); unsigned Unit = *MCRegUnitIterator(Loc.getReg(), &TRI);
LiveInterval *LI = &LIS.getRegUnit(Unit); LiveRange *LR = &LIS.getRegUnit(Unit);
const VNInfo *VNI = LI->getVNInfoAt(Idx); const VNInfo *VNI = LR->getVNInfoAt(Idx);
// Don't track copies from physregs, it is too expensive. // Don't track copies from physregs, it is too expensive.
extendDef(Idx, LocNo, LI, VNI, 0, LIS, MDT, UVS); extendDef(Idx, LocNo, LR, VNI, 0, LIS, MDT, UVS);
} }
// Finally, erase all the undefs. // Finally, erase all the undefs.

View File

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

View File

@@ -262,9 +262,9 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
else if (MOI->isDef()) { else if (MOI->isDef()) {
for (MCRegUnitIterator Units(Reg, MRI.getTargetRegisterInfo()); for (MCRegUnitIterator Units(Reg, MRI.getTargetRegisterInfo());
Units.isValid(); ++Units) { Units.isValid(); ++Units) {
if (LiveInterval *LI = LIS.getCachedRegUnit(*Units)) { if (LiveRange *LR = LIS.getCachedRegUnit(*Units)) {
if (VNInfo *VNI = LI->getVNInfoAt(Idx)) if (VNInfo *VNI = LR->getVNInfoAt(Idx))
LI->removeValNo(VNI); LR->removeValNo(VNI);
} }
} }
} }

View File

@@ -119,9 +119,11 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
if (VirtReg.empty()) if (VirtReg.empty())
return false; return false;
CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
if (VirtReg.overlaps(LIS->getRegUnit(*Units), CP, *LIS->getSlotIndexes())) const LiveRange &UnitRange = LIS->getRegUnit(*Units);
if (VirtReg.overlaps(UnitRange, CP, *LIS->getSlotIndexes()))
return true; return true;
}
return false; return false;
} }

View File

@@ -1018,16 +1018,16 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
// Check the cached regunit intervals. // Check the cached regunit intervals.
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) { if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) { for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) { if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units)) {
LiveQueryResult LRQ = LI->Query(UseIdx); LiveQueryResult LRQ = LR->Query(UseIdx);
if (!LRQ.valueIn()) { if (!LRQ.valueIn()) {
report("No live segment at use", MO, MONum); report("No live segment at use", MO, MONum);
*OS << UseIdx << " is not live in " << PrintRegUnit(*Units, TRI) *OS << UseIdx << " is not live in " << PrintRegUnit(*Units, TRI)
<< ' ' << *LI << '\n'; << ' ' << *LR << '\n';
} }
if (MO->isKill() && !LRQ.isKill()) { if (MO->isKill() && !LRQ.isKill()) {
report("Live range continues after kill flag", MO, MONum); report("Live range continues after kill flag", MO, MONum);
*OS << PrintRegUnit(*Units, TRI) << ' ' << *LI << '\n'; *OS << PrintRegUnit(*Units, TRI) << ' ' << *LR << '\n';
} }
} }
} }
@@ -1352,8 +1352,8 @@ void MachineVerifier::verifyLiveIntervals() {
// Verify all the cached regunit intervals. // Verify all the cached regunit intervals.
for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i) for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(i)) if (const LiveRange *LR = LiveInts->getCachedRegUnit(i))
verifyLiveInterval(*LI); verifyLiveRange(*LR, i);
} }
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,

View File

@@ -1466,9 +1466,9 @@ void RAGreedy::calcGapWeights(unsigned PhysReg,
// Add fixed interference. // Add fixed interference.
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
const LiveInterval &LI = LIS->getRegUnit(*Units); const LiveRange &LR = LIS->getRegUnit(*Units);
LiveInterval::const_iterator I = LI.find(StartIdx); LiveRange::const_iterator I = LR.find(StartIdx);
LiveInterval::const_iterator E = LI.end(); LiveRange::const_iterator E = LR.end();
// Same loop as above. Mark any overlapped gaps as HUGE_VALF. // Same loop as above. Mark any overlapped gaps as HUGE_VALF.
for (unsigned Gap = 0; I != E && I->start < StopIdx; ++I) { for (unsigned Gap = 0; I != E && I->start < StopIdx; ++I) {

View File

@@ -874,8 +874,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) { for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
unsigned Reg = NewMIImplDefs[i]; unsigned Reg = NewMIImplDefs[i];
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
if (LiveInterval *LI = LIS->getCachedRegUnit(*Units)) if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
LI->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator()); LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
} }
DEBUG(dbgs() << "Remat: " << *NewMI); DEBUG(dbgs() << "Remat: " << *NewMI);

View File

@@ -147,7 +147,7 @@ void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
LiveInRegs.clear(); LiveInRegs.clear();
} }
const LiveInterval *RegPressureTracker::getInterval(unsigned Reg) const { const LiveRange *RegPressureTracker::getLiveRange(unsigned Reg) const {
if (TargetRegisterInfo::isVirtualRegister(Reg)) if (TargetRegisterInfo::isVirtualRegister(Reg))
return &LIS->getInterval(Reg); return &LIS->getInterval(Reg);
return LIS->getCachedRegUnit(Reg); return LIS->getCachedRegUnit(Reg);
@@ -510,10 +510,9 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
if (!LiveRegs.contains(Reg)) { if (!LiveRegs.contains(Reg)) {
// Adjust liveouts if LiveIntervals are available. // Adjust liveouts if LiveIntervals are available.
if (RequireIntervals) { if (RequireIntervals) {
const LiveInterval *LI = getInterval(Reg); const LiveRange *LR = getLiveRange(Reg);
// Check if this LR is killed and not redefined here. if (LR) {
if (LI) { LiveQueryResult LRQ = LR->Query(SlotIdx);
LiveQueryResult LRQ = LI->Query(SlotIdx);
if (!LRQ.isKill() && !LRQ.valueDefined()) if (!LRQ.isKill() && !LRQ.valueDefined())
discoverLiveOut(Reg); discoverLiveOut(Reg);
} }
@@ -570,8 +569,8 @@ bool RegPressureTracker::advance() {
// Kill liveness at last uses. // Kill liveness at last uses.
bool lastUse = false; bool lastUse = false;
if (RequireIntervals) { if (RequireIntervals) {
const LiveInterval *LI = getInterval(Reg); const LiveRange *LR = getLiveRange(Reg);
lastUse = LI && LI->Query(SlotIdx).isKill(); lastUse = LR && LR->Query(SlotIdx).isKill();
} }
else { else {
// Allocatable physregs are always single-use before register rewriting. // Allocatable physregs are always single-use before register rewriting.
@@ -894,11 +893,12 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
// FIXME: allow the caller to pass in the list of vreg uses that remain // FIXME: allow the caller to pass in the list of vreg uses that remain
// to be bottom-scheduled to avoid searching uses at each query. // to be bottom-scheduled to avoid searching uses at each query.
SlotIndex CurrIdx = getCurrSlot(); SlotIndex CurrIdx = getCurrSlot();
const LiveInterval *LI = getInterval(Reg); const LiveRange *LR = getLiveRange(Reg);
if (LI) { if (LR) {
LiveQueryResult LRQ = LI->Query(SlotIdx); LiveQueryResult LRQ = LR->Query(SlotIdx);
if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) {
decreaseRegPressure(Reg); decreaseRegPressure(Reg);
}
} }
} }
else if (!TargetRegisterInfo::isVirtualRegister(Reg)) { else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {