1// RUN: llvm-tblgen -gen-macro-fusion-pred -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-PREDICATOR 2// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-SUBTARGET 3 4include "llvm/Target/Target.td" 5 6def TestInstrInfo : InstrInfo { } 7def TestAsmWriter : AsmWriter { 8 int PassSubtarget = 1; 9} 10 11def Test : Target { 12 let InstructionSet = TestInstrInfo; 13 let AssemblyWriters = [TestAsmWriter]; 14} 15 16let Namespace = "Test" in { 17 foreach i = 0-32 in { 18 def X#i : Register<"x"#i>; 19 } 20 21 def GPR : RegisterClass<"GPR", [i32], 32, (sequence "X%u", 0, 32)>; 22 23 class TestInst<int Opc> : Instruction { 24 field bits<32> Inst; 25 field bits<32> SoftFail = 0; 26 let Size = 4; 27 let Inst = Opc; 28 let OutOperandList = (outs); 29 let InOperandList = (ins); 30 let AsmString = NAME; 31 } 32} 33 34def Inst0 : TestInst<0>; 35def Inst1 : TestInst<1>; 36let isCommutable = true in 37def Inst2 : TestInst<2>; 38 39def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate<CheckRegOperand<0, X0>>; 40def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate", 41 "Test BothFusionPredicate", 42 [BothFusionPredicate]>; 43 44def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion", 45 CheckOpcode<[Inst0]>, 46 CheckAll<[ 47 CheckOpcode<[Inst1]>, 48 CheckRegOperand<0, X0> 49 ]>>; 50 51let IsCommutable = 1 in 52def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommutableFusion", 53 "Test Commutable Fusion", 54 CheckOpcode<[Inst0]>, 55 CheckAll<[ 56 CheckOpcode<[Inst1]>, 57 CheckRegOperand<0, X0> 58 ]>>; 59 60def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion", 61 "Test SingleFusion", 62 Inst0, Inst2, 63 secondInstPred=CheckRegOperand<0, X0>>; 64 65// CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL 66// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL 67// CHECK-PREDICATOR-EMPTY: 68// CHECK-PREDICATOR-NEXT: namespace llvm { 69// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); 70// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); 71// 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 &); 73// CHECK-PREDICATOR-NEXT: } // end namespace llvm 74// CHECK-PREDICATOR-EMPTY: 75// CHECK-PREDICATOR-NEXT: #endif 76 77// CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_IMPL 78// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_IMPL 79// CHECK-PREDICATOR-EMPTY: 80// CHECK-PREDICATOR-NEXT: namespace llvm { 81// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate( 82// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII, 83// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI, 84// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI, 85// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) { 86// CHECK-PREDICATOR-NEXT: {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo(); 87// CHECK-PREDICATOR-NEXT: { 88// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI; 89// CHECK-PREDICATOR-NEXT: if (MI->getOperand(0).getReg() != Test::X0) 90// CHECK-PREDICATOR-NEXT: return false; 91// CHECK-PREDICATOR-NEXT: } 92// CHECK-PREDICATOR-NEXT: { 93// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI; 94// CHECK-PREDICATOR-NEXT: if (MI->getOperand(0).getReg() != Test::X0) 95// CHECK-PREDICATOR-NEXT: return false; 96// CHECK-PREDICATOR-NEXT: } 97// CHECK-PREDICATOR-NEXT: return true; 98// CHECK-PREDICATOR-NEXT: } 99// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion( 100// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII, 101// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI, 102// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI, 103// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) { 104// CHECK-PREDICATOR-NEXT: {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo(); 105// CHECK-PREDICATOR-NEXT: { 106// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI; 107// CHECK-PREDICATOR-NEXT: if (!( 108// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst1 ) 109// CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0 110// CHECK-PREDICATOR-NEXT: )) 111// CHECK-PREDICATOR-NEXT: return false; 112// CHECK-PREDICATOR-NEXT: } 113// CHECK-PREDICATOR-NEXT: if (!FirstMI) 114// CHECK-PREDICATOR-NEXT: return true; 115// CHECK-PREDICATOR-NEXT: { 116// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI; 117// CHECK-PREDICATOR-NEXT: if (( MI->getOpcode() != Test::Inst0 )) 118// CHECK-PREDICATOR-NEXT: return false; 119// CHECK-PREDICATOR-NEXT: } 120// CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) { 121// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) { 122// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) 123// CHECK-PREDICATOR-NEXT: return false; 124// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; 125// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) 126// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) 127// CHECK-PREDICATOR-NEXT: return false; 128// CHECK-PREDICATOR-NEXT: } 129// CHECK-PREDICATOR-NEXT: } 130// CHECK-PREDICATOR-NEXT: { 131// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg(); 132// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest)) 133// CHECK-PREDICATOR-NEXT: return false; 134// CHECK-PREDICATOR-NEXT: } 135// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() && 136// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() && 137// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) { 138// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) 139// CHECK-PREDICATOR-NEXT: return false; 140// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; 141// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) 142// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) 143// CHECK-PREDICATOR-NEXT: return false; 144// CHECK-PREDICATOR-NEXT: } 145// CHECK-PREDICATOR-NEXT: return true; 146// CHECK-PREDICATOR-NEXT: } 147// CHECK-PREDICATOR-NEXT: bool isTestFusion( 148// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII, 149// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI, 150// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI, 151// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) { 152// CHECK-PREDICATOR-NEXT: {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo(); 153// CHECK-PREDICATOR-NEXT: { 154// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI; 155// CHECK-PREDICATOR-NEXT: if (!( 156// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst1 ) 157// CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0 158// CHECK-PREDICATOR-NEXT: )) 159// CHECK-PREDICATOR-NEXT: return false; 160// CHECK-PREDICATOR-NEXT: } 161// CHECK-PREDICATOR-NEXT: if (!FirstMI) 162// CHECK-PREDICATOR-NEXT: return true; 163// CHECK-PREDICATOR-NEXT: { 164// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI; 165// CHECK-PREDICATOR-NEXT: if (( MI->getOpcode() != Test::Inst0 )) 166// CHECK-PREDICATOR-NEXT: return false; 167// CHECK-PREDICATOR-NEXT: } 168// CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) { 169// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) 170// CHECK-PREDICATOR-NEXT: return false; 171// CHECK-PREDICATOR-NEXT: } 172// CHECK-PREDICATOR-NEXT: { 173// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg(); 174// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest)) 175// CHECK-PREDICATOR-NEXT: return false; 176// CHECK-PREDICATOR-NEXT: } 177// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() && 178// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() && 179// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) 180// CHECK-PREDICATOR-NEXT: return false; 181// CHECK-PREDICATOR-NEXT: return true; 182// 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: {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} 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: } 234// CHECK-PREDICATOR-NEXT: } // end namespace llvm 235// CHECK-PREDICATOR-EMPTY: 236// CHECK-PREDICATOR-NEXT: #endif 237 238// Check that we have generated target subfeature. 239// CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate 240// CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion 241// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion 242// CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion 243 244// Check that we have generated `getMacroFusions()` function. 245// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override; 246 247// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> TestGenSubtargetInfo::getMacroFusions() const { 248// CHECK-SUBTARGET-NEXT: std::vector<MacroFusionPredTy> Fusions; 249// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate); 250// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion); 251// 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); 253// CHECK-SUBTARGET-NEXT: return Fusions; 254// CHECK-SUBTARGET-NEXT: } 255