}
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;
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);
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];
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
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.