Skip to content

[MacroFusion] Add SingleFusion that accepts a single instruction pair #85750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions llvm/include/llvm/Target/TargetMacroFusion.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,20 @@ class SimpleFusion<string name, string fieldName, string desc,
TieReg<0, 1>,
],
epilog)>;

class SingleFusion<string name, string fieldName, string desc,
Instruction firstInst, Instruction secondInst,
MCInstPredicate firstInstPred = TruePred,
MCInstPredicate secondInstPred = TruePred,
list<FusionPredicate> prolog = [],
list<FusionPredicate> epilog = []>
: SimpleFusion<name, fieldName, desc,
CheckAll<!listconcat(
[CheckOpcode<[firstInst]>],
[firstInstPred])>,
CheckAll<!listconcat(
[CheckOpcode<[secondInst]>],
[secondInstPred])>,
prolog, epilog> {
let IsCommutable = secondInst.isCommutable;
}
61 changes: 61 additions & 0 deletions llvm/test/TableGen/MacroFusion.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<CheckRegOperand<0, X0>>;
def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate",
Expand All @@ -55,13 +57,19 @@ 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:
// CHECK-PREDICATOR-NEXT: namespace llvm {
// 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
Expand Down Expand Up @@ -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
Expand All @@ -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<MacroFusionPredTy> getMacroFusions() const override;
Expand All @@ -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: }