[llvm] 2960656 - [X86][NFC] Extract code for commute in foldMemoryOperandImpl into functions
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 30 08:09:43 PST 2024
Author: Shengchen Kan
Date: 2024-01-31T00:09:08+08:00
New Revision: 2960656eb909b5361ce2c3f641ee341769076ab7
URL: https://github.com/llvm/llvm-project/commit/2960656eb909b5361ce2c3f641ee341769076ab7
DIFF: https://github.com/llvm/llvm-project/commit/2960656eb909b5361ce2c3f641ee341769076ab7.diff
LOG: [X86][NFC] Extract code for commute in foldMemoryOperandImpl into functions
To share code for folding broadcast in #79761
Added:
Modified:
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86InstrInfo.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 99dba8d41ac88..eceabe18154c8 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -7165,6 +7165,52 @@ static bool shouldPreventUndefRegUpdateMemFold(MachineFunction &MF,
return VRegDef && VRegDef->isImplicitDef();
}
+unsigned X86InstrInfo::commuteOperandsForFold(MachineInstr &MI,
+ unsigned Idx1) const {
+ unsigned Idx2 = CommuteAnyOperandIndex;
+ if (!findCommutedOpIndices(MI, Idx1, Idx2))
+ return Idx1;
+
+ bool HasDef = MI.getDesc().getNumDefs();
+ Register Reg0 = HasDef ? MI.getOperand(0).getReg() : Register();
+ Register Reg1 = MI.getOperand(Idx1).getReg();
+ Register Reg2 = MI.getOperand(Idx2).getReg();
+ bool Tied1 = 0 == MI.getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO);
+ bool Tied2 = 0 == MI.getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO);
+
+ // If either of the commutable operands are tied to the destination
+ // then we can not commute + fold.
+ if ((HasDef && Reg0 == Reg1 && Tied1) || (HasDef && Reg0 == Reg2 && Tied2))
+ return Idx1;
+
+ MachineInstr *CommutedMI = commuteInstruction(MI, false, Idx1, Idx2);
+ if (!CommutedMI) {
+ // Unable to commute.
+ return Idx1;
+ }
+ if (CommutedMI != &MI) {
+ // New instruction. We can't fold from this.
+ CommutedMI->eraseFromParent();
+ return Idx1;
+ }
+
+ return Idx2;
+}
+
+void X86InstrInfo::UndoCommuteForFold(MachineInstr &MI, unsigned Idx1,
+ unsigned Idx2) const {
+ // Folding failed again - undo the commute before returning.
+ MachineInstr *UncommutedMI = commuteInstruction(MI, false, Idx1, Idx2);
+ // New instruction. It doesn't need to be kept.
+ if (UncommutedMI && UncommutedMI != &MI)
+ UncommutedMI->eraseFromParent();
+}
+
+static void printFailMsgforFold(const MachineInstr &MI, unsigned Idx) {
+ if (PrintFailedFusing && !MI.isCopy())
+ dbgs() << "We failed to fuse operand " << Idx << " in " << MI;
+}
+
MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
MachineFunction &MF, MachineInstr &MI, unsigned OpNum,
ArrayRef<MachineOperand> MOs, MachineBasicBlock::iterator InsertPt,
@@ -7292,65 +7338,23 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
return NewMI;
}
- // If the instruction and target operand are commutable, commute the
- // instruction and try again.
if (AllowCommute) {
- unsigned CommuteOpIdx1 = OpNum, CommuteOpIdx2 = CommuteAnyOperandIndex;
- if (findCommutedOpIndices(MI, CommuteOpIdx1, CommuteOpIdx2)) {
- bool HasDef = MI.getDesc().getNumDefs();
- Register Reg0 = HasDef ? MI.getOperand(0).getReg() : Register();
- Register Reg1 = MI.getOperand(CommuteOpIdx1).getReg();
- Register Reg2 = MI.getOperand(CommuteOpIdx2).getReg();
- bool Tied1 =
- 0 == MI.getDesc().getOperandConstraint(CommuteOpIdx1, MCOI::TIED_TO);
- bool Tied2 =
- 0 == MI.getDesc().getOperandConstraint(CommuteOpIdx2, MCOI::TIED_TO);
-
- // If either of the commutable operands are tied to the destination
- // then we can not commute + fold.
- if ((HasDef && Reg0 == Reg1 && Tied1) ||
- (HasDef && Reg0 == Reg2 && Tied2))
- return nullptr;
-
- MachineInstr *CommutedMI =
- commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2);
- if (!CommutedMI) {
- // Unable to commute.
- return nullptr;
- }
- if (CommutedMI != &MI) {
- // New instruction. We can't fold from this.
- CommutedMI->eraseFromParent();
- return nullptr;
- }
-
- // Attempt to fold with the commuted version of the instruction.
- NewMI = foldMemoryOperandImpl(MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
- Alignment, /*AllowCommute=*/false);
- if (NewMI)
- return NewMI;
-
- // Folding failed again - undo the commute before returning.
- MachineInstr *UncommutedMI =
- commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2);
- if (!UncommutedMI) {
- // Unable to commute.
- return nullptr;
- }
- if (UncommutedMI != &MI) {
- // New instruction. It doesn't need to be kept.
- UncommutedMI->eraseFromParent();
- return nullptr;
- }
-
- // Return here to prevent duplicate fuse failure report.
+ // If the instruction and target operand are commutable, commute the
+ // instruction and try again.
+ unsigned CommuteOpIdx2 = commuteOperandsForFold(MI, OpNum);
+ if (CommuteOpIdx2 == OpNum) {
+ printFailMsgforFold(MI, OpNum);
return nullptr;
}
+ // Attempt to fold with the commuted version of the instruction.
+ NewMI = foldMemoryOperandImpl(MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
+ Alignment, /*AllowCommute=*/false);
+ if (NewMI)
+ return NewMI;
+ UndoCommuteForFold(MI, OpNum, CommuteOpIdx2);
}
- // No fusion
- if (PrintFailedFusing && !MI.isCopy())
- dbgs() << "We failed to fuse operand " << OpNum << " in " << MI;
+ printFailMsgforFold(MI, OpNum);
return nullptr;
}
diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h
index 0cb6905065610..8512635eadaed 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.h
+++ b/llvm/lib/Target/X86/X86InstrInfo.h
@@ -685,8 +685,10 @@ class X86InstrInfo final : public X86GenInstrInfo {
Register SrcReg2, int64_t ImmMask, int64_t ImmValue,
const MachineInstr &OI, bool *IsSwapped,
int64_t *ImmDelta) const;
-};
+ unsigned commuteOperandsForFold(MachineInstr &MI, unsigned Idx1) const;
+ void UndoCommuteForFold(MachineInstr &MI, unsigned Idx1, unsigned Idx2) const;
+};
} // namespace llvm
#endif
More information about the llvm-commits
mailing list