return LIS->getCachedRegUnit(Reg);
}
+void RegPressureTracker::reset() {
+ MBB = 0;
+ LIS = 0;
+
+ CurrSetPressure.clear();
+ LiveThruPressure.clear();
+ P.MaxSetPressure.clear();
+
+ if (RequireIntervals)
+ static_cast<IntervalPressure&>(P).reset();
+ else
+ static_cast<RegionPressure&>(P).reset();
+
+ LiveRegs.PhysRegs.clear();
+ LiveRegs.VirtRegs.clear();
+ UntiedDefs.clear();
+}
+
/// Setup the RegPressureTracker.
///
/// TODO: Add support for pressure without LiveIntervals.
MachineBasicBlock::const_iterator pos,
bool ShouldTrackUntiedDefs)
{
+ reset();
+
MF = mf;
TRI = MF->getTarget().getRegisterInfo();
RCI = rci;
CurrPos = pos;
CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
- LiveThruPressure.clear();
- if (RequireIntervals)
- static_cast<IntervalPressure&>(P).reset();
- else
- static_cast<RegionPressure&>(P).reset();
P.MaxSetPressure = CurrSetPressure;
- LiveRegs.PhysRegs.clear();
LiveRegs.PhysRegs.setUniverse(TRI->getNumRegs());
- LiveRegs.VirtRegs.clear();
LiveRegs.VirtRegs.setUniverse(MRI->getNumVirtRegs());
- UntiedDefs.clear();
if (TrackUntiedDefs)
UntiedDefs.setUniverse(MRI->getNumVirtRegs());
}
const MachineRegisterInfo *MRI) {
assert(!PDiff.begin()->isValid() && "stale PDiff");
- for (unsigned i = 0, e = RegOpers.Defs.size(); i != e; ++i) {
- if (!containsReg(RegOpers.Uses, RegOpers.Defs[i]))
- PDiff.addPressureChange(RegOpers.Defs[i], true, MRI);
- }
+ for (unsigned i = 0, e = RegOpers.Defs.size(); i != e; ++i)
+ PDiff.addPressureChange(RegOpers.Defs[i], true, MRI);
+
for (unsigned i = 0, e = RegOpers.Uses.size(); i != e; ++i)
PDiff.addPressureChange(RegOpers.Uses[i], false, MRI);
}
increaseSetPressure(P.MaxSetPressure, MRI->getPressureSets(Reg));
}
-/// Recede across the previous instruction.
-/// Record the pressure difference if it is provided.
-bool RegPressureTracker::recede(PressureDiff *PDiff) {
+/// Recede across the previous instruction. If LiveUses is provided, record any
+/// RegUnits that are made live by the current instruction's uses. This includes
+/// registers that are both defined and used by the instruction. If a pressure
+/// difference pointer is provided record the changes is pressure caused by this
+/// instruction independent of liveness.
+bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
+ PressureDiff *PDiff) {
// Check for the top of the analyzable region.
if (CurrPos == MBB->begin()) {
closeRegion();
// Adjust liveouts if LiveIntervals are available.
if (RequireIntervals) {
const LiveInterval *LI = getInterval(Reg);
- if (LI && !LI->isKilledAtInstr(SlotIdx))
- discoverLiveOut(Reg);
+ // Check if this LR is killed and not redefined here.
+ if (LI) {
+ LiveRangeQuery LRQ(*LI, SlotIdx);
+ if (!LRQ.isKill() && !LRQ.valueDefined())
+ discoverLiveOut(Reg);
+ }
}
increaseRegPressure(Reg);
LiveRegs.insert(Reg);
+ if (LiveUses && !containsReg(*LiveUses, Reg))
+ LiveUses->push_back(Reg);
}
}
if (TrackUntiedDefs) {
bool lastUse = false;
if (RequireIntervals) {
const LiveInterval *LI = getInterval(Reg);
- lastUse = LI && LI->isKilledAtInstr(SlotIdx);
+ lastUse = LI && LiveRangeQuery(*LI, SlotIdx).isKill();
}
else {
// Allocatable physregs are always single-use before register rewriting.
/// @param MaxPressureLimit Is the max pressure within the region, not
/// necessarily at the current position.
void RegPressureTracker::
-getUpwardPressureDelta(const MachineInstr *MI, /*const*/ PressureDiff &PDiff1,
+getUpwardPressureDelta(const MachineInstr *MI, /*const*/ PressureDiff &PDiff,
RegPressureDelta &Delta,
ArrayRef<PressureChange> CriticalPSets,
ArrayRef<unsigned> MaxPressureLimit) const {
- RegisterOperands RegOpers(TRI, MRI, /*IgnoreDead=*/true);
- collectOperands(MI, RegOpers);
-
- // Decrease the pressure change for live uses.
- PressureDiff PDiff = PDiff1;
- for (unsigned i = 0, e = RegOpers.Uses.size(); i != e; ++i) {
- if (LiveRegs.contains(RegOpers.Uses[i]))
- PDiff.addPressureChange(RegOpers.Uses[i], true, MRI);
- }
-
- // Now directly query pressure from PDiff. Everything above this can be
- // cached and updated independent of the query.
unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
for (PressureDiff::const_iterator
PDiffI = PDiff.begin(), PDiffE = PDiff.end();
// to be bottom-scheduled to avoid searching uses at each query.
SlotIndex CurrIdx = getCurrSlot();
const LiveInterval *LI = getInterval(Reg);
- if (LI && LI->isKilledAtInstr(SlotIdx)
- && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) {
- decreaseRegPressure(Reg);
+ if (LI) {
+ LiveRangeQuery LRQ(*LI, SlotIdx);
+ if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS))
+ decreaseRegPressure(Reg);
}
}
else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {