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