RegisterPressure: Split RegisterOperands analysis code from result object; NFC

This is in preparation to expose the RegisterOperands class as
RegisterPressure API.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254368 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun 2015-12-01 04:19:56 +00:00
parent 8e83fe2e97
commit 85e0db955c

View File

@ -314,71 +314,88 @@ static bool containsReg(ArrayRef<unsigned> RegUnits, unsigned RegUnit) {
}
namespace {
/// Collect this instruction's unique uses and defs into SmallVectors for
/// processing defs and uses in order.
///
/// FIXME: always ignore tied opers
class RegisterOperands {
const TargetRegisterInfo *TRI;
const MachineRegisterInfo *MRI;
bool IgnoreDead;
/// List of register defined and used by a machine instruction.
class RegisterOperands {
public:
SmallVector<unsigned, 8> Uses;
SmallVector<unsigned, 8> Defs;
SmallVector<unsigned, 8> DeadDefs;
RegisterOperands(const TargetRegisterInfo *tri,
const MachineRegisterInfo *mri, bool ID = false):
TRI(tri), MRI(mri), IgnoreDead(ID) {}
void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI,
const MachineRegisterInfo &MRI, bool IgnoreDead = false);
};
/// Push this operand's register onto the correct vector.
void collect(const MachineOperand &MO) {
/// Collect this instruction's unique uses and defs into SmallVectors for
/// processing defs and uses in order.
///
/// FIXME: always ignore tied opers
class RegisterOperandsCollector {
RegisterOperands &RegOpers;
const TargetRegisterInfo &TRI;
const MachineRegisterInfo &MRI;
bool IgnoreDead;
RegisterOperandsCollector(RegisterOperands &RegOpers,
const TargetRegisterInfo &TRI,
const MachineRegisterInfo &MRI,
bool IgnoreDead)
: RegOpers(RegOpers), TRI(TRI), MRI(MRI), IgnoreDead(IgnoreDead) {}
void collectInstr(const MachineInstr &MI) const {
for (ConstMIBundleOperands OperI(&MI); OperI.isValid(); ++OperI)
collectOperand(*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());
}
/// Push this operand's register onto the correct vectors.
void collectOperand(const MachineOperand &MO) const {
if (!MO.isReg() || !MO.getReg())
return;
unsigned Reg = MO.getReg();
if (MO.readsReg())
pushRegUnits(MO.getReg(), Uses);
pushRegUnits(Reg, RegOpers.Uses);
if (MO.isDef()) {
if (MO.isDead()) {
if (!IgnoreDead)
pushRegUnits(MO.getReg(), DeadDefs);
}
else
pushRegUnits(MO.getReg(), Defs);
pushRegUnits(Reg, RegOpers.DeadDefs);
} else
pushRegUnits(Reg, RegOpers.Defs);
}
}
protected:
void pushRegUnits(unsigned Reg, SmallVectorImpl<unsigned> &RegUnits) {
void pushRegUnits(unsigned Reg, SmallVectorImpl<unsigned> &RegUnits) const {
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
if (containsReg(RegUnits, Reg))
return;
RegUnits.push_back(Reg);
}
else if (MRI->isAllocatable(Reg)) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
} else if (MRI.isAllocatable(Reg)) {
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units) {
if (containsReg(RegUnits, *Units))
continue;
RegUnits.push_back(*Units);
}
}
}
friend class RegisterOperands;
};
} // namespace
/// 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());
void RegisterOperands::collect(const MachineInstr &MI,
const TargetRegisterInfo &TRI,
const MachineRegisterInfo &MRI,
bool IgnoreDead) {
RegisterOperandsCollector Collector(*this, TRI, MRI, IgnoreDead);
Collector.collectInstr(MI);
}
} // namespace
/// Initialize an array of N PressureDiffs.
void PressureDiffs::init(unsigned N) {
Size = N;
@ -505,8 +522,8 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
if (RequireIntervals && isTopClosed())
static_cast<IntervalPressure&>(P).openTop(SlotIdx);
RegisterOperands RegOpers(TRI, MRI);
collectOperands(CurrPos, RegOpers);
RegisterOperands RegOpers;
RegOpers.collect(*CurrPos, *TRI, *MRI);
if (PDiff)
collectPDiff(*PDiff, RegOpers, MRI);
@ -594,8 +611,8 @@ bool RegPressureTracker::advance() {
static_cast<RegionPressure&>(P).openBottom(CurrPos);
}
RegisterOperands RegOpers(TRI, MRI);
collectOperands(CurrPos, RegOpers);
RegisterOperands RegOpers;
RegOpers.collect(*CurrPos, *TRI, *MRI);
for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
unsigned Reg = RegOpers.Uses[i];
@ -728,8 +745,8 @@ void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
// Account for register pressure similar to RegPressureTracker::recede().
RegisterOperands RegOpers(TRI, MRI, /*IgnoreDead=*/true);
collectOperands(MI, RegOpers);
RegisterOperands RegOpers;
RegOpers.collect(*MI, *TRI, *MRI, /*IgnoreDead=*/true);
// Boost max pressure for all dead defs together.
// Since CurrSetPressure and MaxSetPressure
@ -923,8 +940,8 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
// Account for register pressure similar to RegPressureTracker::recede().
RegisterOperands RegOpers(TRI, MRI);
collectOperands(MI, RegOpers);
RegisterOperands RegOpers;
RegOpers.collect(*MI, *TRI, *MRI);
// Kill liveness at last uses. Assume allocatable physregs are single-use
// rather than checking LiveIntervals.