Skip to content

Commit 4a6bc9f

Browse files
committed
[MacroFusion] Add SingleFusion that accepts a single instruction pair
We add a common class `SingleFusion` that accepts a single instruction pair to simplify fusion definitions. Pull Request: #85750
1 parent d712c5e commit 4a6bc9f

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

llvm/include/llvm/Target/TargetMacroFusion.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,20 @@ class SimpleFusion<string name, string fieldName, string desc,
134134
TieReg<0, 1>,
135135
],
136136
epilog)>;
137+
138+
class SingleFusion<string name, string fieldName, string desc,
139+
Instruction firstInst, Instruction secondInst,
140+
MCInstPredicate firstInstPred = TruePred,
141+
MCInstPredicate secondInstPred = TruePred,
142+
list<FusionPredicate> prolog = [],
143+
list<FusionPredicate> epilog = []>
144+
: SimpleFusion<name, fieldName, desc,
145+
CheckAll<!listconcat(
146+
[CheckOpcode<[firstInst]>],
147+
[firstInstPred])>,
148+
CheckAll<!listconcat(
149+
[CheckOpcode<[secondInst]>],
150+
[secondInstPred])>,
151+
prolog, epilog> {
152+
let IsCommutable = secondInst.isCommutable;
153+
}

llvm/test/TableGen/MacroFusion.td

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ let Namespace = "Test" in {
3333

3434
def Inst0 : TestInst<0>;
3535
def Inst1 : TestInst<1>;
36+
let isCommutable = true in
37+
def Inst2 : TestInst<2>;
3638

3739
def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate<CheckRegOperand<0, X0>>;
3840
def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate",
@@ -55,13 +57,19 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
5557
CheckRegOperand<0, X0>
5658
]>>;
5759

60+
def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
61+
"Test SingleFusion",
62+
Inst0, Inst2,
63+
secondInstPred=CheckRegOperand<0, X0>>;
64+
5865
// CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL
5966
// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL
6067
// CHECK-PREDICATOR-EMPTY:
6168
// CHECK-PREDICATOR-NEXT: namespace llvm {
6269
// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6370
// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6471
// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
72+
// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
6573
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
6674
// CHECK-PREDICATOR-EMPTY:
6775
// CHECK-PREDICATOR-NEXT: #endif
@@ -172,6 +180,57 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
172180
// CHECK-PREDICATOR-NEXT: return false;
173181
// CHECK-PREDICATOR-NEXT: return true;
174182
// CHECK-PREDICATOR-NEXT: }
183+
// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(
184+
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
185+
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
186+
// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI,
187+
// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) {
188+
// CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo();
189+
// CHECK-PREDICATOR-NEXT: {
190+
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI;
191+
// CHECK-PREDICATOR-NEXT: if (!(
192+
// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst2 )
193+
// CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0
194+
// CHECK-PREDICATOR-NEXT: ))
195+
// CHECK-PREDICATOR-NEXT: return false;
196+
// CHECK-PREDICATOR-NEXT: }
197+
// CHECK-PREDICATOR-NEXT: if (!FirstMI)
198+
// CHECK-PREDICATOR-NEXT: return true;
199+
// CHECK-PREDICATOR-NEXT: {
200+
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI;
201+
// CHECK-PREDICATOR-NEXT: if (!(
202+
// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst0 )
203+
// CHECK-PREDICATOR-NEXT: && true
204+
// CHECK-PREDICATOR-NEXT: ))
205+
// CHECK-PREDICATOR-NEXT: return false;
206+
// CHECK-PREDICATOR-NEXT: }
207+
// CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) {
208+
// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
209+
// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable())
210+
// CHECK-PREDICATOR-NEXT: return false;
211+
// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
212+
// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
213+
// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
214+
// CHECK-PREDICATOR-NEXT: return false;
215+
// CHECK-PREDICATOR-NEXT: }
216+
// CHECK-PREDICATOR-NEXT: }
217+
// CHECK-PREDICATOR-NEXT: {
218+
// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg();
219+
// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
220+
// CHECK-PREDICATOR-NEXT: return false;
221+
// CHECK-PREDICATOR-NEXT: }
222+
// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() &&
223+
// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() &&
224+
// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
225+
// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable())
226+
// CHECK-PREDICATOR-NEXT: return false;
227+
// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
228+
// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
229+
// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
230+
// CHECK-PREDICATOR-NEXT: return false;
231+
// CHECK-PREDICATOR-NEXT: }
232+
// CHECK-PREDICATOR-NEXT: return true;
233+
// CHECK-PREDICATOR-NEXT: }
175234
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
176235
// CHECK-PREDICATOR-EMPTY:
177236
// CHECK-PREDICATOR-NEXT: #endif
@@ -180,6 +239,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
180239
// CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate
181240
// CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion
182241
// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion
242+
// CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion
183243

184244
// Check that we have generated `getMacroFusions()` function.
185245
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override;
@@ -189,5 +249,6 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta
189249
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate);
190250
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion);
191251
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
252+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestSingleFusion)) Fusions.push_back(llvm::isTestSingleFusion);
192253
// CHECK-SUBTARGET-NEXT: return Fusions;
193254
// CHECK-SUBTARGET-NEXT: }

0 commit comments

Comments
 (0)