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