123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- //===- TargetInstrPredicate.td - ---------------------------*- tablegen -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines class MCInstPredicate and its subclasses.
- //
- // MCInstPredicate definitions are used by target scheduling models to describe
- // constraints on instructions.
- //
- // Here is an example of an MCInstPredicate definition in TableGen:
- //
- // def MCInstPredicateExample : CheckAll<[
- // CheckOpcode<[BLR]>,
- // CheckIsRegOperand<0>,
- // CheckNot<CheckRegOperand<0, LR>>]>;
- //
- // The syntax for MCInstPredicate is declarative, and predicate definitions can
- // be composed together in order to generate more complex constraints.
- //
- // The `CheckAll` from the example defines a composition of three different
- // predicates. Definition `MCInstPredicateExample` identifies instructions
- // whose opcode is BLR, and whose first operand is a register different from
- // register `LR`.
- //
- // Every MCInstPredicate class has a well-known semantic in tablegen. For
- // example, `CheckOpcode` is a special type of predicate used to describe a
- // constraint on the value of an instruction opcode.
- //
- // MCInstPredicate definitions are typically used by scheduling models to
- // construct MCSchedPredicate definitions (see the definition of class
- // MCSchedPredicate in llvm/Target/TargetSchedule.td).
- // In particular, an MCSchedPredicate can be used instead of a SchedPredicate
- // when defining the set of SchedReadVariant and SchedWriteVariant of a
- // processor scheduling model.
- //
- // The `MCInstPredicateExample` definition above is equivalent (and therefore
- // could replace) the following definition from a previous ExynosM3 model (see
- // AArch64SchedExynosM3.td):
- //
- // def M3BranchLinkFastPred : SchedPredicate<[{
- // MI->getOpcode() == AArch64::BLR &&
- // MI->getOperand(0).isReg() &&
- // MI->getOperand(0).getReg() != AArch64::LR}]>;
- //
- // The main advantage of using MCInstPredicate instead of SchedPredicate is
- // portability: users don't need to specify predicates in C++. As a consequence
- // of this, MCInstPredicate definitions are not bound to a particular
- // representation (i.e. MachineInstr vs MCInst).
- //
- // Tablegen backends know how to expand MCInstPredicate definitions into actual
- // C++ code that works on MachineInstr (and/or MCInst).
- //
- // Instances of class PredicateExpander (see utils/Tablegen/PredicateExpander.h)
- // know how to expand a predicate. For each MCInstPredicate class, there must be
- // an "expand" method available in the PredicateExpander interface.
- //
- // For example, a `CheckOpcode` predicate is expanded using method
- // `PredicateExpander::expandCheckOpcode()`.
- //
- // New MCInstPredicate classes must be added to this file. For each new class
- // XYZ, an "expandXYZ" method must be added to the PredicateExpander.
- //
- //===----------------------------------------------------------------------===//
- // Forward declarations.
- class Instruction;
- class SchedMachineModel;
- // A generic machine instruction predicate.
- class MCInstPredicate;
- class MCTrue : MCInstPredicate; // A predicate that always evaluates to True.
- class MCFalse : MCInstPredicate; // A predicate that always evaluates to False.
- def TruePred : MCTrue;
- def FalsePred : MCFalse;
- // A predicate used to negate the outcome of another predicate.
- // It allows to easily express "set difference" operations. For example, it
- // makes it easy to describe a check that tests if an opcode is not part of a
- // set of opcodes.
- class CheckNot<MCInstPredicate P> : MCInstPredicate {
- MCInstPredicate Pred = P;
- }
- // This class is used as a building block to define predicates on instruction
- // operands. It is used to reference a specific machine operand.
- class MCOperandPredicate<int Index> : MCInstPredicate {
- int OpIndex = Index;
- }
- // Return true if machine operand at position `Index` is a register operand.
- class CheckIsRegOperand<int Index> : MCOperandPredicate<Index>;
- // Return true if machine operand at position `Index` is an immediate operand.
- class CheckIsImmOperand<int Index> : MCOperandPredicate<Index>;
- // Check if machine operands at index `First` and index `Second` both reference
- // the same register.
- class CheckSameRegOperand<int First, int Second> : MCInstPredicate {
- int FirstIndex = First;
- int SecondIndex = Second;
- }
- // Base class for checks on register/immediate operands.
- // It allows users to define checks like:
- // MyFunction(MI->getOperand(Index).getImm()) == Val;
- //
- // In the example above, `MyFunction` is a function that takes as input an
- // immediate operand value, and returns another value. Field `FunctionMapper` is
- // the name of the function to call on the operand value.
- class CheckOperandBase<int Index, string Fn = ""> : MCOperandPredicate<Index> {
- string FunctionMapper = Fn;
- }
- // Check that the machine register operand at position `Index` references
- // register R. This predicate assumes that we already checked that the machine
- // operand at position `Index` is a register operand.
- class CheckRegOperand<int Index, Register R> : CheckOperandBase<Index> {
- Register Reg = R;
- }
- // Check if register operand at index `Index` is the invalid register.
- class CheckInvalidRegOperand<int Index> : CheckOperandBase<Index>;
- // Return true if machine operand at position `Index` is a valid
- // register operand.
- class CheckValidRegOperand<int Index> :
- CheckNot<CheckInvalidRegOperand<Index>>;
- // Check that the operand at position `Index` is immediate `Imm`.
- // If field `FunctionMapper` is a non-empty string, then function
- // `FunctionMapper` is applied to the operand value, and the return value is then
- // compared against `Imm`.
- class CheckImmOperand<int Index, int Imm> : CheckOperandBase<Index> {
- int ImmVal = Imm;
- }
- // Similar to CheckImmOperand, however the immediate is not a literal number.
- // This is useful when we want to compare the value of an operand against an
- // enum value, and we know the actual integer value of that enum.
- class CheckImmOperand_s<int Index, string Value> : CheckOperandBase<Index> {
- string ImmVal = Value;
- }
- // Expands to a call to `FunctionMapper` if field `FunctionMapper` is set.
- // Otherwise, it expands to a CheckNot<CheckInvalidRegOperand<Index>>.
- class CheckRegOperandSimple<int Index> : CheckOperandBase<Index>;
- // Expands to a call to `FunctionMapper` if field `FunctionMapper` is set.
- // Otherwise, it simply evaluates to TruePred.
- class CheckImmOperandSimple<int Index> : CheckOperandBase<Index>;
- // Check that the operand at position `Index` is immediate value zero.
- class CheckZeroOperand<int Index> : CheckImmOperand<Index, 0>;
- // Check that the instruction has exactly `Num` operands.
- class CheckNumOperands<int Num> : MCInstPredicate {
- int NumOps = Num;
- }
- // Check that the instruction opcode is one of the opcodes in set `Opcodes`.
- // This is a simple set membership query. The easier way to check if an opcode
- // is not a member of the set is by using a `CheckNot<CheckOpcode<[...]>>`
- // sequence.
- class CheckOpcode<list<Instruction> Opcodes> : MCInstPredicate {
- list<Instruction> ValidOpcodes = Opcodes;
- }
- // Check that the instruction opcode is a pseudo opcode member of the set
- // `Opcodes`. This check is always expanded to "false" if we are generating
- // code for MCInst.
- class CheckPseudo<list<Instruction> Opcodes> : CheckOpcode<Opcodes>;
- // A non-portable predicate. Only to use as a last resort when a block of code
- // cannot possibly be converted in a declarative way using other MCInstPredicate
- // classes. This check is always expanded to "false" when generating code for
- // MCInst.
- class CheckNonPortable<string Code> : MCInstPredicate {
- string CodeBlock = Code;
- }
- // A sequence of predicates. It is used as the base class for CheckAll, and
- // CheckAny. It allows to describe compositions of predicates.
- class CheckPredicateSequence<list<MCInstPredicate> Preds> : MCInstPredicate {
- list<MCInstPredicate> Predicates = Preds;
- }
- // Check that all of the predicates in `Preds` evaluate to true.
- class CheckAll<list<MCInstPredicate> Sequence>
- : CheckPredicateSequence<Sequence>;
- // Check that at least one of the predicates in `Preds` evaluates to true.
- class CheckAny<list<MCInstPredicate> Sequence>
- : CheckPredicateSequence<Sequence>;
- // Used to expand the body of a function predicate. See the definition of
- // TIIPredicate below.
- class MCStatement;
- // Expands to a return statement. The return expression is a boolean expression
- // described by a MCInstPredicate.
- class MCReturnStatement<MCInstPredicate predicate> : MCStatement {
- MCInstPredicate Pred = predicate;
- }
- // Used to automatically construct cases of a switch statement where the switch
- // variable is an instruction opcode. There is a 'case' for every opcode in the
- // `opcodes` list, and each case is associated with MCStatement `caseStmt`.
- class MCOpcodeSwitchCase<list<Instruction> opcodes, MCStatement caseStmt> {
- list<Instruction> Opcodes = opcodes;
- MCStatement CaseStmt = caseStmt;
- }
- // Expands to a switch statement. The switch variable is an instruction opcode.
- // The auto-generated switch is populated by a number of cases based on the
- // `cases` list in input. A default case is automatically generated, and it
- // evaluates to `default`.
- class MCOpcodeSwitchStatement<list<MCOpcodeSwitchCase> cases,
- MCStatement default> : MCStatement {
- list<MCOpcodeSwitchCase> Cases = cases;
- MCStatement DefaultCase = default;
- }
- // Base class for function predicates.
- class FunctionPredicateBase<string name, MCStatement body> {
- string FunctionName = name;
- MCStatement Body = body;
- }
- // Check that a call to method `Name` in class "XXXInstrInfo" (where XXX is
- // the name of a target) returns true.
- //
- // TIIPredicate definitions are used to model calls to the target-specific
- // InstrInfo. A TIIPredicate is treated specially by the InstrInfoEmitter
- // tablegen backend, which will use it to automatically generate a definition in
- // the target specific `InstrInfo` class.
- //
- // There cannot be multiple TIIPredicate definitions with the same name for the
- // same target.
- class TIIPredicate<string Name, MCStatement body>
- : FunctionPredicateBase<Name, body>, MCInstPredicate;
- // A function predicate that takes as input a machine instruction, and returns
- // a boolean value.
- //
- // This predicate is expanded into a function call by the PredicateExpander.
- // In particular, the PredicateExpander would either expand this predicate into
- // a call to `MCInstFn`, or into a call to`MachineInstrFn` depending on whether
- // it is lowering predicates for MCInst or MachineInstr.
- //
- // In this context, `MCInstFn` and `MachineInstrFn` are both function names.
- class CheckFunctionPredicate<string MCInstFn, string MachineInstrFn> : MCInstPredicate {
- string MCInstFnName = MCInstFn;
- string MachineInstrFnName = MachineInstrFn;
- }
- // Similar to CheckFunctionPredicate. However it assumes that MachineInstrFn is
- // a method in TargetInstrInfo, and MCInstrFn takes an extra pointer to
- // MCInstrInfo.
- //
- // It Expands to:
- // - TIIPointer->MachineInstrFn(MI)
- // - MCInstrFn(MI, MCII);
- class CheckFunctionPredicateWithTII<string MCInstFn, string MachineInstrFn, string
- TIIPointer = "TII"> : MCInstPredicate {
- string MCInstFnName = MCInstFn;
- string TIIPtrName = TIIPointer;
- string MachineInstrFnName = MachineInstrFn;
- }
- // Used to classify machine instructions based on a machine instruction
- // predicate.
- //
- // Let IC be an InstructionEquivalenceClass definition, and MI a machine
- // instruction. We say that MI belongs to the equivalence class described by IC
- // if and only if the following two conditions are met:
- // a) MI's opcode is in the `opcodes` set, and
- // b) `Predicate` evaluates to true when applied to MI.
- //
- // Instances of this class can be used by processor scheduling models to
- // describe instructions that have a property in common. For example,
- // InstructionEquivalenceClass definitions can be used to identify the set of
- // dependency breaking instructions for a processor model.
- //
- // An (optional) list of operand indices can be used to further describe
- // properties that apply to instruction operands. For example, it can be used to
- // identify register uses of a dependency breaking instructions that are not in
- // a RAW dependency.
- class InstructionEquivalenceClass<list<Instruction> opcodes,
- MCInstPredicate pred,
- list<int> operands = []> {
- list<Instruction> Opcodes = opcodes;
- MCInstPredicate Predicate = pred;
- list<int> OperandIndices = operands;
- }
- // Used by processor models to describe dependency breaking instructions.
- //
- // This is mainly an alias for InstructionEquivalenceClass. Input operand
- // `BrokenDeps` identifies the set of "broken dependencies". There is one bit
- // per each implicit and explicit input operand. An empty set of broken
- // dependencies means: "explicit input register operands are independent."
- class DepBreakingClass<list<Instruction> opcodes, MCInstPredicate pred,
- list<int> BrokenDeps = []>
- : InstructionEquivalenceClass<opcodes, pred, BrokenDeps>;
- // A function descriptor used to describe the signature of a predicate methods
- // which will be expanded by the STIPredicateExpander into a tablegen'd
- // XXXGenSubtargetInfo class member definition (here, XXX is a target name).
- //
- // It describes the signature of a TargetSubtarget hook, as well as a few extra
- // properties. Examples of extra properties are:
- // - The default return value for the auto-generate function hook.
- // - A list of subtarget hooks (Delegates) that are called from this function.
- //
- class STIPredicateDecl<string name, MCInstPredicate default = FalsePred,
- bit overrides = true, bit expandForMC = true,
- bit updatesOpcodeMask = false,
- list<STIPredicateDecl> delegates = []> {
- string Name = name;
- MCInstPredicate DefaultReturnValue = default;
- // True if this method is declared as virtual in class TargetSubtargetInfo.
- bit OverridesBaseClassMember = overrides;
- // True if we need an equivalent predicate function in the MC layer.
- bit ExpandForMC = expandForMC;
- // True if the autogenerated method has a extra in/out APInt param used as a
- // mask of operands.
- bit UpdatesOpcodeMask = updatesOpcodeMask;
- // A list of STIPredicates used by this definition to delegate part of the
- // computation. For example, STIPredicateFunction `isDependencyBreaking()`
- // delegates to `isZeroIdiom()` part of its computation.
- list<STIPredicateDecl> Delegates = delegates;
- }
- // A predicate function definition member of class `XXXGenSubtargetInfo`.
- //
- // If `Declaration.ExpandForMC` is true, then SubtargetEmitter
- // will also expand another definition of this method that accepts a MCInst.
- class STIPredicate<STIPredicateDecl declaration,
- list<InstructionEquivalenceClass> classes> {
- STIPredicateDecl Declaration = declaration;
- list<InstructionEquivalenceClass> Classes = classes;
- SchedMachineModel SchedModel = ?;
- }
- // Convenience classes and definitions used by processor scheduling models to
- // describe dependency breaking instructions and move elimination candidates.
- let UpdatesOpcodeMask = true in {
- def IsZeroIdiomDecl : STIPredicateDecl<"isZeroIdiom">;
- let Delegates = [IsZeroIdiomDecl] in
- def IsDepBreakingDecl : STIPredicateDecl<"isDependencyBreaking">;
- } // UpdatesOpcodeMask
- def IsOptimizableRegisterMoveDecl
- : STIPredicateDecl<"isOptimizableRegisterMove">;
- class IsZeroIdiomFunction<list<DepBreakingClass> classes>
- : STIPredicate<IsZeroIdiomDecl, classes>;
- class IsDepBreakingFunction<list<DepBreakingClass> classes>
- : STIPredicate<IsDepBreakingDecl, classes>;
- class IsOptimizableRegisterMove<list<InstructionEquivalenceClass> classes>
- : STIPredicate<IsOptimizableRegisterMoveDecl, classes>;
|