[BreakFalseDeps][X86] Move operand loop out of X86's getUndefRegClearance and put in the pass.

X86 is the only user of this interface in tree. Previously the
X86 pass would loop over operands looking for one undef operand for
the pass to fix. But there could theoretically be multiple operands
to fix. So it makes more sense for the pass to do the looping and
ask the target if an operand needs to be fixed.
This commit is contained in:
Craig Topper 2020-08-10 10:32:29 -07:00
parent ecdeeefdee
commit 1e510916fc
4 changed files with 23 additions and 23 deletions

View File

@ -1627,7 +1627,7 @@ public:
/// This hook works similarly to getPartialRegUpdateClearance, except that it
/// does not take an operand index. Instead sets \p OpNum to the index of the
/// unused register.
virtual unsigned getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum,
virtual unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const {
// The default implementation returns 0 for no undef register dependency.
return 0;

View File

@ -186,17 +186,24 @@ bool BreakFalseDeps::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx,
void BreakFalseDeps::processDefs(MachineInstr *MI) {
assert(!MI->isDebugInstr() && "Won't process debug values");
const MCInstrDesc &MCID = MI->getDesc();
// Break dependence on undef uses. Do this before updating LiveRegs below.
// This can remove a false dependence with no additional instructions.
unsigned OpNum;
unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI);
if (Pref) {
bool HadTrueDependency = pickBestRegisterForUndef(MI, OpNum, Pref);
// We don't need to bother trying to break a dependency if this
// instruction has a true dependency on that register through another
// operand - we'll have to wait for it to be available regardless.
if (!HadTrueDependency && shouldBreakDependence(MI, OpNum, Pref))
UndefReads.push_back(std::make_pair(MI, OpNum));
for (unsigned i = MCID.getNumDefs(), e = MCID.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.getReg() || !MO.isUse() || !MO.isUndef())
continue;
unsigned Pref = TII->getUndefRegClearance(*MI, i, TRI);
if (Pref) {
bool HadTrueDependency = pickBestRegisterForUndef(MI, i, Pref);
// We don't need to bother trying to break a dependency if this
// instruction has a true dependency on that register through another
// operand - we'll have to wait for it to be available regardless.
if (!HadTrueDependency && shouldBreakDependence(MI, i, Pref))
UndefReads.push_back(std::make_pair(MI, i));
}
}
// The code below allows the target to create a new instruction to break the
@ -204,7 +211,6 @@ void BreakFalseDeps::processDefs(MachineInstr *MI) {
if (MF->getFunction().hasMinSize())
return;
const MCInstrDesc &MCID = MI->getDesc();
for (unsigned i = 0,
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {

View File

@ -5121,18 +5121,12 @@ static bool hasUndefRegUpdate(unsigned Opcode, unsigned OpNum,
/// Like getPartialRegUpdateClearance, this makes a strong assumption that the
/// high bits that are passed-through are not live.
unsigned
X86InstrInfo::getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum,
X86InstrInfo::getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const {
for (unsigned i = MI.getNumExplicitDefs(), e = MI.getNumExplicitOperands();
i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (MO.isReg() && MO.isUndef() &&
Register::isPhysicalRegister(MO.getReg()) &&
hasUndefRegUpdate(MI.getOpcode(), i)) {
OpNum = i;
return UndefRegClearance;
}
}
const MachineOperand &MO = MI.getOperand(OpNum);
if (Register::isPhysicalRegister(MO.getReg()) &&
hasUndefRegUpdate(MI.getOpcode(), OpNum))
return UndefRegClearance;
return 0;
}

View File

@ -459,7 +459,7 @@ public:
unsigned
getPartialRegUpdateClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;
unsigned getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum,
unsigned getUndefRegClearance(const MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;
void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum,
const TargetRegisterInfo *TRI) const override;