Skip to content

Commit 2960656

Browse files
committed
[X86][NFC] Extract code for commute in foldMemoryOperandImpl into functions
To share code for folding broadcast in #79761
1 parent b23e518 commit 2960656

File tree

2 files changed

+61
-55
lines changed

2 files changed

+61
-55
lines changed

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7165,6 +7165,52 @@ static bool shouldPreventUndefRegUpdateMemFold(MachineFunction &MF,
71657165
return VRegDef && VRegDef->isImplicitDef();
71667166
}
71677167

7168+
unsigned X86InstrInfo::commuteOperandsForFold(MachineInstr &MI,
7169+
unsigned Idx1) const {
7170+
unsigned Idx2 = CommuteAnyOperandIndex;
7171+
if (!findCommutedOpIndices(MI, Idx1, Idx2))
7172+
return Idx1;
7173+
7174+
bool HasDef = MI.getDesc().getNumDefs();
7175+
Register Reg0 = HasDef ? MI.getOperand(0).getReg() : Register();
7176+
Register Reg1 = MI.getOperand(Idx1).getReg();
7177+
Register Reg2 = MI.getOperand(Idx2).getReg();
7178+
bool Tied1 = 0 == MI.getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO);
7179+
bool Tied2 = 0 == MI.getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO);
7180+
7181+
// If either of the commutable operands are tied to the destination
7182+
// then we can not commute + fold.
7183+
if ((HasDef && Reg0 == Reg1 && Tied1) || (HasDef && Reg0 == Reg2 && Tied2))
7184+
return Idx1;
7185+
7186+
MachineInstr *CommutedMI = commuteInstruction(MI, false, Idx1, Idx2);
7187+
if (!CommutedMI) {
7188+
// Unable to commute.
7189+
return Idx1;
7190+
}
7191+
if (CommutedMI != &MI) {
7192+
// New instruction. We can't fold from this.
7193+
CommutedMI->eraseFromParent();
7194+
return Idx1;
7195+
}
7196+
7197+
return Idx2;
7198+
}
7199+
7200+
void X86InstrInfo::UndoCommuteForFold(MachineInstr &MI, unsigned Idx1,
7201+
unsigned Idx2) const {
7202+
// Folding failed again - undo the commute before returning.
7203+
MachineInstr *UncommutedMI = commuteInstruction(MI, false, Idx1, Idx2);
7204+
// New instruction. It doesn't need to be kept.
7205+
if (UncommutedMI && UncommutedMI != &MI)
7206+
UncommutedMI->eraseFromParent();
7207+
}
7208+
7209+
static void printFailMsgforFold(const MachineInstr &MI, unsigned Idx) {
7210+
if (PrintFailedFusing && !MI.isCopy())
7211+
dbgs() << "We failed to fuse operand " << Idx << " in " << MI;
7212+
}
7213+
71687214
MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
71697215
MachineFunction &MF, MachineInstr &MI, unsigned OpNum,
71707216
ArrayRef<MachineOperand> MOs, MachineBasicBlock::iterator InsertPt,
@@ -7292,65 +7338,23 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
72927338
return NewMI;
72937339
}
72947340

7295-
// If the instruction and target operand are commutable, commute the
7296-
// instruction and try again.
72977341
if (AllowCommute) {
7298-
unsigned CommuteOpIdx1 = OpNum, CommuteOpIdx2 = CommuteAnyOperandIndex;
7299-
if (findCommutedOpIndices(MI, CommuteOpIdx1, CommuteOpIdx2)) {
7300-
bool HasDef = MI.getDesc().getNumDefs();
7301-
Register Reg0 = HasDef ? MI.getOperand(0).getReg() : Register();
7302-
Register Reg1 = MI.getOperand(CommuteOpIdx1).getReg();
7303-
Register Reg2 = MI.getOperand(CommuteOpIdx2).getReg();
7304-
bool Tied1 =
7305-
0 == MI.getDesc().getOperandConstraint(CommuteOpIdx1, MCOI::TIED_TO);
7306-
bool Tied2 =
7307-
0 == MI.getDesc().getOperandConstraint(CommuteOpIdx2, MCOI::TIED_TO);
7308-
7309-
// If either of the commutable operands are tied to the destination
7310-
// then we can not commute + fold.
7311-
if ((HasDef && Reg0 == Reg1 && Tied1) ||
7312-
(HasDef && Reg0 == Reg2 && Tied2))
7313-
return nullptr;
7314-
7315-
MachineInstr *CommutedMI =
7316-
commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2);
7317-
if (!CommutedMI) {
7318-
// Unable to commute.
7319-
return nullptr;
7320-
}
7321-
if (CommutedMI != &MI) {
7322-
// New instruction. We can't fold from this.
7323-
CommutedMI->eraseFromParent();
7324-
return nullptr;
7325-
}
7326-
7327-
// Attempt to fold with the commuted version of the instruction.
7328-
NewMI = foldMemoryOperandImpl(MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
7329-
Alignment, /*AllowCommute=*/false);
7330-
if (NewMI)
7331-
return NewMI;
7332-
7333-
// Folding failed again - undo the commute before returning.
7334-
MachineInstr *UncommutedMI =
7335-
commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2);
7336-
if (!UncommutedMI) {
7337-
// Unable to commute.
7338-
return nullptr;
7339-
}
7340-
if (UncommutedMI != &MI) {
7341-
// New instruction. It doesn't need to be kept.
7342-
UncommutedMI->eraseFromParent();
7343-
return nullptr;
7344-
}
7345-
7346-
// Return here to prevent duplicate fuse failure report.
7342+
// If the instruction and target operand are commutable, commute the
7343+
// instruction and try again.
7344+
unsigned CommuteOpIdx2 = commuteOperandsForFold(MI, OpNum);
7345+
if (CommuteOpIdx2 == OpNum) {
7346+
printFailMsgforFold(MI, OpNum);
73477347
return nullptr;
73487348
}
7349+
// Attempt to fold with the commuted version of the instruction.
7350+
NewMI = foldMemoryOperandImpl(MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
7351+
Alignment, /*AllowCommute=*/false);
7352+
if (NewMI)
7353+
return NewMI;
7354+
UndoCommuteForFold(MI, OpNum, CommuteOpIdx2);
73497355
}
73507356

7351-
// No fusion
7352-
if (PrintFailedFusing && !MI.isCopy())
7353-
dbgs() << "We failed to fuse operand " << OpNum << " in " << MI;
7357+
printFailMsgforFold(MI, OpNum);
73547358
return nullptr;
73557359
}
73567360

llvm/lib/Target/X86/X86InstrInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,8 +685,10 @@ class X86InstrInfo final : public X86GenInstrInfo {
685685
Register SrcReg2, int64_t ImmMask, int64_t ImmValue,
686686
const MachineInstr &OI, bool *IsSwapped,
687687
int64_t *ImmDelta) const;
688-
};
689688

689+
unsigned commuteOperandsForFold(MachineInstr &MI, unsigned Idx1) const;
690+
void UndoCommuteForFold(MachineInstr &MI, unsigned Idx1, unsigned Idx2) const;
691+
};
690692
} // namespace llvm
691693

692694
#endif

0 commit comments

Comments
 (0)