}
void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
+ const char *sep = "";
for (const PressureChange &Change : *this) {
if (!Change.isValid())
break;
- dbgs() << " " << TRI.getRegPressureSetName(Change.getPSet())
+ dbgs() << sep << TRI.getRegPressureSetName(Change.getPSet())
<< " " << Change.getUnitInc();
+ sep = " ";
}
dbgs() << '\n';
}
LiveInRegs.clear();
}
+void LiveRegSet::init(const MachineRegisterInfo &MRI) {
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+ unsigned NumRegUnits = TRI.getNumRegs();
+ unsigned NumVirtRegs = MRI.getNumVirtRegs();
+ Regs.setUniverse(NumRegUnits + NumVirtRegs);
+ this->NumRegUnits = NumRegUnits;
+}
+
+void LiveRegSet::clear() {
+ Regs.clear();
+}
+
const LiveRange *RegPressureTracker::getLiveRange(unsigned Reg) const {
if (TargetRegisterInfo::isVirtualRegister(Reg))
return &LIS->getInterval(Reg);
else
static_cast<RegionPressure&>(P).reset();
- LiveRegs.PhysRegs.clear();
- LiveRegs.VirtRegs.clear();
+ LiveRegs.clear();
UntiedDefs.clear();
}
P.MaxSetPressure = CurrSetPressure;
- LiveRegs.PhysRegs.setUniverse(TRI->getNumRegUnits());
- LiveRegs.VirtRegs.setUniverse(MRI->getNumVirtRegs());
+ LiveRegs.init(*MRI);
if (TrackUntiedDefs)
UntiedDefs.setUniverse(MRI->getNumVirtRegs());
}
static_cast<RegionPressure&>(P).TopPos = CurrPos;
assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
- P.LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
- P.LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
- P.LiveInRegs.append(LiveRegs.VirtRegs.begin(), LiveRegs.VirtRegs.end());
+ P.LiveInRegs.reserve(LiveRegs.size());
+ LiveRegs.appendTo(P.LiveInRegs);
}
/// Set the boundary for the bottom of the region and summarize live outs.
static_cast<RegionPressure&>(P).BottomPos = CurrPos;
assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
- P.LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
- P.LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
- P.LiveOutRegs.append(LiveRegs.VirtRegs.begin(), LiveRegs.VirtRegs.end());
+ P.LiveOutRegs.reserve(LiveRegs.size());
+ LiveRegs.appendTo(P.LiveOutRegs);
}
/// Finalize the region boundaries and record live ins and live outs.
void RegPressureTracker::closeRegion() {
if (!isTopClosed() && !isBottomClosed()) {
- assert(LiveRegs.PhysRegs.empty() && LiveRegs.VirtRegs.empty() &&
- "no region boundary");
+ assert(LiveRegs.size() == 0 && "no region boundary");
return;
}
if (!isBottomClosed())
return true;
}
-bool RegPressureTracker::isLastUse(unsigned VRegOrUnit, SlotIndex Pos) const {
- // Allocatable physregs are always single-use before register rewriting.
- if (!TargetRegisterInfo::isVirtualRegister(VRegOrUnit))
- return true;
- // Without liveness information we conservatively assume "no last use".
- if (!RequireIntervals)
- return false;
- const LiveRange *LR = getLiveRange(VRegOrUnit);
- return LR && LR->Query(Pos).isKill();
-}
-
/// Advance across the current instruction.
bool RegPressureTracker::advance() {
assert(!TrackUntiedDefs && "unsupported mode");
if (!isLive)
discoverLiveIn(Reg);
// Kill liveness at last uses.
- if (isLastUse(Reg, SlotIdx)) {
- if (isLive) {
- LiveRegs.erase(Reg);
- decreaseRegPressure(Reg);
- }
- } else if(!isLive) {
- // We discovered a live which was not last used here, adjust pressure.
- increaseRegPressure(Reg);
+ bool lastUse = false;
+ if (RequireIntervals) {
+ const LiveRange *LR = getLiveRange(Reg);
+ lastUse = LR && LR->Query(SlotIdx).isKill();
}
+ else {
+ // Allocatable physregs are always single-use before register rewriting.
+ lastUse = !TargetRegisterInfo::isVirtualRegister(Reg);
+ }
+ if (lastUse && isLive) {
+ LiveRegs.erase(Reg);
+ decreaseRegPressure(Reg);
+ }
+ else if (!lastUse && !isLive)
+ increaseRegPressure(Reg);
}
// Generate liveness for defs.
unsigned MNew = MOld;
// Ignore DeadDefs here because they aren't captured by PressureChange.
unsigned PNew = POld + PDiffI->getUnitInc();
- assert((PDiffI->getUnitInc() >= 0) == (PNew >= POld) && "PSet overflow");
+ assert((PDiffI->getUnitInc() >= 0) == (PNew >= POld)
+ && "PSet overflow/underflow");
if (PNew > MOld)
MNew = PNew;
// Check if current pressure has exceeded the limit.
for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
unsigned Reg = RegOpers.Uses[i];
- bool IsLastUse = isLastUse(Reg, SlotIdx);
- // We had a last use at MIs position. To know the situation for the current
- // position we have to check if there exist other uses in between.
- if (IsLastUse && TargetRegisterInfo::isVirtualRegister(Reg)) {
- SlotIndex CurrIdx = getCurrSlot();
+ if (RequireIntervals) {
// 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.
- if (findUseBetween(Reg, CurrIdx, SlotIdx, *MRI, LIS))
- IsLastUse = false;
+ SlotIndex CurrIdx = getCurrSlot();
+ const LiveRange *LR = getLiveRange(Reg);
+ if (LR) {
+ LiveQueryResult LRQ = LR->Query(SlotIdx);
+ if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, *MRI, LIS))
+ decreaseRegPressure(Reg);
+ }
}
- if (IsLastUse)
+ else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
+ // Allocatable physregs are always single-use before register rewriting.
decreaseRegPressure(Reg);
+ }
}
// Generate liveness for defs.