1 //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file This file declares the GIMatchTableExecutor API, the opcodes supported 10 /// by the match table, and some associated data structures used by the 11 /// executor's implementation (see `GIMatchTableExecutorImpl.h`). 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 16 #define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 17 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/CodeGen/GlobalISel/Utils.h" 21 #include "llvm/CodeGen/LowLevelType.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/IR/Function.h" 24 #include <bitset> 25 #include <cstddef> 26 #include <cstdint> 27 #include <functional> 28 #include <initializer_list> 29 #include <optional> 30 #include <vector> 31 32 namespace llvm { 33 34 class BlockFrequencyInfo; 35 class CodeGenCoverage; 36 class MachineBasicBlock; 37 class ProfileSummaryInfo; 38 class APInt; 39 class APFloat; 40 class GISelKnownBits; 41 class MachineInstr; 42 class MachineInstrBuilder; 43 class MachineFunction; 44 class MachineOperand; 45 class MachineRegisterInfo; 46 class RegisterBankInfo; 47 class TargetInstrInfo; 48 class TargetRegisterInfo; 49 50 /// Container class for CodeGen predicate results. 51 /// This is convenient because std::bitset does not have a constructor 52 /// with an initializer list of set bits. 53 /// 54 /// Each GIMatchTableExecutor subclass should define a PredicateBitset class 55 /// with: 56 /// const unsigned MAX_SUBTARGET_PREDICATES = 192; 57 /// using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>; 58 /// and updating the constant to suit the target. Tablegen provides a suitable 59 /// definition for the predicates in use in <Target>GenGlobalISel.inc when 60 /// GET_GLOBALISEL_PREDICATE_BITSET is defined. 61 template <std::size_t MaxPredicates> 62 class PredicateBitsetImpl : public std::bitset<MaxPredicates> { 63 public: 64 // Cannot inherit constructors because it's not supported by VC++.. 65 PredicateBitsetImpl() = default; 66 67 PredicateBitsetImpl(const std::bitset<MaxPredicates> &B) 68 : std::bitset<MaxPredicates>(B) {} 69 70 PredicateBitsetImpl(std::initializer_list<unsigned> Init) { 71 for (auto I : Init) 72 std::bitset<MaxPredicates>::set(I); 73 } 74 }; 75 76 enum { 77 GICXXPred_Invalid = 0, 78 GICXXCustomAction_Invalid = 0, 79 }; 80 81 enum { 82 /// Begin a try-block to attempt a match and jump to OnFail if it is 83 /// unsuccessful. 84 /// - OnFail - The MatchTable entry at which to resume if the match fails. 85 /// 86 /// FIXME: This ought to take an argument indicating the number of try-blocks 87 /// to exit on failure. It's usually one but the last match attempt of 88 /// a block will need more. The (implemented) alternative is to tack a 89 /// GIM_Reject on the end of each try-block which is simpler but 90 /// requires an extra opcode and iteration in the interpreter on each 91 /// failed match. 92 GIM_Try, 93 94 /// Switch over the opcode on the specified instruction 95 /// - InsnID - Instruction ID 96 /// - LowerBound - numerically minimum opcode supported 97 /// - UpperBound - numerically maximum + 1 opcode supported 98 /// - Default - failure jump target 99 /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets 100 GIM_SwitchOpcode, 101 102 /// Switch over the LLT on the specified instruction operand 103 /// - InsnID - Instruction ID 104 /// - OpIdx - Operand index 105 /// - LowerBound - numerically minimum Type ID supported 106 /// - UpperBound - numerically maximum + 1 Type ID supported 107 /// - Default - failure jump target 108 /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets 109 GIM_SwitchType, 110 111 /// Record the specified instruction. 112 /// The IgnoreCopies variant ignores COPY instructions. 113 /// - NewInsnID - Instruction ID to define 114 /// - InsnID - Instruction ID 115 /// - OpIdx - Operand index 116 GIM_RecordInsn, 117 GIM_RecordInsnIgnoreCopies, 118 119 /// Check the feature bits 120 /// - Expected features 121 GIM_CheckFeatures, 122 123 /// Check the opcode on the specified instruction 124 /// - InsnID - Instruction ID 125 /// - Expected opcode 126 GIM_CheckOpcode, 127 128 /// Check the opcode on the specified instruction, checking 2 acceptable 129 /// alternatives. 130 /// - InsnID - Instruction ID 131 /// - Expected opcode 132 /// - Alternative expected opcode 133 GIM_CheckOpcodeIsEither, 134 135 /// Check the instruction has the right number of operands 136 /// - InsnID - Instruction ID 137 /// - Expected number of operands 138 GIM_CheckNumOperands, 139 /// Check an immediate predicate on the specified instruction 140 /// - InsnID - Instruction ID 141 /// - The predicate to test 142 GIM_CheckI64ImmPredicate, 143 /// Check an immediate predicate on the specified instruction via an APInt. 144 /// - InsnID - Instruction ID 145 /// - The predicate to test 146 GIM_CheckAPIntImmPredicate, 147 /// Check a floating point immediate predicate on the specified instruction. 148 /// - InsnID - Instruction ID 149 /// - The predicate to test 150 GIM_CheckAPFloatImmPredicate, 151 /// Check an immediate predicate on the specified instruction 152 /// - InsnID - Instruction ID 153 /// - OpIdx - Operand index 154 /// - The predicate to test 155 GIM_CheckImmOperandPredicate, 156 /// Check a memory operation has the specified atomic ordering. 157 /// - InsnID - Instruction ID 158 /// - Ordering - The AtomicOrdering value 159 GIM_CheckAtomicOrdering, 160 GIM_CheckAtomicOrderingOrStrongerThan, 161 GIM_CheckAtomicOrderingWeakerThan, 162 /// Check the size of the memory access for the given machine memory operand. 163 /// - InsnID - Instruction ID 164 /// - MMOIdx - MMO index 165 /// - Size - The size in bytes of the memory access 166 GIM_CheckMemorySizeEqualTo, 167 168 /// Check the address space of the memory access for the given machine memory 169 /// operand. 170 /// - InsnID - Instruction ID 171 /// - MMOIdx - MMO index 172 /// - NumAddrSpace - Number of valid address spaces 173 /// - AddrSpaceN - An allowed space of the memory access 174 /// - AddrSpaceN+1 ... 175 GIM_CheckMemoryAddressSpace, 176 177 /// Check the minimum alignment of the memory access for the given machine 178 /// memory operand. 179 /// - InsnID - Instruction ID 180 /// - MMOIdx - MMO index 181 /// - MinAlign - Minimum acceptable alignment 182 GIM_CheckMemoryAlignment, 183 184 /// Check the size of the memory access for the given machine memory operand 185 /// against the size of an operand. 186 /// - InsnID - Instruction ID 187 /// - MMOIdx - MMO index 188 /// - OpIdx - The operand index to compare the MMO against 189 GIM_CheckMemorySizeEqualToLLT, 190 GIM_CheckMemorySizeLessThanLLT, 191 GIM_CheckMemorySizeGreaterThanLLT, 192 193 /// Check if this is a vector that can be treated as a vector splat 194 /// constant. This is valid for both G_BUILD_VECTOR as well as 195 /// G_BUILD_VECTOR_TRUNC. For AllOnes refers to individual bits, so a -1 196 /// element. 197 /// - InsnID - Instruction ID 198 GIM_CheckIsBuildVectorAllOnes, 199 GIM_CheckIsBuildVectorAllZeros, 200 201 /// Check a trivial predicate which takes no arguments. 202 /// This can be used by executors to implement custom flags that don't fit in 203 /// target features. 204 GIM_CheckSimplePredicate, 205 206 /// Check a generic C++ instruction predicate 207 /// - InsnID - Instruction ID 208 /// - PredicateID - The ID of the predicate function to call 209 GIM_CheckCxxInsnPredicate, 210 211 /// Check if there's no use of the first result. 212 /// - InsnID - Instruction ID 213 GIM_CheckHasNoUse, 214 215 /// Check the type for the specified operand 216 /// - InsnID - Instruction ID 217 /// - OpIdx - Operand index 218 /// - Expected type 219 GIM_CheckType, 220 /// Check the type of a pointer to any address space. 221 /// - InsnID - Instruction ID 222 /// - OpIdx - Operand index 223 /// - SizeInBits - The size of the pointer value in bits. 224 GIM_CheckPointerToAny, 225 /// Check the register bank for the specified operand 226 /// - InsnID - Instruction ID 227 /// - OpIdx - Operand index 228 /// - Expected register bank (specified as a register class) 229 GIM_CheckRegBankForClass, 230 231 /// Check the operand matches a complex predicate 232 /// - InsnID - Instruction ID 233 /// - OpIdx - Operand index 234 /// - RendererID - The renderer to hold the result 235 /// - Complex predicate ID 236 GIM_CheckComplexPattern, 237 238 /// Check the operand is a specific integer 239 /// - InsnID - Instruction ID 240 /// - OpIdx - Operand index 241 /// - Expected integer 242 GIM_CheckConstantInt, 243 /// Check the operand is a specific literal integer (i.e. MO.isImm() or 244 /// MO.isCImm() is true). 245 /// - InsnID - Instruction ID 246 /// - OpIdx - Operand index 247 /// - Expected integer 248 GIM_CheckLiteralInt, 249 /// Check the operand is a specific intrinsic ID 250 /// - InsnID - Instruction ID 251 /// - OpIdx - Operand index 252 /// - Expected Intrinsic ID 253 GIM_CheckIntrinsicID, 254 255 /// Check the operand is a specific predicate 256 /// - InsnID - Instruction ID 257 /// - OpIdx - Operand index 258 /// - Expected predicate 259 GIM_CheckCmpPredicate, 260 261 /// Check the specified operand is an MBB 262 /// - InsnID - Instruction ID 263 /// - OpIdx - Operand index 264 GIM_CheckIsMBB, 265 266 /// Check the specified operand is an Imm 267 /// - InsnID - Instruction ID 268 /// - OpIdx - Operand index 269 GIM_CheckIsImm, 270 271 /// Check if the specified operand is safe to fold into the current 272 /// instruction. 273 /// - InsnID - Instruction ID 274 GIM_CheckIsSafeToFold, 275 276 /// Check the specified operands are identical. 277 /// The IgnoreCopies variant looks through COPY instructions before 278 /// comparing the operands. 279 /// - InsnID - Instruction ID 280 /// - OpIdx - Operand index 281 /// - OtherInsnID - Other instruction ID 282 /// - OtherOpIdx - Other operand index 283 GIM_CheckIsSameOperand, 284 GIM_CheckIsSameOperandIgnoreCopies, 285 286 /// Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some 287 /// named operands that will be recorded in RecordedOperands. Names of these 288 /// operands are referenced in predicate argument list. Emitter determines 289 /// StoreIdx(corresponds to the order in which names appear in argument list). 290 /// - InsnID - Instruction ID 291 /// - OpIdx - Operand index 292 /// - StoreIdx - Store location in RecordedOperands. 293 GIM_RecordNamedOperand, 294 295 /// Fail the current try-block, or completely fail to match if there is no 296 /// current try-block. 297 GIM_Reject, 298 299 //=== Renderers === 300 301 /// Mutate an instruction 302 /// - NewInsnID - Instruction ID to define 303 /// - OldInsnID - Instruction ID to mutate 304 /// - NewOpcode - The new opcode to use 305 GIR_MutateOpcode, 306 307 /// Build a new instruction 308 /// - InsnID - Instruction ID to define 309 /// - Opcode - The new opcode to use 310 GIR_BuildMI, 311 312 /// Copy an operand to the specified instruction 313 /// - NewInsnID - Instruction ID to modify 314 /// - OldInsnID - Instruction ID to copy from 315 /// - OpIdx - The operand to copy 316 GIR_Copy, 317 318 /// Copy an operand to the specified instruction or add a zero register if the 319 /// operand is a zero immediate. 320 /// - NewInsnID - Instruction ID to modify 321 /// - OldInsnID - Instruction ID to copy from 322 /// - OpIdx - The operand to copy 323 /// - ZeroReg - The zero register to use 324 GIR_CopyOrAddZeroReg, 325 /// Copy an operand to the specified instruction 326 /// - NewInsnID - Instruction ID to modify 327 /// - OldInsnID - Instruction ID to copy from 328 /// - OpIdx - The operand to copy 329 /// - SubRegIdx - The subregister to copy 330 GIR_CopySubReg, 331 332 /// Add an implicit register def to the specified instruction 333 /// - InsnID - Instruction ID to modify 334 /// - RegNum - The register to add 335 GIR_AddImplicitDef, 336 /// Add an implicit register use to the specified instruction 337 /// - InsnID - Instruction ID to modify 338 /// - RegNum - The register to add 339 GIR_AddImplicitUse, 340 /// Add an register to the specified instruction 341 /// - InsnID - Instruction ID to modify 342 /// - RegNum - The register to add 343 GIR_AddRegister, 344 345 /// Add a temporary register to the specified instruction 346 /// - InsnID - Instruction ID to modify 347 /// - TempRegID - The temporary register ID to add 348 /// - TempRegFlags - The register flags to set 349 GIR_AddTempRegister, 350 351 /// Add a temporary register to the specified instruction 352 /// - InsnID - Instruction ID to modify 353 /// - TempRegID - The temporary register ID to add 354 /// - TempRegFlags - The register flags to set 355 /// - SubRegIndex - The subregister index to set 356 GIR_AddTempSubRegister, 357 358 /// Add an immediate to the specified instruction 359 /// - InsnID - Instruction ID to modify 360 /// - Imm - The immediate to add 361 GIR_AddImm, 362 363 /// Render complex operands to the specified instruction 364 /// - InsnID - Instruction ID to modify 365 /// - RendererID - The renderer to call 366 GIR_ComplexRenderer, 367 /// Render sub-operands of complex operands to the specified instruction 368 /// - InsnID - Instruction ID to modify 369 /// - RendererID - The renderer to call 370 /// - RenderOpID - The suboperand to render. 371 GIR_ComplexSubOperandRenderer, 372 /// Render subregisters of suboperands of complex operands to the 373 /// specified instruction 374 /// - InsnID - Instruction ID to modify 375 /// - RendererID - The renderer to call 376 /// - RenderOpID - The suboperand to render 377 /// - SubRegIdx - The subregister to extract 378 GIR_ComplexSubOperandSubRegRenderer, 379 380 /// Render operands to the specified instruction using a custom function 381 /// - InsnID - Instruction ID to modify 382 /// - OldInsnID - Instruction ID to get the matched operand from 383 /// - RendererFnID - Custom renderer function to call 384 GIR_CustomRenderer, 385 386 /// Calls a C++ function to perform an action when a match is complete. 387 /// The MatcherState is passed to the function to allow it to modify 388 /// instructions. 389 /// This is less constrained than a custom renderer and can update instructions 390 /// in the state. 391 /// - FnID - The function to call. 392 /// TODO: Remove this at some point when combiners aren't reliant on it. It's 393 /// a bit of a hack. 394 GIR_CustomAction, 395 396 /// Render operands to the specified instruction using a custom function, 397 /// reading from a specific operand. 398 /// - InsnID - Instruction ID to modify 399 /// - OldInsnID - Instruction ID to get the matched operand from 400 /// - OpIdx - Operand index in OldInsnID the render function should read 401 /// from.. 402 /// - RendererFnID - Custom renderer function to call 403 GIR_CustomOperandRenderer, 404 405 /// Render a G_CONSTANT operator as a sign-extended immediate. 406 /// - NewInsnID - Instruction ID to modify 407 /// - OldInsnID - Instruction ID to copy from 408 /// The operand index is implicitly 1. 409 GIR_CopyConstantAsSImm, 410 411 /// Render a G_FCONSTANT operator as a sign-extended immediate. 412 /// - NewInsnID - Instruction ID to modify 413 /// - OldInsnID - Instruction ID to copy from 414 /// The operand index is implicitly 1. 415 GIR_CopyFConstantAsFPImm, 416 417 /// Constrain an instruction operand to a register class. 418 /// - InsnID - Instruction ID to modify 419 /// - OpIdx - Operand index 420 /// - RCEnum - Register class enumeration value 421 GIR_ConstrainOperandRC, 422 423 /// Constrain an instructions operands according to the instruction 424 /// description. 425 /// - InsnID - Instruction ID to modify 426 GIR_ConstrainSelectedInstOperands, 427 428 /// Merge all memory operands into instruction. 429 /// - InsnID - Instruction ID to modify 430 /// - MergeInsnID... - One or more Instruction ID to merge into the result. 431 /// - GIU_MergeMemOperands_EndOfList - Terminates the list of instructions to 432 /// merge. 433 GIR_MergeMemOperands, 434 435 /// Erase from parent. 436 /// - InsnID - Instruction ID to erase 437 GIR_EraseFromParent, 438 439 /// Create a new temporary register that's not constrained. 440 /// - TempRegID - The temporary register ID to initialize. 441 /// - Expected type 442 GIR_MakeTempReg, 443 444 /// A successful emission 445 GIR_Done, 446 447 /// Increment the rule coverage counter. 448 /// - RuleID - The ID of the rule that was covered. 449 GIR_Coverage, 450 451 /// Keeping track of the number of the GI opcodes. Must be the last entry. 452 GIU_NumOpcodes, 453 }; 454 455 enum { 456 /// Indicates the end of the variable-length MergeInsnID list in a 457 /// GIR_MergeMemOperands opcode. 458 GIU_MergeMemOperands_EndOfList = -1, 459 }; 460 461 /// Provides the logic to execute GlobalISel match tables, which are used by the 462 /// instruction selector and instruction combiners as their engine to match and 463 /// apply MIR patterns. 464 class GIMatchTableExecutor { 465 public: 466 virtual ~GIMatchTableExecutor() = default; 467 468 CodeGenCoverage *CoverageInfo = nullptr; 469 GISelKnownBits *KB = nullptr; 470 MachineFunction *MF = nullptr; 471 ProfileSummaryInfo *PSI = nullptr; 472 BlockFrequencyInfo *BFI = nullptr; 473 // For some predicates, we need to track the current MBB. 474 MachineBasicBlock *CurMBB = nullptr; 475 476 virtual void setupGeneratedPerFunctionState(MachineFunction &MF) { 477 llvm_unreachable("TableGen should have emitted implementation"); 478 } 479 480 /// Setup per-MF executor state. 481 virtual void setupMF(MachineFunction &mf, GISelKnownBits *kb, 482 CodeGenCoverage *covinfo = nullptr, 483 ProfileSummaryInfo *psi = nullptr, 484 BlockFrequencyInfo *bfi = nullptr) { 485 CoverageInfo = covinfo; 486 KB = kb; 487 MF = &mf; 488 PSI = psi; 489 BFI = bfi; 490 CurMBB = nullptr; 491 setupGeneratedPerFunctionState(mf); 492 } 493 494 protected: 495 using ComplexRendererFns = 496 std::optional<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>; 497 using RecordedMIVector = SmallVector<MachineInstr *, 4>; 498 using NewMIVector = SmallVector<MachineInstrBuilder, 4>; 499 500 struct MatcherState { 501 std::vector<ComplexRendererFns::value_type> Renderers; 502 RecordedMIVector MIs; 503 DenseMap<unsigned, unsigned> TempRegisters; 504 /// Named operands that predicate with 'let PredicateCodeUsesOperands = 1' 505 /// referenced in its argument list. Operands are inserted at index set by 506 /// emitter, it corresponds to the order in which names appear in argument 507 /// list. Currently such predicates don't have more then 3 arguments. 508 std::array<const MachineOperand *, 3> RecordedOperands; 509 510 MatcherState(unsigned MaxRenderers); 511 }; 512 513 bool shouldOptForSize(const MachineFunction *MF) const { 514 const auto &F = MF->getFunction(); 515 return F.hasOptSize() || F.hasMinSize() || 516 (PSI && BFI && CurMBB && llvm::shouldOptForSize(*CurMBB, PSI, BFI)); 517 } 518 519 public: 520 template <class PredicateBitset, class ComplexMatcherMemFn, 521 class CustomRendererFn> 522 struct ExecInfoTy { 523 ExecInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, 524 const PredicateBitset *FeatureBitsets, 525 const ComplexMatcherMemFn *ComplexPredicates, 526 const CustomRendererFn *CustomRenderers) 527 : TypeObjects(TypeObjects), FeatureBitsets(FeatureBitsets), 528 ComplexPredicates(ComplexPredicates), 529 CustomRenderers(CustomRenderers) { 530 531 for (size_t I = 0; I < NumTypeObjects; ++I) 532 TypeIDMap[TypeObjects[I]] = I; 533 } 534 const LLT *TypeObjects; 535 const PredicateBitset *FeatureBitsets; 536 const ComplexMatcherMemFn *ComplexPredicates; 537 const CustomRendererFn *CustomRenderers; 538 539 SmallDenseMap<LLT, unsigned, 64> TypeIDMap; 540 }; 541 542 protected: 543 GIMatchTableExecutor(); 544 545 /// Execute a given matcher table and return true if the match was successful 546 /// and false otherwise. 547 template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn, 548 class CustomRendererFn> 549 bool executeMatchTable( 550 TgtExecutor &Exec, NewMIVector &OutMIs, MatcherState &State, 551 const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> 552 &ISelInfo, 553 const int64_t *MatchTable, const TargetInstrInfo &TII, 554 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 555 const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, 556 CodeGenCoverage *CoverageInfo) const; 557 558 virtual const int64_t *getMatchTable() const { 559 llvm_unreachable("Should have been overridden by tablegen if used"); 560 } 561 562 virtual bool testImmPredicate_I64(unsigned, int64_t) const { 563 llvm_unreachable( 564 "Subclasses must override this with a tablegen-erated function"); 565 } 566 virtual bool testImmPredicate_APInt(unsigned, const APInt &) const { 567 llvm_unreachable( 568 "Subclasses must override this with a tablegen-erated function"); 569 } 570 virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const { 571 llvm_unreachable( 572 "Subclasses must override this with a tablegen-erated function"); 573 } 574 virtual bool testMIPredicate_MI(unsigned, const MachineInstr &, 575 const MatcherState &State) const { 576 llvm_unreachable( 577 "Subclasses must override this with a tablegen-erated function"); 578 } 579 580 virtual bool testSimplePredicate(unsigned) const { 581 llvm_unreachable("Subclass does not implement testSimplePredicate!"); 582 } 583 584 virtual void runCustomAction(unsigned, const MatcherState &State) const { 585 llvm_unreachable("Subclass does not implement runCustomAction!"); 586 } 587 588 bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, 589 const MachineRegisterInfo &MRI) const; 590 591 /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on 592 /// the right-hand side. GlobalISel's separation of pointer and integer types 593 /// means that we don't need to worry about G_OR with equivalent semantics. 594 bool isBaseWithConstantOffset(const MachineOperand &Root, 595 const MachineRegisterInfo &MRI) const; 596 597 /// Return true if MI can obviously be folded into IntoMI. 598 /// MI and IntoMI do not need to be in the same basic blocks, but MI must 599 /// preceed IntoMI. 600 bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const; 601 }; 602 603 } // end namespace llvm 604 605 #endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTOR_H 606