106c3fb27SDimitry Andric //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h -----------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric // 906c3fb27SDimitry Andric /// \file This file declares the GIMatchTableExecutor API, the opcodes supported 1006c3fb27SDimitry Andric /// by the match table, and some associated data structures used by the 1106c3fb27SDimitry Andric /// executor's implementation (see `GIMatchTableExecutorImpl.h`). 1206c3fb27SDimitry Andric // 1306c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andric #ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 1606c3fb27SDimitry Andric #define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 1706c3fb27SDimitry Andric 18*5f757f3fSDimitry Andric #include "llvm/ADT/Bitset.h" 1906c3fb27SDimitry Andric #include "llvm/ADT/DenseMap.h" 2006c3fb27SDimitry Andric #include "llvm/ADT/SmallVector.h" 2106c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 2206c3fb27SDimitry Andric #include "llvm/CodeGen/LowLevelType.h" 2306c3fb27SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 2406c3fb27SDimitry Andric #include "llvm/IR/Function.h" 2506c3fb27SDimitry Andric #include <bitset> 2606c3fb27SDimitry Andric #include <cstddef> 2706c3fb27SDimitry Andric #include <cstdint> 2806c3fb27SDimitry Andric #include <functional> 2906c3fb27SDimitry Andric #include <initializer_list> 3006c3fb27SDimitry Andric #include <optional> 3106c3fb27SDimitry Andric #include <vector> 3206c3fb27SDimitry Andric 3306c3fb27SDimitry Andric namespace llvm { 3406c3fb27SDimitry Andric 3506c3fb27SDimitry Andric class BlockFrequencyInfo; 3606c3fb27SDimitry Andric class CodeGenCoverage; 3706c3fb27SDimitry Andric class MachineBasicBlock; 3806c3fb27SDimitry Andric class ProfileSummaryInfo; 3906c3fb27SDimitry Andric class APInt; 4006c3fb27SDimitry Andric class APFloat; 4106c3fb27SDimitry Andric class GISelKnownBits; 4206c3fb27SDimitry Andric class MachineInstr; 43*5f757f3fSDimitry Andric class MachineIRBuilder; 4406c3fb27SDimitry Andric class MachineInstrBuilder; 4506c3fb27SDimitry Andric class MachineFunction; 4606c3fb27SDimitry Andric class MachineOperand; 4706c3fb27SDimitry Andric class MachineRegisterInfo; 4806c3fb27SDimitry Andric class RegisterBankInfo; 4906c3fb27SDimitry Andric class TargetInstrInfo; 5006c3fb27SDimitry Andric class TargetRegisterInfo; 5106c3fb27SDimitry Andric 5206c3fb27SDimitry Andric enum { 5306c3fb27SDimitry Andric GICXXPred_Invalid = 0, 5406c3fb27SDimitry Andric GICXXCustomAction_Invalid = 0, 5506c3fb27SDimitry Andric }; 5606c3fb27SDimitry Andric 57*5f757f3fSDimitry Andric /// The MatchTable is encoded as an array of bytes. 58*5f757f3fSDimitry Andric /// Thus, opcodes are expected to be <255. 59*5f757f3fSDimitry Andric /// 60*5f757f3fSDimitry Andric /// Operands can be variable-sized, their size is always after their name 61*5f757f3fSDimitry Andric /// in the docs, e.g. "Foo(4)" means that "Foo" takes 4 entries in the table, 62*5f757f3fSDimitry Andric /// so 4 bytes. "Foo()" 63*5f757f3fSDimitry Andric /// 64*5f757f3fSDimitry Andric /// As a general rule of thumb: 65*5f757f3fSDimitry Andric /// - Instruction & Operand IDs are ULEB128 66*5f757f3fSDimitry Andric /// - LLT IDs are 1 byte 67*5f757f3fSDimitry Andric /// - Predicates and target opcodes, register and register class IDs are 2 68*5f757f3fSDimitry Andric /// bytes. 69*5f757f3fSDimitry Andric /// - Indexes into the table are 4 bytes. 70*5f757f3fSDimitry Andric /// - Inline constants are 8 bytes 71*5f757f3fSDimitry Andric /// 72*5f757f3fSDimitry Andric /// Design notes: 73*5f757f3fSDimitry Andric /// - Inst/Op IDs have to be LEB128 because some targets generate 74*5f757f3fSDimitry Andric /// extremely long patterns which need more than 255 temporaries. 75*5f757f3fSDimitry Andric /// We could just use 2 bytes everytime, but then some targets like 76*5f757f3fSDimitry Andric /// X86/AMDGPU that have no need for it will pay the price all the time. 7706c3fb27SDimitry Andric enum { 7806c3fb27SDimitry Andric /// Begin a try-block to attempt a match and jump to OnFail if it is 7906c3fb27SDimitry Andric /// unsuccessful. 80*5f757f3fSDimitry Andric /// - OnFail(4) - The MatchTable entry at which to resume if the match fails. 8106c3fb27SDimitry Andric /// 8206c3fb27SDimitry Andric /// FIXME: This ought to take an argument indicating the number of try-blocks 8306c3fb27SDimitry Andric /// to exit on failure. It's usually one but the last match attempt of 8406c3fb27SDimitry Andric /// a block will need more. The (implemented) alternative is to tack a 8506c3fb27SDimitry Andric /// GIM_Reject on the end of each try-block which is simpler but 8606c3fb27SDimitry Andric /// requires an extra opcode and iteration in the interpreter on each 8706c3fb27SDimitry Andric /// failed match. 8806c3fb27SDimitry Andric GIM_Try, 8906c3fb27SDimitry Andric 9006c3fb27SDimitry Andric /// Switch over the opcode on the specified instruction 91*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 92*5f757f3fSDimitry Andric /// - LowerBound(2) - numerically minimum opcode supported 93*5f757f3fSDimitry Andric /// - UpperBound(2) - numerically maximum + 1 opcode supported 94*5f757f3fSDimitry Andric /// - Default(4) - failure jump target 95*5f757f3fSDimitry Andric /// - JumpTable(4)... - (UpperBound - LowerBound) (at least 2) jump targets 9606c3fb27SDimitry Andric GIM_SwitchOpcode, 9706c3fb27SDimitry Andric 9806c3fb27SDimitry Andric /// Switch over the LLT on the specified instruction operand 99*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 100*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 101*5f757f3fSDimitry Andric /// - LowerBound(2) - numerically minimum Type ID supported 102*5f757f3fSDimitry Andric /// - UpperBound(2) - numerically maximum + 1 Type ID supported 103*5f757f3fSDimitry Andric /// - Default(4) - failure jump target 104*5f757f3fSDimitry Andric /// - JumpTable(4)... - (UpperBound - LowerBound) (at least 2) jump targets 10506c3fb27SDimitry Andric GIM_SwitchType, 10606c3fb27SDimitry Andric 10706c3fb27SDimitry Andric /// Record the specified instruction. 10806c3fb27SDimitry Andric /// The IgnoreCopies variant ignores COPY instructions. 109*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to define 110*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 111*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 11206c3fb27SDimitry Andric GIM_RecordInsn, 11306c3fb27SDimitry Andric GIM_RecordInsnIgnoreCopies, 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric /// Check the feature bits 116*5f757f3fSDimitry Andric /// Feature(2) - Expected features 11706c3fb27SDimitry Andric GIM_CheckFeatures, 11806c3fb27SDimitry Andric 11906c3fb27SDimitry Andric /// Check the opcode on the specified instruction 120*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 121*5f757f3fSDimitry Andric /// - Opc(2) - Expected opcode 12206c3fb27SDimitry Andric GIM_CheckOpcode, 12306c3fb27SDimitry Andric 12406c3fb27SDimitry Andric /// Check the opcode on the specified instruction, checking 2 acceptable 12506c3fb27SDimitry Andric /// alternatives. 126*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 127*5f757f3fSDimitry Andric /// - Opc(2) - Expected opcode 128*5f757f3fSDimitry Andric /// - Opc(2) - Alternative expected opcode 12906c3fb27SDimitry Andric GIM_CheckOpcodeIsEither, 13006c3fb27SDimitry Andric 13106c3fb27SDimitry Andric /// Check the instruction has the right number of operands 132*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 133*5f757f3fSDimitry Andric /// - Ops(ULEB128) - Expected number of operands 13406c3fb27SDimitry Andric GIM_CheckNumOperands, 135*5f757f3fSDimitry Andric 13606c3fb27SDimitry Andric /// Check an immediate predicate on the specified instruction 137*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 138*5f757f3fSDimitry Andric /// - Pred(2) - The predicate to test 13906c3fb27SDimitry Andric GIM_CheckI64ImmPredicate, 14006c3fb27SDimitry Andric /// Check an immediate predicate on the specified instruction via an APInt. 141*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 142*5f757f3fSDimitry Andric /// - Pred(2) - The predicate to test 14306c3fb27SDimitry Andric GIM_CheckAPIntImmPredicate, 14406c3fb27SDimitry Andric /// Check a floating point immediate predicate on the specified instruction. 145*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 146*5f757f3fSDimitry Andric /// - Pred(2) - The predicate to test 14706c3fb27SDimitry Andric GIM_CheckAPFloatImmPredicate, 14806c3fb27SDimitry Andric /// Check an immediate predicate on the specified instruction 149*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 150*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 151*5f757f3fSDimitry Andric /// - Pred(2) - The predicate to test 15206c3fb27SDimitry Andric GIM_CheckImmOperandPredicate, 153*5f757f3fSDimitry Andric 15406c3fb27SDimitry Andric /// Check a memory operation has the specified atomic ordering. 155*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 156*5f757f3fSDimitry Andric /// - Ordering(ULEB128) - The AtomicOrdering value 15706c3fb27SDimitry Andric GIM_CheckAtomicOrdering, 15806c3fb27SDimitry Andric GIM_CheckAtomicOrderingOrStrongerThan, 15906c3fb27SDimitry Andric GIM_CheckAtomicOrderingWeakerThan, 160*5f757f3fSDimitry Andric 16106c3fb27SDimitry Andric /// Check the size of the memory access for the given machine memory operand. 162*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 163*5f757f3fSDimitry Andric /// - MMOIdx(ULEB128) - MMO index 164*5f757f3fSDimitry Andric /// - Size(4) - The size in bytes of the memory access 16506c3fb27SDimitry Andric GIM_CheckMemorySizeEqualTo, 16606c3fb27SDimitry Andric 16706c3fb27SDimitry Andric /// Check the address space of the memory access for the given machine memory 16806c3fb27SDimitry Andric /// operand. 169*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 170*5f757f3fSDimitry Andric /// - MMOIdx(ULEB128) - MMO index 171*5f757f3fSDimitry Andric /// - NumAddrSpace(ULEB128) - Number of valid address spaces 172*5f757f3fSDimitry Andric /// - AddrSpaceN(ULEB128) - An allowed space of the memory access 17306c3fb27SDimitry Andric /// - AddrSpaceN+1 ... 17406c3fb27SDimitry Andric GIM_CheckMemoryAddressSpace, 17506c3fb27SDimitry Andric 17606c3fb27SDimitry Andric /// Check the minimum alignment of the memory access for the given machine 17706c3fb27SDimitry Andric /// memory operand. 178*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 179*5f757f3fSDimitry Andric /// - MMOIdx(ULEB128) - MMO index 180*5f757f3fSDimitry Andric /// - MinAlign(ULEB128) - Minimum acceptable alignment 18106c3fb27SDimitry Andric GIM_CheckMemoryAlignment, 18206c3fb27SDimitry Andric 18306c3fb27SDimitry Andric /// Check the size of the memory access for the given machine memory operand 18406c3fb27SDimitry Andric /// against the size of an operand. 185*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 186*5f757f3fSDimitry Andric /// - MMOIdx(ULEB128) - MMO index 187*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - The operand index to compare the MMO against 18806c3fb27SDimitry Andric GIM_CheckMemorySizeEqualToLLT, 18906c3fb27SDimitry Andric GIM_CheckMemorySizeLessThanLLT, 19006c3fb27SDimitry Andric GIM_CheckMemorySizeGreaterThanLLT, 19106c3fb27SDimitry Andric 19206c3fb27SDimitry Andric /// Check if this is a vector that can be treated as a vector splat 19306c3fb27SDimitry Andric /// constant. This is valid for both G_BUILD_VECTOR as well as 19406c3fb27SDimitry Andric /// G_BUILD_VECTOR_TRUNC. For AllOnes refers to individual bits, so a -1 19506c3fb27SDimitry Andric /// element. 196*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 19706c3fb27SDimitry Andric GIM_CheckIsBuildVectorAllOnes, 19806c3fb27SDimitry Andric GIM_CheckIsBuildVectorAllZeros, 19906c3fb27SDimitry Andric 20006c3fb27SDimitry Andric /// Check a trivial predicate which takes no arguments. 20106c3fb27SDimitry Andric /// This can be used by executors to implement custom flags that don't fit in 20206c3fb27SDimitry Andric /// target features. 203*5f757f3fSDimitry Andric /// - Pred(2) - Predicate ID to check. 20406c3fb27SDimitry Andric GIM_CheckSimplePredicate, 20506c3fb27SDimitry Andric 20606c3fb27SDimitry Andric /// Check a generic C++ instruction predicate 207*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 208*5f757f3fSDimitry Andric /// - PredicateID(2) - The ID of the predicate function to call 20906c3fb27SDimitry Andric GIM_CheckCxxInsnPredicate, 21006c3fb27SDimitry Andric 21106c3fb27SDimitry Andric /// Check if there's no use of the first result. 212*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 21306c3fb27SDimitry Andric GIM_CheckHasNoUse, 21406c3fb27SDimitry Andric 21506c3fb27SDimitry Andric /// Check the type for the specified operand 216*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 217*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 218*5f757f3fSDimitry Andric /// - Ty(1) - Expected type 21906c3fb27SDimitry Andric GIM_CheckType, 220*5f757f3fSDimitry Andric 22106c3fb27SDimitry Andric /// Check the type of a pointer to any address space. 222*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 223*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 224*5f757f3fSDimitry Andric /// - SizeInBits(ULEB128) - The size of the pointer value in bits. 22506c3fb27SDimitry Andric GIM_CheckPointerToAny, 226*5f757f3fSDimitry Andric 22706c3fb27SDimitry Andric /// Check the register bank for the specified operand 228*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 229*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 230*5f757f3fSDimitry Andric /// - RC(2) - Expected register bank (specified as a register class) 23106c3fb27SDimitry Andric GIM_CheckRegBankForClass, 23206c3fb27SDimitry Andric 23306c3fb27SDimitry Andric /// Check the operand matches a complex predicate 234*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 235*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 236*5f757f3fSDimitry Andric /// - RendererID(2) - The renderer to hold the result 237*5f757f3fSDimitry Andric /// - Pred(2) - Complex predicate ID 23806c3fb27SDimitry Andric GIM_CheckComplexPattern, 23906c3fb27SDimitry Andric 24006c3fb27SDimitry Andric /// Check the operand is a specific integer 241*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 242*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 243*5f757f3fSDimitry Andric /// - Val(8) Expected integer 24406c3fb27SDimitry Andric GIM_CheckConstantInt, 245*5f757f3fSDimitry Andric 246*5f757f3fSDimitry Andric /// Check the operand is a specific 8-bit signed integer 247*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 248*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 249*5f757f3fSDimitry Andric /// - Val(1) Expected integer 250*5f757f3fSDimitry Andric GIM_CheckConstantInt8, 251*5f757f3fSDimitry Andric 25206c3fb27SDimitry Andric /// Check the operand is a specific literal integer (i.e. MO.isImm() or 25306c3fb27SDimitry Andric /// MO.isCImm() is true). 254*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 255*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 256*5f757f3fSDimitry Andric /// - Val(8) - Expected integer 25706c3fb27SDimitry Andric GIM_CheckLiteralInt, 258*5f757f3fSDimitry Andric 25906c3fb27SDimitry Andric /// Check the operand is a specific intrinsic ID 260*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 261*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 262*5f757f3fSDimitry Andric /// - IID(2) - Expected Intrinsic ID 26306c3fb27SDimitry Andric GIM_CheckIntrinsicID, 26406c3fb27SDimitry Andric 26506c3fb27SDimitry Andric /// Check the operand is a specific predicate 266*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 267*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 268*5f757f3fSDimitry Andric /// - Pred(2) - Expected predicate 26906c3fb27SDimitry Andric GIM_CheckCmpPredicate, 27006c3fb27SDimitry Andric 27106c3fb27SDimitry Andric /// Check the specified operand is an MBB 272*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 273*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 27406c3fb27SDimitry Andric GIM_CheckIsMBB, 27506c3fb27SDimitry Andric 27606c3fb27SDimitry Andric /// Check the specified operand is an Imm 277*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 278*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 27906c3fb27SDimitry Andric GIM_CheckIsImm, 28006c3fb27SDimitry Andric 28106c3fb27SDimitry Andric /// Check if the specified operand is safe to fold into the current 28206c3fb27SDimitry Andric /// instruction. 283*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 28406c3fb27SDimitry Andric GIM_CheckIsSafeToFold, 28506c3fb27SDimitry Andric 28606c3fb27SDimitry Andric /// Check the specified operands are identical. 28706c3fb27SDimitry Andric /// The IgnoreCopies variant looks through COPY instructions before 28806c3fb27SDimitry Andric /// comparing the operands. 289*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 290*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 291*5f757f3fSDimitry Andric /// - OtherInsnID(ULEB128) - Other instruction ID 292*5f757f3fSDimitry Andric /// - OtherOpIdx(ULEB128) - Other operand index 29306c3fb27SDimitry Andric GIM_CheckIsSameOperand, 29406c3fb27SDimitry Andric GIM_CheckIsSameOperandIgnoreCopies, 29506c3fb27SDimitry Andric 296*5f757f3fSDimitry Andric /// Check we can replace all uses of a register with another. 297*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) 298*5f757f3fSDimitry Andric /// - OldOpIdx(ULEB128) 299*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) 300*5f757f3fSDimitry Andric /// - NewOpIdx(ULEB128) 301*5f757f3fSDimitry Andric GIM_CheckCanReplaceReg, 302*5f757f3fSDimitry Andric 303*5f757f3fSDimitry Andric /// Check that a matched instruction has, or doesn't have a MIFlag. 304*5f757f3fSDimitry Andric /// 305*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction to check. 306*5f757f3fSDimitry Andric /// - Flags(4) - (can be one or more flags OR'd together) 307*5f757f3fSDimitry Andric GIM_MIFlags, 308*5f757f3fSDimitry Andric GIM_MIFlagsNot, 309*5f757f3fSDimitry Andric 31006c3fb27SDimitry Andric /// Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some 31106c3fb27SDimitry Andric /// named operands that will be recorded in RecordedOperands. Names of these 31206c3fb27SDimitry Andric /// operands are referenced in predicate argument list. Emitter determines 31306c3fb27SDimitry Andric /// StoreIdx(corresponds to the order in which names appear in argument list). 314*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 315*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 316*5f757f3fSDimitry Andric /// - StoreIdx(ULEB128) - Store location in RecordedOperands. 31706c3fb27SDimitry Andric GIM_RecordNamedOperand, 31806c3fb27SDimitry Andric 319*5f757f3fSDimitry Andric /// Records an operand's register type into the set of temporary types. 320*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID 321*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 322*5f757f3fSDimitry Andric /// - TempTypeIdx(1) - Temp Type Index, always negative. 323*5f757f3fSDimitry Andric GIM_RecordRegType, 324*5f757f3fSDimitry Andric 32506c3fb27SDimitry Andric /// Fail the current try-block, or completely fail to match if there is no 32606c3fb27SDimitry Andric /// current try-block. 32706c3fb27SDimitry Andric GIM_Reject, 32806c3fb27SDimitry Andric 32906c3fb27SDimitry Andric //=== Renderers === 33006c3fb27SDimitry Andric 33106c3fb27SDimitry Andric /// Mutate an instruction 332*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to define 333*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to mutate 334*5f757f3fSDimitry Andric /// - NewOpcode(2) - The new opcode to use 33506c3fb27SDimitry Andric GIR_MutateOpcode, 33606c3fb27SDimitry Andric 33706c3fb27SDimitry Andric /// Build a new instruction 338*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to define 339*5f757f3fSDimitry Andric /// - Opcode(2) - The new opcode to use 34006c3fb27SDimitry Andric GIR_BuildMI, 34106c3fb27SDimitry Andric 342*5f757f3fSDimitry Andric /// Builds a constant and stores its result in a TempReg. 343*5f757f3fSDimitry Andric /// - TempRegID(ULEB128) - Temp Register to define. 344*5f757f3fSDimitry Andric /// - Imm(8) - The immediate to add 345*5f757f3fSDimitry Andric GIR_BuildConstant, 346*5f757f3fSDimitry Andric 34706c3fb27SDimitry Andric /// Copy an operand to the specified instruction 348*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to modify 349*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to copy from 350*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - The operand to copy 35106c3fb27SDimitry Andric GIR_Copy, 35206c3fb27SDimitry Andric 35306c3fb27SDimitry Andric /// Copy an operand to the specified instruction or add a zero register if the 35406c3fb27SDimitry Andric /// operand is a zero immediate. 355*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to modify 356*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to copy from 357*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - The operand to copy 358*5f757f3fSDimitry Andric /// - ZeroReg(2) - The zero register to use 35906c3fb27SDimitry Andric GIR_CopyOrAddZeroReg, 36006c3fb27SDimitry Andric /// Copy an operand to the specified instruction 361*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to modify 362*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to copy from 363*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - The operand to copy 364*5f757f3fSDimitry Andric /// - SubRegIdx(2) - The subregister to copy 36506c3fb27SDimitry Andric GIR_CopySubReg, 36606c3fb27SDimitry Andric 36706c3fb27SDimitry Andric /// Add an implicit register def to the specified instruction 368*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 369*5f757f3fSDimitry Andric /// - RegNum(2) - The register to add 370*5f757f3fSDimitry Andric /// - Flags(2) - Register Flags 37106c3fb27SDimitry Andric GIR_AddImplicitDef, 37206c3fb27SDimitry Andric /// Add an implicit register use to the specified instruction 373*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 374*5f757f3fSDimitry Andric /// - RegNum(2) - The register to add 37506c3fb27SDimitry Andric GIR_AddImplicitUse, 37606c3fb27SDimitry Andric /// Add an register to the specified instruction 377*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 378*5f757f3fSDimitry Andric /// - RegNum(2) - The register to add 379*5f757f3fSDimitry Andric /// - Flags(2) - Register Flags 38006c3fb27SDimitry Andric GIR_AddRegister, 38106c3fb27SDimitry Andric 382*5f757f3fSDimitry Andric /// Marks the implicit def of a register as dead. 383*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 384*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - The implicit def operand index 385*5f757f3fSDimitry Andric /// 386*5f757f3fSDimitry Andric /// OpIdx starts at 0 for the first implicit def. 387*5f757f3fSDimitry Andric GIR_SetImplicitDefDead, 388*5f757f3fSDimitry Andric 389*5f757f3fSDimitry Andric /// Set or unset a MIFlag on an instruction. 390*5f757f3fSDimitry Andric /// 391*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction to modify. 392*5f757f3fSDimitry Andric /// - Flags(4) - (can be one or more flags OR'd together) 393*5f757f3fSDimitry Andric GIR_SetMIFlags, 394*5f757f3fSDimitry Andric GIR_UnsetMIFlags, 395*5f757f3fSDimitry Andric 396*5f757f3fSDimitry Andric /// Copy the MIFlags of a matched instruction into an 397*5f757f3fSDimitry Andric /// output instruction. The flags are OR'd together. 398*5f757f3fSDimitry Andric /// 399*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction to modify. 400*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Matched instruction to copy flags from. 401*5f757f3fSDimitry Andric GIR_CopyMIFlags, 40206c3fb27SDimitry Andric 40306c3fb27SDimitry Andric /// Add a temporary register to the specified instruction 404*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 405*5f757f3fSDimitry Andric /// - TempRegID(ULEB128) - The temporary register ID to add 406*5f757f3fSDimitry Andric /// - TempRegFlags(2) - The register flags to set 407*5f757f3fSDimitry Andric GIR_AddTempRegister, 408*5f757f3fSDimitry Andric 409*5f757f3fSDimitry Andric /// Add a temporary register to the specified instruction without 410*5f757f3fSDimitry Andric /// setting any flags. 411*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 412*5f757f3fSDimitry Andric /// - TempRegID(ULEB128) - The temporary register ID to add 413*5f757f3fSDimitry Andric GIR_AddSimpleTempRegister, 414*5f757f3fSDimitry Andric 415*5f757f3fSDimitry Andric /// Add a temporary register to the specified instruction 416*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 417*5f757f3fSDimitry Andric /// - TempRegID(ULEB128) - The temporary register ID to add 418*5f757f3fSDimitry Andric /// - TempRegFlags(2) - The register flags to set 419*5f757f3fSDimitry Andric /// - SubRegIndex(2) - The subregister index to set 42006c3fb27SDimitry Andric GIR_AddTempSubRegister, 42106c3fb27SDimitry Andric 42206c3fb27SDimitry Andric /// Add an immediate to the specified instruction 423*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 424*5f757f3fSDimitry Andric /// - Imm(8) - The immediate to add 42506c3fb27SDimitry Andric GIR_AddImm, 42606c3fb27SDimitry Andric 427*5f757f3fSDimitry Andric /// Add signed 8 bit immediate to the specified instruction 428*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 429*5f757f3fSDimitry Andric /// - Imm(1) - The immediate to add 430*5f757f3fSDimitry Andric GIR_AddImm8, 431*5f757f3fSDimitry Andric 432*5f757f3fSDimitry Andric /// Add an CImm to the specified instruction 433*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 434*5f757f3fSDimitry Andric /// - Ty(1) - Type of the constant immediate. 435*5f757f3fSDimitry Andric /// - Imm(8) - The immediate to add 436*5f757f3fSDimitry Andric GIR_AddCImm, 437*5f757f3fSDimitry Andric 43806c3fb27SDimitry Andric /// Render complex operands to the specified instruction 439*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 440*5f757f3fSDimitry Andric /// - RendererID(2) - The renderer to call 44106c3fb27SDimitry Andric GIR_ComplexRenderer, 44206c3fb27SDimitry Andric /// Render sub-operands of complex operands to the specified instruction 443*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 444*5f757f3fSDimitry Andric /// - RendererID(2) - The renderer to call 445*5f757f3fSDimitry Andric /// - RenderOpID(ULEB128) - The suboperand to render. 44606c3fb27SDimitry Andric GIR_ComplexSubOperandRenderer, 44706c3fb27SDimitry Andric /// Render subregisters of suboperands of complex operands to the 44806c3fb27SDimitry Andric /// specified instruction 449*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 450*5f757f3fSDimitry Andric /// - RendererID(2) - The renderer to call 451*5f757f3fSDimitry Andric /// - RenderOpID(ULEB128) - The suboperand to render 452*5f757f3fSDimitry Andric /// - SubRegIdx(2) - The subregister to extract 45306c3fb27SDimitry Andric GIR_ComplexSubOperandSubRegRenderer, 45406c3fb27SDimitry Andric 45506c3fb27SDimitry Andric /// Render operands to the specified instruction using a custom function 456*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 457*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to get the matched operand from 458*5f757f3fSDimitry Andric /// - RendererFnID(2) - Custom renderer function to call 45906c3fb27SDimitry Andric GIR_CustomRenderer, 46006c3fb27SDimitry Andric 46106c3fb27SDimitry Andric /// Calls a C++ function to perform an action when a match is complete. 46206c3fb27SDimitry Andric /// The MatcherState is passed to the function to allow it to modify 46306c3fb27SDimitry Andric /// instructions. 464*5f757f3fSDimitry Andric /// This is less constrained than a custom renderer and can update 465*5f757f3fSDimitry Andric /// instructions 46606c3fb27SDimitry Andric /// in the state. 467*5f757f3fSDimitry Andric /// - FnID(2) - The function to call. 46806c3fb27SDimitry Andric /// TODO: Remove this at some point when combiners aren't reliant on it. It's 46906c3fb27SDimitry Andric /// a bit of a hack. 47006c3fb27SDimitry Andric GIR_CustomAction, 47106c3fb27SDimitry Andric 47206c3fb27SDimitry Andric /// Render operands to the specified instruction using a custom function, 47306c3fb27SDimitry Andric /// reading from a specific operand. 474*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 475*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to get the matched operand from 476*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index in OldInsnID the render function should 477*5f757f3fSDimitry Andric /// read 47806c3fb27SDimitry Andric /// from.. 479*5f757f3fSDimitry Andric /// - RendererFnID(2) - Custom renderer function to call 48006c3fb27SDimitry Andric GIR_CustomOperandRenderer, 48106c3fb27SDimitry Andric 48206c3fb27SDimitry Andric /// Render a G_CONSTANT operator as a sign-extended immediate. 483*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to modify 484*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to copy from 48506c3fb27SDimitry Andric /// The operand index is implicitly 1. 48606c3fb27SDimitry Andric GIR_CopyConstantAsSImm, 48706c3fb27SDimitry Andric 48806c3fb27SDimitry Andric /// Render a G_FCONSTANT operator as a sign-extended immediate. 489*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) - Instruction ID to modify 490*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) - Instruction ID to copy from 49106c3fb27SDimitry Andric /// The operand index is implicitly 1. 49206c3fb27SDimitry Andric GIR_CopyFConstantAsFPImm, 49306c3fb27SDimitry Andric 49406c3fb27SDimitry Andric /// Constrain an instruction operand to a register class. 495*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 496*5f757f3fSDimitry Andric /// - OpIdx(ULEB128) - Operand index 497*5f757f3fSDimitry Andric /// - RCEnum(2) - Register class enumeration value 49806c3fb27SDimitry Andric GIR_ConstrainOperandRC, 49906c3fb27SDimitry Andric 50006c3fb27SDimitry Andric /// Constrain an instructions operands according to the instruction 50106c3fb27SDimitry Andric /// description. 502*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 50306c3fb27SDimitry Andric GIR_ConstrainSelectedInstOperands, 50406c3fb27SDimitry Andric 50506c3fb27SDimitry Andric /// Merge all memory operands into instruction. 506*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to modify 507*5f757f3fSDimitry Andric /// - NumInsnID(1) - Number of instruction IDs following this argument 508*5f757f3fSDimitry Andric /// - MergeInsnID(ULEB128)... - One or more Instruction ID to merge into the 509*5f757f3fSDimitry Andric /// result. 51006c3fb27SDimitry Andric GIR_MergeMemOperands, 51106c3fb27SDimitry Andric 51206c3fb27SDimitry Andric /// Erase from parent. 513*5f757f3fSDimitry Andric /// - InsnID(ULEB128) - Instruction ID to erase 51406c3fb27SDimitry Andric GIR_EraseFromParent, 51506c3fb27SDimitry Andric 51606c3fb27SDimitry Andric /// Create a new temporary register that's not constrained. 517*5f757f3fSDimitry Andric /// - TempRegID(ULEB128) - The temporary register ID to initialize. 518*5f757f3fSDimitry Andric /// - Ty(1) - Expected type 51906c3fb27SDimitry Andric GIR_MakeTempReg, 52006c3fb27SDimitry Andric 521*5f757f3fSDimitry Andric /// Replaces all references to a register from an instruction 522*5f757f3fSDimitry Andric /// with another register from another instruction. 523*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) 524*5f757f3fSDimitry Andric /// - OldOpIdx(ULEB128) 525*5f757f3fSDimitry Andric /// - NewInsnID(ULEB128) 526*5f757f3fSDimitry Andric /// - NewOpIdx(ULEB128) 527*5f757f3fSDimitry Andric GIR_ReplaceReg, 528*5f757f3fSDimitry Andric 529*5f757f3fSDimitry Andric /// Replaces all references to a register with a temporary register. 530*5f757f3fSDimitry Andric /// - OldInsnID(ULEB128) 531*5f757f3fSDimitry Andric /// - OldOpIdx(ULEB128) 532*5f757f3fSDimitry Andric /// - TempRegIdx(ULEB128) 533*5f757f3fSDimitry Andric GIR_ReplaceRegWithTempReg, 534*5f757f3fSDimitry Andric 53506c3fb27SDimitry Andric /// A successful emission 53606c3fb27SDimitry Andric GIR_Done, 53706c3fb27SDimitry Andric 53806c3fb27SDimitry Andric /// Increment the rule coverage counter. 539*5f757f3fSDimitry Andric /// - RuleID(4) - The ID of the rule that was covered. 54006c3fb27SDimitry Andric GIR_Coverage, 54106c3fb27SDimitry Andric 54206c3fb27SDimitry Andric /// Keeping track of the number of the GI opcodes. Must be the last entry. 54306c3fb27SDimitry Andric GIU_NumOpcodes, 54406c3fb27SDimitry Andric }; 54506c3fb27SDimitry Andric 54606c3fb27SDimitry Andric /// Provides the logic to execute GlobalISel match tables, which are used by the 54706c3fb27SDimitry Andric /// instruction selector and instruction combiners as their engine to match and 54806c3fb27SDimitry Andric /// apply MIR patterns. 54906c3fb27SDimitry Andric class GIMatchTableExecutor { 55006c3fb27SDimitry Andric public: 55106c3fb27SDimitry Andric virtual ~GIMatchTableExecutor() = default; 55206c3fb27SDimitry Andric 55306c3fb27SDimitry Andric CodeGenCoverage *CoverageInfo = nullptr; 55406c3fb27SDimitry Andric GISelKnownBits *KB = nullptr; 55506c3fb27SDimitry Andric MachineFunction *MF = nullptr; 55606c3fb27SDimitry Andric ProfileSummaryInfo *PSI = nullptr; 55706c3fb27SDimitry Andric BlockFrequencyInfo *BFI = nullptr; 55806c3fb27SDimitry Andric // For some predicates, we need to track the current MBB. 55906c3fb27SDimitry Andric MachineBasicBlock *CurMBB = nullptr; 56006c3fb27SDimitry Andric 561*5f757f3fSDimitry Andric virtual void setupGeneratedPerFunctionState(MachineFunction &MF) = 0; 56206c3fb27SDimitry Andric 56306c3fb27SDimitry Andric /// Setup per-MF executor state. 56406c3fb27SDimitry Andric virtual void setupMF(MachineFunction &mf, GISelKnownBits *kb, 56506c3fb27SDimitry Andric CodeGenCoverage *covinfo = nullptr, 56606c3fb27SDimitry Andric ProfileSummaryInfo *psi = nullptr, 56706c3fb27SDimitry Andric BlockFrequencyInfo *bfi = nullptr) { 56806c3fb27SDimitry Andric CoverageInfo = covinfo; 56906c3fb27SDimitry Andric KB = kb; 57006c3fb27SDimitry Andric MF = &mf; 57106c3fb27SDimitry Andric PSI = psi; 57206c3fb27SDimitry Andric BFI = bfi; 57306c3fb27SDimitry Andric CurMBB = nullptr; 57406c3fb27SDimitry Andric setupGeneratedPerFunctionState(mf); 57506c3fb27SDimitry Andric } 57606c3fb27SDimitry Andric 57706c3fb27SDimitry Andric protected: 57806c3fb27SDimitry Andric using ComplexRendererFns = 57906c3fb27SDimitry Andric std::optional<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>; 58006c3fb27SDimitry Andric using RecordedMIVector = SmallVector<MachineInstr *, 4>; 58106c3fb27SDimitry Andric using NewMIVector = SmallVector<MachineInstrBuilder, 4>; 58206c3fb27SDimitry Andric 58306c3fb27SDimitry Andric struct MatcherState { 58406c3fb27SDimitry Andric std::vector<ComplexRendererFns::value_type> Renderers; 58506c3fb27SDimitry Andric RecordedMIVector MIs; 58606c3fb27SDimitry Andric DenseMap<unsigned, unsigned> TempRegisters; 58706c3fb27SDimitry Andric /// Named operands that predicate with 'let PredicateCodeUsesOperands = 1' 58806c3fb27SDimitry Andric /// referenced in its argument list. Operands are inserted at index set by 58906c3fb27SDimitry Andric /// emitter, it corresponds to the order in which names appear in argument 59006c3fb27SDimitry Andric /// list. Currently such predicates don't have more then 3 arguments. 59106c3fb27SDimitry Andric std::array<const MachineOperand *, 3> RecordedOperands; 59206c3fb27SDimitry Andric 593*5f757f3fSDimitry Andric /// Types extracted from an instruction's operand. 594*5f757f3fSDimitry Andric /// Whenever a type index is negative, we look here instead. 595*5f757f3fSDimitry Andric SmallVector<LLT, 4> RecordedTypes; 596*5f757f3fSDimitry Andric 59706c3fb27SDimitry Andric MatcherState(unsigned MaxRenderers); 59806c3fb27SDimitry Andric }; 59906c3fb27SDimitry Andric shouldOptForSize(const MachineFunction * MF)60006c3fb27SDimitry Andric bool shouldOptForSize(const MachineFunction *MF) const { 60106c3fb27SDimitry Andric const auto &F = MF->getFunction(); 60206c3fb27SDimitry Andric return F.hasOptSize() || F.hasMinSize() || 60306c3fb27SDimitry Andric (PSI && BFI && CurMBB && llvm::shouldOptForSize(*CurMBB, PSI, BFI)); 60406c3fb27SDimitry Andric } 60506c3fb27SDimitry Andric 60606c3fb27SDimitry Andric public: 60706c3fb27SDimitry Andric template <class PredicateBitset, class ComplexMatcherMemFn, 60806c3fb27SDimitry Andric class CustomRendererFn> 60906c3fb27SDimitry Andric struct ExecInfoTy { ExecInfoTyExecInfoTy61006c3fb27SDimitry Andric ExecInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, 61106c3fb27SDimitry Andric const PredicateBitset *FeatureBitsets, 61206c3fb27SDimitry Andric const ComplexMatcherMemFn *ComplexPredicates, 61306c3fb27SDimitry Andric const CustomRendererFn *CustomRenderers) 61406c3fb27SDimitry Andric : TypeObjects(TypeObjects), FeatureBitsets(FeatureBitsets), 61506c3fb27SDimitry Andric ComplexPredicates(ComplexPredicates), 61606c3fb27SDimitry Andric CustomRenderers(CustomRenderers) { 61706c3fb27SDimitry Andric 61806c3fb27SDimitry Andric for (size_t I = 0; I < NumTypeObjects; ++I) 61906c3fb27SDimitry Andric TypeIDMap[TypeObjects[I]] = I; 62006c3fb27SDimitry Andric } 62106c3fb27SDimitry Andric const LLT *TypeObjects; 62206c3fb27SDimitry Andric const PredicateBitset *FeatureBitsets; 62306c3fb27SDimitry Andric const ComplexMatcherMemFn *ComplexPredicates; 62406c3fb27SDimitry Andric const CustomRendererFn *CustomRenderers; 62506c3fb27SDimitry Andric 62606c3fb27SDimitry Andric SmallDenseMap<LLT, unsigned, 64> TypeIDMap; 62706c3fb27SDimitry Andric }; 62806c3fb27SDimitry Andric 62906c3fb27SDimitry Andric protected: 63006c3fb27SDimitry Andric GIMatchTableExecutor(); 63106c3fb27SDimitry Andric 63206c3fb27SDimitry Andric /// Execute a given matcher table and return true if the match was successful 63306c3fb27SDimitry Andric /// and false otherwise. 63406c3fb27SDimitry Andric template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn, 63506c3fb27SDimitry Andric class CustomRendererFn> 636*5f757f3fSDimitry Andric bool executeMatchTable(TgtExecutor &Exec, MatcherState &State, 637*5f757f3fSDimitry Andric const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, 638*5f757f3fSDimitry Andric CustomRendererFn> &ExecInfo, 639*5f757f3fSDimitry Andric MachineIRBuilder &Builder, const uint8_t *MatchTable, 640*5f757f3fSDimitry Andric const TargetInstrInfo &TII, MachineRegisterInfo &MRI, 641*5f757f3fSDimitry Andric const TargetRegisterInfo &TRI, 642*5f757f3fSDimitry Andric const RegisterBankInfo &RBI, 643*5f757f3fSDimitry Andric const PredicateBitset &AvailableFeatures, 64406c3fb27SDimitry Andric CodeGenCoverage *CoverageInfo) const; 64506c3fb27SDimitry Andric getMatchTable()646*5f757f3fSDimitry Andric virtual const uint8_t *getMatchTable() const { 64706c3fb27SDimitry Andric llvm_unreachable("Should have been overridden by tablegen if used"); 64806c3fb27SDimitry Andric } 64906c3fb27SDimitry Andric testImmPredicate_I64(unsigned,int64_t)65006c3fb27SDimitry Andric virtual bool testImmPredicate_I64(unsigned, int64_t) const { 65106c3fb27SDimitry Andric llvm_unreachable( 65206c3fb27SDimitry Andric "Subclasses must override this with a tablegen-erated function"); 65306c3fb27SDimitry Andric } testImmPredicate_APInt(unsigned,const APInt &)65406c3fb27SDimitry Andric virtual bool testImmPredicate_APInt(unsigned, const APInt &) const { 65506c3fb27SDimitry Andric llvm_unreachable( 65606c3fb27SDimitry Andric "Subclasses must override this with a tablegen-erated function"); 65706c3fb27SDimitry Andric } testImmPredicate_APFloat(unsigned,const APFloat &)65806c3fb27SDimitry Andric virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const { 65906c3fb27SDimitry Andric llvm_unreachable( 66006c3fb27SDimitry Andric "Subclasses must override this with a tablegen-erated function"); 66106c3fb27SDimitry Andric } testMIPredicate_MI(unsigned,const MachineInstr &,const MatcherState & State)66206c3fb27SDimitry Andric virtual bool testMIPredicate_MI(unsigned, const MachineInstr &, 66306c3fb27SDimitry Andric const MatcherState &State) const { 66406c3fb27SDimitry Andric llvm_unreachable( 66506c3fb27SDimitry Andric "Subclasses must override this with a tablegen-erated function"); 66606c3fb27SDimitry Andric } 66706c3fb27SDimitry Andric testSimplePredicate(unsigned)66806c3fb27SDimitry Andric virtual bool testSimplePredicate(unsigned) const { 66906c3fb27SDimitry Andric llvm_unreachable("Subclass does not implement testSimplePredicate!"); 67006c3fb27SDimitry Andric } 67106c3fb27SDimitry Andric runCustomAction(unsigned,const MatcherState & State,NewMIVector & OutMIs)672*5f757f3fSDimitry Andric virtual void runCustomAction(unsigned, const MatcherState &State, 673*5f757f3fSDimitry Andric NewMIVector &OutMIs) const { 67406c3fb27SDimitry Andric llvm_unreachable("Subclass does not implement runCustomAction!"); 67506c3fb27SDimitry Andric } 67606c3fb27SDimitry Andric 67706c3fb27SDimitry Andric bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, 678*5f757f3fSDimitry Andric const MachineRegisterInfo &MRI, 679*5f757f3fSDimitry Andric bool Splat = false) const; 68006c3fb27SDimitry Andric 68106c3fb27SDimitry Andric /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on 68206c3fb27SDimitry Andric /// the right-hand side. GlobalISel's separation of pointer and integer types 68306c3fb27SDimitry Andric /// means that we don't need to worry about G_OR with equivalent semantics. 68406c3fb27SDimitry Andric bool isBaseWithConstantOffset(const MachineOperand &Root, 68506c3fb27SDimitry Andric const MachineRegisterInfo &MRI) const; 68606c3fb27SDimitry Andric 68706c3fb27SDimitry Andric /// Return true if MI can obviously be folded into IntoMI. 68806c3fb27SDimitry Andric /// MI and IntoMI do not need to be in the same basic blocks, but MI must 68906c3fb27SDimitry Andric /// preceed IntoMI. 69006c3fb27SDimitry Andric bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const; 691*5f757f3fSDimitry Andric readBytesAs(const uint8_t * MatchTable)692*5f757f3fSDimitry Andric template <typename Ty> static Ty readBytesAs(const uint8_t *MatchTable) { 693*5f757f3fSDimitry Andric Ty Ret; 694*5f757f3fSDimitry Andric memcpy(&Ret, MatchTable, sizeof(Ret)); 695*5f757f3fSDimitry Andric return Ret; 696*5f757f3fSDimitry Andric } 69706c3fb27SDimitry Andric }; 69806c3fb27SDimitry Andric 69906c3fb27SDimitry Andric } // end namespace llvm 70006c3fb27SDimitry Andric 70106c3fb27SDimitry Andric #endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 702