1//===-- TargetMacroFusion.td - Target Macro Fusion ---------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file defines the TableGen-based macro fusion classes. 10 11// The target instruction that FusionPredicate will be evaluated on. 12class FusionTarget; 13def first_fusion_target : FusionTarget; 14def second_fusion_target : FusionTarget; 15def both_fusion_target : FusionTarget; 16 17// Base class of FusionPredicate, etc. The avaliable variables are: 18// * const TargetInstrInfo &TII 19// * const TargetSubtargetInfo &STI 20// * const MachineRegisterInfo &MRI 21// * const MachineInstr *FirstMI 22// * const MachineInstr &SecondMI 23class FusionPredicate<FusionTarget target> { 24 FusionTarget Target = target; 25} 26class FirstFusionPredicate: FusionPredicate<first_fusion_target>; 27class SecondFusionPredicate: FusionPredicate<second_fusion_target>; 28class BothFusionPredicate: FusionPredicate<both_fusion_target>; 29 30// FusionPredicate with raw code predicate. 31class FusionPredicateWithCode<code pred> : FusionPredicate<both_fusion_target> { 32 code Predicate = pred; 33} 34 35// FusionPredicate with MCInstPredicate. 36class FusionPredicateWithMCInstPredicate<FusionTarget target, MCInstPredicate pred> 37 : FusionPredicate<target> { 38 MCInstPredicate Predicate = pred; 39} 40class FirstFusionPredicateWithMCInstPredicate<MCInstPredicate pred> 41 : FusionPredicateWithMCInstPredicate<first_fusion_target, pred>; 42class SecondFusionPredicateWithMCInstPredicate<MCInstPredicate pred> 43 : FusionPredicateWithMCInstPredicate<second_fusion_target, pred>; 44// The pred will be applied on both firstMI and secondMI. 45class BothFusionPredicateWithMCInstPredicate<MCInstPredicate pred> 46 : FusionPredicateWithMCInstPredicate<both_fusion_target, pred>; 47 48// Tie firstOpIdx and secondOpIdx. The operand of `FirstMI` at position 49// `firstOpIdx` should be the same as the operand of `SecondMI` at position 50// `secondOpIdx`. 51// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` 52// has commutable operand, then the commutable operand will be checked too. 53class TieReg<int firstOpIdx, int secondOpIdx> : BothFusionPredicate { 54 int FirstOpIdx = firstOpIdx; 55 int SecondOpIdx = secondOpIdx; 56} 57 58// The operand of `SecondMI` at position `firstOpIdx` should be the same as the 59// operand at position `secondOpIdx`. 60// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` 61// has commutable operand, then the commutable operand will be checked too. 62class SameReg<int firstOpIdx, int secondOpIdx> : SecondFusionPredicate { 63 int FirstOpIdx = firstOpIdx; 64 int SecondOpIdx = secondOpIdx; 65} 66 67// A predicate for wildcard. The generated code will be like: 68// ``` 69// if (!FirstMI) 70// return ReturnValue; 71// ``` 72class WildcardPred<bit ret> : FirstFusionPredicate { 73 bit ReturnValue = ret; 74} 75def WildcardFalse : WildcardPred<0>; 76def WildcardTrue : WildcardPred<1>; 77 78// Indicates that the destination register of `FirstMI` should have one use if 79// it is a virtual register. 80class OneUsePred : FirstFusionPredicate; 81def OneUse : OneUsePred; 82 83// Handled by MacroFusionPredicatorEmitter backend. 84// The generated predicator will be like: 85// ``` 86// bool isNAME(const TargetInstrInfo &TII, 87// const TargetSubtargetInfo &STI, 88// const MachineInstr *FirstMI, 89// const MachineInstr &SecondMI) { 90// auto &MRI = SecondMI.getMF()->getRegInfo(); 91// /* Predicates */ 92// return true; 93// } 94// ``` 95// 96// `IsCommutable` means whether we should handle commutable operands. 97class Fusion<string name, string fieldName, string desc, list<FusionPredicate> predicates> 98 : SubtargetFeature<name, fieldName, "true", desc> { 99 list<FusionPredicate> Predicates = predicates; 100 bit IsCommutable = 0; 101} 102 103// The generated predicator will be like: 104// ``` 105// bool isNAME(const TargetInstrInfo &TII, 106// const TargetSubtargetInfo &STI, 107// const MachineInstr *FirstMI, 108// const MachineInstr &SecondMI) { 109// auto &MRI = SecondMI.getMF()->getRegInfo(); 110// /* Prolog */ 111// /* Predicate for `SecondMI` */ 112// /* Wildcard */ 113// /* Predicate for `FirstMI` */ 114// /* Check same registers */ 115// /* Check One Use */ 116// /* Tie registers */ 117// /* Epilog */ 118// return true; 119// } 120// ``` 121class SimpleFusion<string name, string fieldName, string desc, 122 MCInstPredicate firstPred, MCInstPredicate secondPred, 123 list<FusionPredicate> prolog = [], 124 list<FusionPredicate> epilog = []> 125 : Fusion<name, fieldName, desc, 126 !listconcat( 127 prolog, 128 [ 129 SecondFusionPredicateWithMCInstPredicate<secondPred>, 130 WildcardTrue, 131 FirstFusionPredicateWithMCInstPredicate<firstPred>, 132 SameReg<0, 1>, 133 OneUse, 134 TieReg<0, 1>, 135 ], 136 epilog)>; 137 138class 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} 154