From 4a6bc9fd14bd79f1edf5b651b43bd9bda9b90991 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Tue, 19 Mar 2024 15:46:56 +0800 Subject: [PATCH] [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: https://github.com/llvm/llvm-project/pull/85750 --- llvm/include/llvm/Target/TargetMacroFusion.td | 17 ++++++ llvm/test/TableGen/MacroFusion.td | 61 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/llvm/include/llvm/Target/TargetMacroFusion.td b/llvm/include/llvm/Target/TargetMacroFusion.td index 766ba0afbf99c1..0306794ef50d1f 100644 --- a/llvm/include/llvm/Target/TargetMacroFusion.td +++ b/llvm/include/llvm/Target/TargetMacroFusion.td @@ -134,3 +134,20 @@ class SimpleFusion, ], epilog)>; + +class SingleFusion prolog = [], + list epilog = []> + : SimpleFusion], + [firstInstPred])>, + CheckAll], + [secondInstPred])>, + prolog, epilog> { + let IsCommutable = secondInst.isCommutable; +} diff --git a/llvm/test/TableGen/MacroFusion.td b/llvm/test/TableGen/MacroFusion.td index f8d375931ab866..b54b0506c56359 100644 --- a/llvm/test/TableGen/MacroFusion.td +++ b/llvm/test/TableGen/MacroFusion.td @@ -33,6 +33,8 @@ let Namespace = "Test" in { def Inst0 : TestInst<0>; def Inst1 : TestInst<1>; +let isCommutable = true in +def Inst2 : TestInst<2>; def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate>; def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate", @@ -55,6 +57,11 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta CheckRegOperand<0, X0> ]>>; +def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion", + "Test SingleFusion", + Inst0, Inst2, + secondInstPred=CheckRegOperand<0, X0>>; + // CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL // CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL // CHECK-PREDICATOR-EMPTY: @@ -62,6 +69,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); +// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: } // end namespace llvm // CHECK-PREDICATOR-EMPTY: // CHECK-PREDICATOR-NEXT: #endif @@ -172,6 +180,57 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-PREDICATOR-NEXT: return false; // CHECK-PREDICATOR-NEXT: return true; // CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion( +// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII, +// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI, +// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI, +// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) { +// CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo(); +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI; +// CHECK-PREDICATOR-NEXT: if (!( +// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst2 ) +// CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0 +// CHECK-PREDICATOR-NEXT: )) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!FirstMI) +// CHECK-PREDICATOR-NEXT: return true; +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI; +// CHECK-PREDICATOR-NEXT: if (!( +// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst0 ) +// CHECK-PREDICATOR-NEXT: && true +// CHECK-PREDICATOR-NEXT: )) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) { +// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) { +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; +// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) +// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg(); +// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest)) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() && +// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() && +// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) { +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; +// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) +// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: return true; +// CHECK-PREDICATOR-NEXT: } // CHECK-PREDICATOR-NEXT: } // end namespace llvm // CHECK-PREDICATOR-EMPTY: // CHECK-PREDICATOR-NEXT: #endif @@ -180,6 +239,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate // CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion // CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion +// CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion // Check that we have generated `getMacroFusions()` function. // CHECK-SUBTARGET: std::vector getMacroFusions() const override; @@ -189,5 +249,6 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate); // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion); // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion); +// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestSingleFusion)) Fusions.push_back(llvm::isTestSingleFusion); // CHECK-SUBTARGET-NEXT: return Fusions; // CHECK-SUBTARGET-NEXT: }