Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 1 | //===- TargetInstrPredicate.td - ---------------------------*- tablegen -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 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 |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 9 | // This file defines class MCInstPredicate and its subclasses. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 10 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 11 | // MCInstPredicate definitions are used by target scheduling models to describe |
| 12 | // constraints on instructions. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 13 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 14 | // Here is an example of an MCInstPredicate definition in tablegen: |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 15 | // |
| 16 | // def MCInstPredicateExample : CheckAll<[ |
| 17 | // CheckOpcode<[BLR]>, |
| 18 | // CheckIsRegOperand<0>, |
| 19 | // CheckNot<CheckRegOperand<0, LR>>]>; |
| 20 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 21 | // The syntax for MCInstPredicate is declarative, and predicate definitions can |
| 22 | // be composed together in order to generate more complex constraints. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 23 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 24 | // The `CheckAll` from the example defines a composition of three different |
| 25 | // predicates. Definition `MCInstPredicateExample` identifies instructions |
| 26 | // whose opcode is BLR, and whose first operand is a register different from |
| 27 | // register `LR`. |
| 28 | // |
| 29 | // Every MCInstPredicate class has a well-known semantic in tablegen. For |
| 30 | // example, `CheckOpcode` is a special type of predicate used to describe a |
| 31 | // constraint on the value of an instruction opcode. |
| 32 | // |
| 33 | // MCInstPredicate definitions are typically used by scheduling models to |
| 34 | // construct MCSchedPredicate definitions (see the definition of class |
| 35 | // MCSchedPredicate in llvm/Target/TargetSchedule.td). |
| 36 | // In particular, an MCSchedPredicate can be used instead of a SchedPredicate |
| 37 | // when defining the set of SchedReadVariant and SchedWriteVariant of a |
| 38 | // processor scheduling model. |
| 39 | // |
| 40 | // The `MCInstPredicateExample` definition above is equivalent (and therefore |
| 41 | // could replace) the following definition from a previous ExynosM3 model (see |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 42 | // AArch64SchedExynosM3.td): |
| 43 | // |
| 44 | // def M3BranchLinkFastPred : SchedPredicate<[{ |
| 45 | // MI->getOpcode() == AArch64::BLR && |
| 46 | // MI->getOperand(0).isReg() && |
| 47 | // MI->getOperand(0).getReg() != AArch64::LR}]>; |
| 48 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 49 | // The main advantage of using MCInstPredicate instead of SchedPredicate is |
| 50 | // portability: users don't need to specify predicates in C++. As a consequence |
| 51 | // of this, MCInstPredicate definitions are not bound to a particular |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 52 | // representation (i.e. MachineInstr vs MCInst). |
| 53 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 54 | // Tablegen backends know how to expand MCInstPredicate definitions into actual |
| 55 | // C++ code that works on MachineInstr (and/or MCInst). |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 56 | // |
| 57 | // Instances of class PredicateExpander (see utils/Tablegen/PredicateExpander.h) |
| 58 | // know how to expand a predicate. For each MCInstPredicate class, there must be |
| 59 | // an "expand" method available in the PredicateExpander interface. |
| 60 | // |
| 61 | // For example, a `CheckOpcode` predicate is expanded using method |
| 62 | // `PredicateExpander::expandCheckOpcode()`. |
| 63 | // |
| 64 | // New MCInstPredicate classes must be added to this file. For each new class |
| 65 | // XYZ, an "expandXYZ" method must be added to the PredicateExpander. |
| 66 | // |
| 67 | //===----------------------------------------------------------------------===// |
| 68 | |
| 69 | // Forward declarations. |
| 70 | class Instruction; |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 71 | class SchedMachineModel; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 72 | |
| 73 | // A generic machine instruction predicate. |
| 74 | class MCInstPredicate; |
| 75 | |
| 76 | class MCTrue : MCInstPredicate; // A predicate that always evaluates to True. |
| 77 | class MCFalse : MCInstPredicate; // A predicate that always evaluates to False. |
| 78 | def TruePred : MCTrue; |
| 79 | def FalsePred : MCFalse; |
| 80 | |
| 81 | // A predicate used to negate the outcome of another predicate. |
| 82 | // It allows to easily express "set difference" operations. For example, it |
| 83 | // makes it easy to describe a check that tests if an opcode is not part of a |
| 84 | // set of opcodes. |
| 85 | class CheckNot<MCInstPredicate P> : MCInstPredicate { |
| 86 | MCInstPredicate Pred = P; |
| 87 | } |
| 88 | |
| 89 | // This class is used as a building block to define predicates on instruction |
| 90 | // operands. It is used to reference a specific machine operand. |
| 91 | class MCOperandPredicate<int Index> : MCInstPredicate { |
| 92 | int OpIndex = Index; |
| 93 | } |
| 94 | |
| 95 | // Return true if machine operand at position `Index` is a register operand. |
| 96 | class CheckIsRegOperand<int Index> : MCOperandPredicate<Index>; |
| 97 | |
| 98 | // Return true if machine operand at position `Index` is an immediate operand. |
| 99 | class CheckIsImmOperand<int Index> : MCOperandPredicate<Index>; |
| 100 | |
| 101 | // Check if machine operands at index `First` and index `Second` both reference |
| 102 | // the same register. |
| 103 | class CheckSameRegOperand<int First, int Second> : MCInstPredicate { |
| 104 | int FirstIndex = First; |
| 105 | int SecondIndex = Second; |
| 106 | } |
| 107 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 108 | // Base class for checks on register/immediate operands. |
| 109 | // It allows users to define checks like: |
| 110 | // MyFunction(MI->getOperand(Index).getImm()) == Val; |
| 111 | // |
| 112 | // In the example above, `MyFunction` is a function that takes as input an |
| 113 | // immediate operand value, and returns another value. Field `FunctionMapper` is |
| 114 | // the name of the function to call on the operand value. |
| 115 | class CheckOperandBase<int Index, string Fn = ""> : MCOperandPredicate<Index> { |
| 116 | string FunctionMapper = Fn; |
| 117 | } |
| 118 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 119 | // Check that the machine register operand at position `Index` references |
| 120 | // register R. This predicate assumes that we already checked that the machine |
| 121 | // operand at position `Index` is a register operand. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 122 | class CheckRegOperand<int Index, Register R> : CheckOperandBase<Index> { |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 123 | Register Reg = R; |
| 124 | } |
| 125 | |
| 126 | // Check if register operand at index `Index` is the invalid register. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 127 | class CheckInvalidRegOperand<int Index> : CheckOperandBase<Index>; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 128 | |
| 129 | // Check that the operand at position `Index` is immediate `Imm`. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 130 | // If field `FunctionMapper` is a non-empty string, then function |
| 131 | // `FunctionMapper` is applied to the operand value, and the return value is then |
| 132 | // compared against `Imm`. |
| 133 | class CheckImmOperand<int Index, int Imm> : CheckOperandBase<Index> { |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 134 | int ImmVal = Imm; |
| 135 | } |
| 136 | |
| 137 | // Similar to CheckImmOperand, however the immediate is not a literal number. |
| 138 | // This is useful when we want to compare the value of an operand against an |
| 139 | // enum value, and we know the actual integer value of that enum. |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 140 | class CheckImmOperand_s<int Index, string Value> : CheckOperandBase<Index> { |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 141 | string ImmVal = Value; |
| 142 | } |
| 143 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 144 | // Expands to a call to `FunctionMapper` if field `FunctionMapper` is set. |
| 145 | // Otherwise, it expands to a CheckNot<CheckInvalidRegOperand<Index>>. |
| 146 | class CheckRegOperandSimple<int Index> : CheckOperandBase<Index>; |
| 147 | |
| 148 | // Expands to a call to `FunctionMapper` if field `FunctionMapper` is set. |
| 149 | // Otherwise, it simply evaluates to TruePred. |
| 150 | class CheckImmOperandSimple<int Index> : CheckOperandBase<Index>; |
| 151 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 152 | // Check that the operand at position `Index` is immediate value zero. |
| 153 | class CheckZeroOperand<int Index> : CheckImmOperand<Index, 0>; |
| 154 | |
| 155 | // Check that the instruction has exactly `Num` operands. |
| 156 | class CheckNumOperands<int Num> : MCInstPredicate { |
| 157 | int NumOps = Num; |
| 158 | } |
| 159 | |
| 160 | // Check that the instruction opcode is one of the opcodes in set `Opcodes`. |
| 161 | // This is a simple set membership query. The easier way to check if an opcode |
| 162 | // is not a member of the set is by using a `CheckNot<CheckOpcode<[...]>>` |
| 163 | // sequence. |
| 164 | class CheckOpcode<list<Instruction> Opcodes> : MCInstPredicate { |
| 165 | list<Instruction> ValidOpcodes = Opcodes; |
| 166 | } |
| 167 | |
| 168 | // Check that the instruction opcode is a pseudo opcode member of the set |
| 169 | // `Opcodes`. This check is always expanded to "false" if we are generating |
| 170 | // code for MCInst. |
| 171 | class CheckPseudo<list<Instruction> Opcodes> : CheckOpcode<Opcodes>; |
| 172 | |
| 173 | // A non-portable predicate. Only to use as a last resort when a block of code |
| 174 | // cannot possibly be converted in a declarative way using other MCInstPredicate |
| 175 | // classes. This check is always expanded to "false" when generating code for |
| 176 | // MCInst. |
| 177 | class CheckNonPortable<string Code> : MCInstPredicate { |
| 178 | string CodeBlock = Code; |
| 179 | } |
| 180 | |
| 181 | // A sequence of predicates. It is used as the base class for CheckAll, and |
| 182 | // CheckAny. It allows to describe compositions of predicates. |
| 183 | class CheckPredicateSequence<list<MCInstPredicate> Preds> : MCInstPredicate { |
| 184 | list<MCInstPredicate> Predicates = Preds; |
| 185 | } |
| 186 | |
| 187 | // Check that all of the predicates in `Preds` evaluate to true. |
| 188 | class CheckAll<list<MCInstPredicate> Sequence> |
| 189 | : CheckPredicateSequence<Sequence>; |
| 190 | |
| 191 | // Check that at least one of the predicates in `Preds` evaluates to true. |
| 192 | class CheckAny<list<MCInstPredicate> Sequence> |
| 193 | : CheckPredicateSequence<Sequence>; |
| 194 | |
| 195 | |
| 196 | // Used to expand the body of a function predicate. See the definition of |
| 197 | // TIIPredicate below. |
| 198 | class MCStatement; |
| 199 | |
| 200 | // Expands to a return statement. The return expression is a boolean expression |
| 201 | // described by a MCInstPredicate. |
| 202 | class MCReturnStatement<MCInstPredicate predicate> : MCStatement { |
| 203 | MCInstPredicate Pred = predicate; |
| 204 | } |
| 205 | |
| 206 | // Used to automatically construct cases of a switch statement where the switch |
| 207 | // variable is an instruction opcode. There is a 'case' for every opcode in the |
| 208 | // `opcodes` list, and each case is associated with MCStatement `caseStmt`. |
| 209 | class MCOpcodeSwitchCase<list<Instruction> opcodes, MCStatement caseStmt> { |
| 210 | list<Instruction> Opcodes = opcodes; |
| 211 | MCStatement CaseStmt = caseStmt; |
| 212 | } |
| 213 | |
| 214 | // Expands to a switch statement. The switch variable is an instruction opcode. |
| 215 | // The auto-generated switch is populated by a number of cases based on the |
| 216 | // `cases` list in input. A default case is automatically generated, and it |
| 217 | // evaluates to `default`. |
| 218 | class MCOpcodeSwitchStatement<list<MCOpcodeSwitchCase> cases, |
| 219 | MCStatement default> : MCStatement { |
| 220 | list<MCOpcodeSwitchCase> Cases = cases; |
| 221 | MCStatement DefaultCase = default; |
| 222 | } |
| 223 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 224 | // Base class for function predicates. |
| 225 | class FunctionPredicateBase<string name, MCStatement body> { |
| 226 | string FunctionName = name; |
| 227 | MCStatement Body = body; |
| 228 | } |
| 229 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 230 | // Check that a call to method `Name` in class "XXXInstrInfo" (where XXX is |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 231 | // the name of a target) returns true. |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 232 | // |
| 233 | // TIIPredicate definitions are used to model calls to the target-specific |
| 234 | // InstrInfo. A TIIPredicate is treated specially by the InstrInfoEmitter |
| 235 | // tablegen backend, which will use it to automatically generate a definition in |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 236 | // the target specific `InstrInfo` class. |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 237 | // |
| 238 | // There cannot be multiple TIIPredicate definitions with the same name for the |
| 239 | // same target. |
| 240 | class TIIPredicate<string Name, MCStatement body> |
| 241 | : FunctionPredicateBase<Name, body>, MCInstPredicate; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 242 | |
| 243 | // A function predicate that takes as input a machine instruction, and returns |
| 244 | // a boolean value. |
| 245 | // |
| 246 | // This predicate is expanded into a function call by the PredicateExpander. |
| 247 | // In particular, the PredicateExpander would either expand this predicate into |
| 248 | // a call to `MCInstFn`, or into a call to`MachineInstrFn` depending on whether |
| 249 | // it is lowering predicates for MCInst or MachineInstr. |
| 250 | // |
| 251 | // In this context, `MCInstFn` and `MachineInstrFn` are both function names. |
| 252 | class CheckFunctionPredicate<string MCInstFn, string MachineInstrFn> : MCInstPredicate { |
| 253 | string MCInstFnName = MCInstFn; |
| 254 | string MachineInstrFnName = MachineInstrFn; |
| 255 | } |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 256 | |
| 257 | // Used to classify machine instructions based on a machine instruction |
| 258 | // predicate. |
| 259 | // |
| 260 | // Let IC be an InstructionEquivalenceClass definition, and MI a machine |
| 261 | // instruction. We say that MI belongs to the equivalence class described by IC |
| 262 | // if and only if the following two conditions are met: |
| 263 | // a) MI's opcode is in the `opcodes` set, and |
| 264 | // b) `Predicate` evaluates to true when applied to MI. |
| 265 | // |
| 266 | // Instances of this class can be used by processor scheduling models to |
| 267 | // describe instructions that have a property in common. For example, |
| 268 | // InstructionEquivalenceClass definitions can be used to identify the set of |
| 269 | // dependency breaking instructions for a processor model. |
| 270 | // |
| 271 | // An (optional) list of operand indices can be used to further describe |
| 272 | // properties that apply to instruction operands. For example, it can be used to |
| 273 | // identify register uses of a dependency breaking instructions that are not in |
| 274 | // a RAW dependency. |
| 275 | class InstructionEquivalenceClass<list<Instruction> opcodes, |
| 276 | MCInstPredicate pred, |
| 277 | list<int> operands = []> { |
| 278 | list<Instruction> Opcodes = opcodes; |
| 279 | MCInstPredicate Predicate = pred; |
| 280 | list<int> OperandIndices = operands; |
| 281 | } |
| 282 | |
| 283 | // Used by processor models to describe dependency breaking instructions. |
| 284 | // |
| 285 | // This is mainly an alias for InstructionEquivalenceClass. Input operand |
| 286 | // `BrokenDeps` identifies the set of "broken dependencies". There is one bit |
| 287 | // per each implicit and explicit input operand. An empty set of broken |
| 288 | // dependencies means: "explicit input register operands are independent." |
| 289 | class DepBreakingClass<list<Instruction> opcodes, MCInstPredicate pred, |
| 290 | list<int> BrokenDeps = []> |
| 291 | : InstructionEquivalenceClass<opcodes, pred, BrokenDeps>; |
| 292 | |
| 293 | // A function descriptor used to describe the signature of a predicate methods |
| 294 | // which will be expanded by the STIPredicateExpander into a tablegen'd |
| 295 | // XXXGenSubtargetInfo class member definition (here, XXX is a target name). |
| 296 | // |
| 297 | // It describes the signature of a TargetSubtarget hook, as well as a few extra |
| 298 | // properties. Examples of extra properties are: |
| 299 | // - The default return value for the auto-generate function hook. |
| 300 | // - A list of subtarget hooks (Delegates) that are called from this function. |
| 301 | // |
| 302 | class STIPredicateDecl<string name, MCInstPredicate default = FalsePred, |
| 303 | bit overrides = 1, bit expandForMC = 1, |
| 304 | bit updatesOpcodeMask = 0, |
| 305 | list<STIPredicateDecl> delegates = []> { |
| 306 | string Name = name; |
| 307 | |
| 308 | MCInstPredicate DefaultReturnValue = default; |
| 309 | |
| 310 | // True if this method is declared as virtual in class TargetSubtargetInfo. |
| 311 | bit OverridesBaseClassMember = overrides; |
| 312 | |
| 313 | // True if we need an equivalent predicate function in the MC layer. |
| 314 | bit ExpandForMC = expandForMC; |
| 315 | |
| 316 | // True if the autogenerated method has a extra in/out APInt param used as a |
| 317 | // mask of operands. |
| 318 | bit UpdatesOpcodeMask = updatesOpcodeMask; |
| 319 | |
| 320 | // A list of STIPredicates used by this definition to delegate part of the |
| 321 | // computation. For example, STIPredicateFunction `isDependencyBreaking()` |
| 322 | // delegates to `isZeroIdiom()` part of its computation. |
| 323 | list<STIPredicateDecl> Delegates = delegates; |
| 324 | } |
| 325 | |
| 326 | // A predicate function definition member of class `XXXGenSubtargetInfo`. |
| 327 | // |
| 328 | // If `Declaration.ExpandForMC` is true, then SubtargetEmitter |
| 329 | // will also expand another definition of this method that accepts a MCInst. |
| 330 | class STIPredicate<STIPredicateDecl declaration, |
| 331 | list<InstructionEquivalenceClass> classes> { |
| 332 | STIPredicateDecl Declaration = declaration; |
| 333 | list<InstructionEquivalenceClass> Classes = classes; |
| 334 | SchedMachineModel SchedModel = ?; |
| 335 | } |
| 336 | |
| 337 | // Convenience classes and definitions used by processor scheduling models to |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 338 | // describe dependency breaking instructions and move elimination candidates. |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 339 | let UpdatesOpcodeMask = 1 in { |
| 340 | |
| 341 | def IsZeroIdiomDecl : STIPredicateDecl<"isZeroIdiom">; |
| 342 | |
| 343 | let Delegates = [IsZeroIdiomDecl] in |
| 344 | def IsDepBreakingDecl : STIPredicateDecl<"isDependencyBreaking">; |
| 345 | |
| 346 | } // UpdatesOpcodeMask |
| 347 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 348 | def IsOptimizableRegisterMoveDecl |
| 349 | : STIPredicateDecl<"isOptimizableRegisterMove">; |
| 350 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 351 | class IsZeroIdiomFunction<list<DepBreakingClass> classes> |
| 352 | : STIPredicate<IsZeroIdiomDecl, classes>; |
| 353 | |
| 354 | class IsDepBreakingFunction<list<DepBreakingClass> classes> |
| 355 | : STIPredicate<IsDepBreakingDecl, classes>; |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 356 | |
| 357 | class IsOptimizableRegisterMove<list<InstructionEquivalenceClass> classes> |
| 358 | : STIPredicate<IsOptimizableRegisterMoveDecl, classes>; |