void RegPressureTracker::advance() { const MachineInstr &MI = *CurrPos; RegisterOperands RegOpers; RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false); if (TrackLaneMasks) { SlotIndex SlotIdx = getCurrSlot(); RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx); } advance(RegOpers); }
void RegPressureTracker::recede(SmallVectorImpl<RegisterMaskPair> *LiveUses) { recedeSkipDebugValues(); const MachineInstr &MI = *CurrPos; RegisterOperands RegOpers; RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false); if (TrackLaneMasks) { SlotIndex SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot(); RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx); } else if (RequireIntervals) { RegOpers.detectDeadDefs(MI, *LIS); } recede(RegOpers, LiveUses); }
/// Record the downward impact of a single instruction on current register /// pressure. Unlike the advance/recede pressure tracking interface, this does /// not discover live in/outs. /// /// This is intended for speculative queries. It leaves pressure inconsistent /// with the current position, so must be restored by the caller. void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) { assert(!MI->isDebugValue() && "Expect a nondebug instruction."); SlotIndex SlotIdx; if (RequireIntervals) SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot(); // Account for register pressure similar to RegPressureTracker::recede(). RegisterOperands RegOpers; RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, false); if (TrackLaneMasks) RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx); for (const RegisterMaskPair &Use : RegOpers.Uses) { unsigned Reg = Use.RegUnit; LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx); if (LastUseMask == 0) continue; if (RequireIntervals) { // The LastUseMask is queried from the liveness information of instruction // which may be further down the schedule. Some lanes may actually not be // last uses for the current position. // 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. SlotIndex CurrIdx = getCurrSlot(); LastUseMask = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS); if (LastUseMask == 0) continue; } LaneBitmask LiveMask = LiveRegs.contains(Reg); LaneBitmask NewMask = LiveMask & ~LastUseMask; decreaseRegPressure(Reg, LiveMask, NewMask); } // Generate liveness for defs. for (const RegisterMaskPair &Def : RegOpers.Defs) { unsigned Reg = Def.RegUnit; LaneBitmask LiveMask = LiveRegs.contains(Reg); LaneBitmask NewMask = LiveMask | Def.LaneMask; increaseRegPressure(Reg, LiveMask, NewMask); } // Boost pressure for all dead defs together. bumpDeadDefs(RegOpers.DeadDefs); }
/// Collect physical and virtual register operands. static void collectOperands(const MachineInstr *MI, RegisterOperands &RegOpers) { for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI) RegOpers.collect(*OperI); // Remove redundant physreg dead defs. SmallVectorImpl<unsigned>::iterator I = std::remove_if(RegOpers.DeadDefs.begin(), RegOpers.DeadDefs.end(), std::bind1st(std::ptr_fun(containsReg), RegOpers.Defs)); RegOpers.DeadDefs.erase(I, RegOpers.DeadDefs.end()); }
/// Record the upward impact of a single instruction on current register /// pressure. Unlike the advance/recede pressure tracking interface, this does /// not discover live in/outs. /// /// This is intended for speculative queries. It leaves pressure inconsistent /// with the current position, so must be restored by the caller. void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) { assert(!MI->isDebugValue() && "Expect a nondebug instruction."); SlotIndex SlotIdx; if (RequireIntervals) SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot(); // Account for register pressure similar to RegPressureTracker::recede(). RegisterOperands RegOpers; RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/true); assert(RegOpers.DeadDefs.size() == 0); if (TrackLaneMasks) RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx); else if (RequireIntervals) RegOpers.detectDeadDefs(*MI, *LIS); // Boost max pressure for all dead defs together. // Since CurrSetPressure and MaxSetPressure bumpDeadDefs(RegOpers.DeadDefs); // Kill liveness at live defs. for (const RegisterMaskPair &P : RegOpers.Defs) { unsigned Reg = P.RegUnit; LaneBitmask LiveLanes = LiveRegs.contains(Reg); LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg); LaneBitmask DefLanes = P.LaneMask; LaneBitmask LiveAfter = (LiveLanes & ~DefLanes) | UseLanes; decreaseRegPressure(Reg, LiveLanes, LiveAfter); } // Generate liveness for uses. for (const RegisterMaskPair &P : RegOpers.Uses) { unsigned Reg = P.RegUnit; LaneBitmask LiveLanes = LiveRegs.contains(Reg); LaneBitmask LiveAfter = LiveLanes | P.LaneMask; increaseRegPressure(Reg, LiveLanes, LiveAfter); } }