1321369Sdim//===- llvm/CodeGen/GlobalISel/InstructionSelector.h ------------*- C++ -*-===//
2311116Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6311116Sdim//
7311116Sdim//===----------------------------------------------------------------------===//
8311116Sdim//
9311116Sdim/// \file This file declares the API for the instruction selector.
10311116Sdim/// This class is responsible for selecting machine instructions.
11311116Sdim/// It's implemented by the target. It's used by the InstructionSelect pass.
12311116Sdim//
13311116Sdim//===----------------------------------------------------------------------===//
14311116Sdim
15311116Sdim#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
16311116Sdim#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
17311116Sdim
18327952Sdim#include "llvm/ADT/DenseMap.h"
19327952Sdim#include "llvm/ADT/Optional.h"
20321369Sdim#include "llvm/ADT/SmallVector.h"
21327952Sdim#include "llvm/Support/CodeGenCoverage.h"
22341825Sdim#include "llvm/Support/LowLevelTypeImpl.h"
23321369Sdim#include <bitset>
24321369Sdim#include <cstddef>
25321369Sdim#include <cstdint>
26321369Sdim#include <functional>
27321369Sdim#include <initializer_list>
28321369Sdim#include <vector>
29321369Sdim
30311116Sdimnamespace llvm {
31321369Sdim
32327952Sdimclass APInt;
33327952Sdimclass APFloat;
34360784Sdimclass GISelKnownBits;
35311116Sdimclass MachineInstr;
36321369Sdimclass MachineInstrBuilder;
37327952Sdimclass MachineFunction;
38321369Sdimclass MachineOperand;
39321369Sdimclass MachineRegisterInfo;
40311116Sdimclass RegisterBankInfo;
41311116Sdimclass TargetInstrInfo;
42321369Sdimclass TargetRegisterClass;
43311116Sdimclass TargetRegisterInfo;
44311116Sdim
45321369Sdim/// Container class for CodeGen predicate results.
46321369Sdim/// This is convenient because std::bitset does not have a constructor
47321369Sdim/// with an initializer list of set bits.
48321369Sdim///
49321723Sdim/// Each InstructionSelector subclass should define a PredicateBitset class
50321723Sdim/// with:
51321369Sdim///   const unsigned MAX_SUBTARGET_PREDICATES = 192;
52321369Sdim///   using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
53321369Sdim/// and updating the constant to suit the target. Tablegen provides a suitable
54321369Sdim/// definition for the predicates in use in <Target>GenGlobalISel.inc when
55321369Sdim/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
56321369Sdimtemplate <std::size_t MaxPredicates>
57321369Sdimclass PredicateBitsetImpl : public std::bitset<MaxPredicates> {
58321369Sdimpublic:
59321369Sdim  // Cannot inherit constructors because it's not supported by VC++..
60321369Sdim  PredicateBitsetImpl() = default;
61321369Sdim
62321369Sdim  PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
63321369Sdim      : std::bitset<MaxPredicates>(B) {}
64321369Sdim
65321369Sdim  PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
66321369Sdim    for (auto I : Init)
67321369Sdim      std::bitset<MaxPredicates>::set(I);
68321369Sdim  }
69321369Sdim};
70321369Sdim
71321369Sdimenum {
72327952Sdim  /// Begin a try-block to attempt a match and jump to OnFail if it is
73327952Sdim  /// unsuccessful.
74327952Sdim  /// - OnFail - The MatchTable entry at which to resume if the match fails.
75327952Sdim  ///
76327952Sdim  /// FIXME: This ought to take an argument indicating the number of try-blocks
77327952Sdim  ///        to exit on failure. It's usually one but the last match attempt of
78327952Sdim  ///        a block will need more. The (implemented) alternative is to tack a
79327952Sdim  ///        GIM_Reject on the end of each try-block which is simpler but
80327952Sdim  ///        requires an extra opcode and iteration in the interpreter on each
81327952Sdim  ///        failed match.
82327952Sdim  GIM_Try,
83327952Sdim
84341825Sdim  /// Switch over the opcode on the specified instruction
85341825Sdim  /// - InsnID - Instruction ID
86341825Sdim  /// - LowerBound - numerically minimum opcode supported
87341825Sdim  /// - UpperBound - numerically maximum + 1 opcode supported
88341825Sdim  /// - Default - failure jump target
89341825Sdim  /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets
90341825Sdim  GIM_SwitchOpcode,
91341825Sdim
92341825Sdim  /// Switch over the LLT on the specified instruction operand
93341825Sdim  /// - InsnID - Instruction ID
94341825Sdim  /// - OpIdx - Operand index
95341825Sdim  /// - LowerBound - numerically minimum Type ID supported
96341825Sdim  /// - UpperBound - numerically maximum + 1 Type ID supported
97341825Sdim  /// - Default - failure jump target
98341825Sdim  /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets
99341825Sdim  GIM_SwitchType,
100341825Sdim
101321369Sdim  /// Record the specified instruction
102321369Sdim  /// - NewInsnID - Instruction ID to define
103321369Sdim  /// - InsnID - Instruction ID
104321369Sdim  /// - OpIdx - Operand index
105321369Sdim  GIM_RecordInsn,
106321369Sdim
107321369Sdim  /// Check the feature bits
108321369Sdim  /// - Expected features
109321369Sdim  GIM_CheckFeatures,
110321369Sdim
111321369Sdim  /// Check the opcode on the specified instruction
112321369Sdim  /// - InsnID - Instruction ID
113321369Sdim  /// - Expected opcode
114321369Sdim  GIM_CheckOpcode,
115321369Sdim  /// Check the instruction has the right number of operands
116321369Sdim  /// - InsnID - Instruction ID
117321369Sdim  /// - Expected number of operands
118321369Sdim  GIM_CheckNumOperands,
119327952Sdim  /// Check an immediate predicate on the specified instruction
120327952Sdim  /// - InsnID - Instruction ID
121327952Sdim  /// - The predicate to test
122327952Sdim  GIM_CheckI64ImmPredicate,
123327952Sdim  /// Check an immediate predicate on the specified instruction via an APInt.
124327952Sdim  /// - InsnID - Instruction ID
125327952Sdim  /// - The predicate to test
126327952Sdim  GIM_CheckAPIntImmPredicate,
127327952Sdim  /// Check a floating point immediate predicate on the specified instruction.
128327952Sdim  /// - InsnID - Instruction ID
129327952Sdim  /// - The predicate to test
130327952Sdim  GIM_CheckAPFloatImmPredicate,
131327952Sdim  /// Check a memory operation has the specified atomic ordering.
132327952Sdim  /// - InsnID - Instruction ID
133327952Sdim  /// - Ordering - The AtomicOrdering value
134327952Sdim  GIM_CheckAtomicOrdering,
135327952Sdim  GIM_CheckAtomicOrderingOrStrongerThan,
136327952Sdim  GIM_CheckAtomicOrderingWeakerThan,
137341825Sdim  /// Check the size of the memory access for the given machine memory operand.
138341825Sdim  /// - InsnID - Instruction ID
139341825Sdim  /// - MMOIdx - MMO index
140341825Sdim  /// - Size - The size in bytes of the memory access
141341825Sdim  GIM_CheckMemorySizeEqualTo,
142353358Sdim
143353358Sdim  /// Check the address space of the memory access for the given machine memory
144353358Sdim  /// operand.
145353358Sdim  /// - InsnID - Instruction ID
146353358Sdim  /// - MMOIdx - MMO index
147353358Sdim  /// - NumAddrSpace - Number of valid address spaces
148353358Sdim  /// - AddrSpaceN - An allowed space of the memory access
149353358Sdim  /// - AddrSpaceN+1 ...
150353358Sdim  GIM_CheckMemoryAddressSpace,
151353358Sdim
152360784Sdim  /// Check the minimum alignment of the memory access for the given machine
153360784Sdim  /// memory operand.
154360784Sdim  /// - InsnID - Instruction ID
155360784Sdim  /// - MMOIdx - MMO index
156360784Sdim  /// - MinAlign - Minimum acceptable alignment
157360784Sdim  GIM_CheckMemoryAlignment,
158360784Sdim
159341825Sdim  /// Check the size of the memory access for the given machine memory operand
160341825Sdim  /// against the size of an operand.
161341825Sdim  /// - InsnID - Instruction ID
162341825Sdim  /// - MMOIdx - MMO index
163341825Sdim  /// - OpIdx - The operand index to compare the MMO against
164341825Sdim  GIM_CheckMemorySizeEqualToLLT,
165341825Sdim  GIM_CheckMemorySizeLessThanLLT,
166341825Sdim  GIM_CheckMemorySizeGreaterThanLLT,
167341825Sdim  /// Check a generic C++ instruction predicate
168341825Sdim  /// - InsnID - Instruction ID
169341825Sdim  /// - PredicateID - The ID of the predicate function to call
170341825Sdim  GIM_CheckCxxInsnPredicate,
171321369Sdim
172321369Sdim  /// Check the type for the specified operand
173321369Sdim  /// - InsnID - Instruction ID
174321369Sdim  /// - OpIdx - Operand index
175321369Sdim  /// - Expected type
176321369Sdim  GIM_CheckType,
177327952Sdim  /// Check the type of a pointer to any address space.
178327952Sdim  /// - InsnID - Instruction ID
179327952Sdim  /// - OpIdx - Operand index
180327952Sdim  /// - SizeInBits - The size of the pointer value in bits.
181327952Sdim  GIM_CheckPointerToAny,
182321369Sdim  /// Check the register bank for the specified operand
183321369Sdim  /// - InsnID - Instruction ID
184321369Sdim  /// - OpIdx - Operand index
185321369Sdim  /// - Expected register bank (specified as a register class)
186321369Sdim  GIM_CheckRegBankForClass,
187341825Sdim
188321369Sdim  /// Check the operand matches a complex predicate
189321369Sdim  /// - InsnID - Instruction ID
190321369Sdim  /// - OpIdx - Operand index
191321369Sdim  /// - RendererID - The renderer to hold the result
192321369Sdim  /// - Complex predicate ID
193321369Sdim  GIM_CheckComplexPattern,
194341825Sdim
195321369Sdim  /// Check the operand is a specific integer
196321369Sdim  /// - InsnID - Instruction ID
197321369Sdim  /// - OpIdx - Operand index
198321369Sdim  /// - Expected integer
199321369Sdim  GIM_CheckConstantInt,
200321723Sdim  /// Check the operand is a specific literal integer (i.e. MO.isImm() or
201321723Sdim  /// MO.isCImm() is true).
202321369Sdim  /// - InsnID - Instruction ID
203321369Sdim  /// - OpIdx - Operand index
204321369Sdim  /// - Expected integer
205321369Sdim  GIM_CheckLiteralInt,
206321369Sdim  /// Check the operand is a specific intrinsic ID
207321369Sdim  /// - InsnID - Instruction ID
208321369Sdim  /// - OpIdx - Operand index
209321369Sdim  /// - Expected Intrinsic ID
210321369Sdim  GIM_CheckIntrinsicID,
211341825Sdim
212360784Sdim  /// Check the operand is a specific predicate
213360784Sdim  /// - InsnID - Instruction ID
214360784Sdim  /// - OpIdx - Operand index
215360784Sdim  /// - Expected predicate
216360784Sdim  GIM_CheckCmpPredicate,
217360784Sdim
218321369Sdim  /// Check the specified operand is an MBB
219321369Sdim  /// - InsnID - Instruction ID
220321369Sdim  /// - OpIdx - Operand index
221321369Sdim  GIM_CheckIsMBB,
222321369Sdim
223360784Sdim  /// Check the specified operand is an Imm
224360784Sdim  /// - InsnID - Instruction ID
225360784Sdim  /// - OpIdx - Operand index
226360784Sdim  GIM_CheckIsImm,
227360784Sdim
228321369Sdim  /// Check if the specified operand is safe to fold into the current
229321369Sdim  /// instruction.
230321369Sdim  /// - InsnID - Instruction ID
231321369Sdim  GIM_CheckIsSafeToFold,
232321369Sdim
233327952Sdim  /// Check the specified operands are identical.
234327952Sdim  /// - InsnID - Instruction ID
235327952Sdim  /// - OpIdx - Operand index
236327952Sdim  /// - OtherInsnID - Other instruction ID
237327952Sdim  /// - OtherOpIdx - Other operand index
238327952Sdim  GIM_CheckIsSameOperand,
239327952Sdim
240327952Sdim  /// Fail the current try-block, or completely fail to match if there is no
241327952Sdim  /// current try-block.
242327952Sdim  GIM_Reject,
243327952Sdim
244321369Sdim  //=== Renderers ===
245321369Sdim
246321369Sdim  /// Mutate an instruction
247321369Sdim  /// - NewInsnID - Instruction ID to define
248321369Sdim  /// - OldInsnID - Instruction ID to mutate
249321369Sdim  /// - NewOpcode - The new opcode to use
250321369Sdim  GIR_MutateOpcode,
251341825Sdim
252321369Sdim  /// Build a new instruction
253321369Sdim  /// - InsnID - Instruction ID to define
254321369Sdim  /// - Opcode - The new opcode to use
255321369Sdim  GIR_BuildMI,
256321369Sdim
257321369Sdim  /// Copy an operand to the specified instruction
258321369Sdim  /// - NewInsnID - Instruction ID to modify
259321369Sdim  /// - OldInsnID - Instruction ID to copy from
260321369Sdim  /// - OpIdx - The operand to copy
261321369Sdim  GIR_Copy,
262341825Sdim
263327952Sdim  /// Copy an operand to the specified instruction or add a zero register if the
264327952Sdim  /// operand is a zero immediate.
265327952Sdim  /// - NewInsnID - Instruction ID to modify
266327952Sdim  /// - OldInsnID - Instruction ID to copy from
267327952Sdim  /// - OpIdx - The operand to copy
268327952Sdim  /// - ZeroReg - The zero register to use
269327952Sdim  GIR_CopyOrAddZeroReg,
270321369Sdim  /// Copy an operand to the specified instruction
271321369Sdim  /// - NewInsnID - Instruction ID to modify
272321369Sdim  /// - OldInsnID - Instruction ID to copy from
273321369Sdim  /// - OpIdx - The operand to copy
274321369Sdim  /// - SubRegIdx - The subregister to copy
275321369Sdim  GIR_CopySubReg,
276341825Sdim
277321369Sdim  /// Add an implicit register def to the specified instruction
278321369Sdim  /// - InsnID - Instruction ID to modify
279321369Sdim  /// - RegNum - The register to add
280321369Sdim  GIR_AddImplicitDef,
281321369Sdim  /// Add an implicit register use to the specified instruction
282321369Sdim  /// - InsnID - Instruction ID to modify
283321369Sdim  /// - RegNum - The register to add
284321369Sdim  GIR_AddImplicitUse,
285321369Sdim  /// Add an register to the specified instruction
286321369Sdim  /// - InsnID - Instruction ID to modify
287321369Sdim  /// - RegNum - The register to add
288321369Sdim  GIR_AddRegister,
289341825Sdim
290341825Sdim  /// Add a temporary register to the specified instruction
291327952Sdim  /// - InsnID - Instruction ID to modify
292327952Sdim  /// - TempRegID - The temporary register ID to add
293341825Sdim  /// - TempRegFlags - The register flags to set
294327952Sdim  GIR_AddTempRegister,
295341825Sdim
296321369Sdim  /// Add an immediate to the specified instruction
297321369Sdim  /// - InsnID - Instruction ID to modify
298321369Sdim  /// - Imm - The immediate to add
299321369Sdim  GIR_AddImm,
300321369Sdim  /// Render complex operands to the specified instruction
301321369Sdim  /// - InsnID - Instruction ID to modify
302321369Sdim  /// - RendererID - The renderer to call
303321369Sdim  GIR_ComplexRenderer,
304341825Sdim
305327952Sdim  /// Render sub-operands of complex operands to the specified instruction
306327952Sdim  /// - InsnID - Instruction ID to modify
307327952Sdim  /// - RendererID - The renderer to call
308327952Sdim  /// - RenderOpID - The suboperand to render.
309327952Sdim  GIR_ComplexSubOperandRenderer,
310341825Sdim  /// Render operands to the specified instruction using a custom function
311341825Sdim  /// - InsnID - Instruction ID to modify
312341825Sdim  /// - OldInsnID - Instruction ID to get the matched operand from
313341825Sdim  /// - RendererFnID - Custom renderer function to call
314341825Sdim  GIR_CustomRenderer,
315321369Sdim
316360784Sdim  /// Render operands to the specified instruction using a custom function,
317360784Sdim  /// reading from a specific operand.
318360784Sdim  /// - InsnID - Instruction ID to modify
319360784Sdim  /// - OldInsnID - Instruction ID to get the matched operand from
320360784Sdim  /// - OpIdx - Operand index in OldInsnID the render function should read from..
321360784Sdim  /// - RendererFnID - Custom renderer function to call
322360784Sdim  GIR_CustomOperandRenderer,
323360784Sdim
324327952Sdim  /// Render a G_CONSTANT operator as a sign-extended immediate.
325327952Sdim  /// - NewInsnID - Instruction ID to modify
326327952Sdim  /// - OldInsnID - Instruction ID to copy from
327327952Sdim  /// The operand index is implicitly 1.
328327952Sdim  GIR_CopyConstantAsSImm,
329327952Sdim
330341825Sdim  /// Render a G_FCONSTANT operator as a sign-extended immediate.
331341825Sdim  /// - NewInsnID - Instruction ID to modify
332341825Sdim  /// - OldInsnID - Instruction ID to copy from
333341825Sdim  /// The operand index is implicitly 1.
334341825Sdim  GIR_CopyFConstantAsFPImm,
335341825Sdim
336321369Sdim  /// Constrain an instruction operand to a register class.
337321369Sdim  /// - InsnID - Instruction ID to modify
338321369Sdim  /// - OpIdx - Operand index
339321369Sdim  /// - RCEnum - Register class enumeration value
340321369Sdim  GIR_ConstrainOperandRC,
341341825Sdim
342321369Sdim  /// Constrain an instructions operands according to the instruction
343321369Sdim  /// description.
344321369Sdim  /// - InsnID - Instruction ID to modify
345321369Sdim  GIR_ConstrainSelectedInstOperands,
346341825Sdim
347321369Sdim  /// Merge all memory operands into instruction.
348321369Sdim  /// - InsnID - Instruction ID to modify
349327952Sdim  /// - MergeInsnID... - One or more Instruction ID to merge into the result.
350327952Sdim  /// - GIU_MergeMemOperands_EndOfList - Terminates the list of instructions to
351327952Sdim  ///                                    merge.
352321369Sdim  GIR_MergeMemOperands,
353341825Sdim
354321369Sdim  /// Erase from parent.
355321369Sdim  /// - InsnID - Instruction ID to erase
356321369Sdim  GIR_EraseFromParent,
357341825Sdim
358327952Sdim  /// Create a new temporary register that's not constrained.
359327952Sdim  /// - TempRegID - The temporary register ID to initialize.
360327952Sdim  /// - Expected type
361327952Sdim  GIR_MakeTempReg,
362321369Sdim
363321369Sdim  /// A successful emission
364321369Sdim  GIR_Done,
365327952Sdim
366327952Sdim  /// Increment the rule coverage counter.
367327952Sdim  /// - RuleID - The ID of the rule that was covered.
368327952Sdim  GIR_Coverage,
369341825Sdim
370341825Sdim  /// Keeping track of the number of the GI opcodes. Must be the last entry.
371341825Sdim  GIU_NumOpcodes,
372321369Sdim};
373321369Sdim
374327952Sdimenum {
375327952Sdim  /// Indicates the end of the variable-length MergeInsnID list in a
376327952Sdim  /// GIR_MergeMemOperands opcode.
377327952Sdim  GIU_MergeMemOperands_EndOfList = -1,
378327952Sdim};
379327952Sdim
380311116Sdim/// Provides the logic to select generic machine instructions.
381311116Sdimclass InstructionSelector {
382311116Sdimpublic:
383321369Sdim  virtual ~InstructionSelector() = default;
384311116Sdim
385311116Sdim  /// Select the (possibly generic) instruction \p I to only use target-specific
386311116Sdim  /// opcodes. It is OK to insert multiple instructions, but they cannot be
387311116Sdim  /// generic pre-isel instructions.
388311116Sdim  ///
389311116Sdim  /// \returns whether selection succeeded.
390311116Sdim  /// \pre  I.getParent() && I.getParent()->getParent()
391311116Sdim  /// \post
392311116Sdim  ///   if returns true:
393311116Sdim  ///     for I in all mutated/inserted instructions:
394311116Sdim  ///       !isPreISelGenericOpcode(I.getOpcode())
395360784Sdim  virtual bool select(MachineInstr &I) = 0;
396311116Sdim
397360784Sdim  CodeGenCoverage *CoverageInfo = nullptr;
398360784Sdim  GISelKnownBits *KnownBits = nullptr;
399360784Sdim  MachineFunction *MF = nullptr;
400360784Sdim
401360784Sdim  virtual void setupGeneratedPerFunctionState(MachineFunction &MF) {
402360784Sdim    llvm_unreachable("TableGen should have emitted implementation");
403360784Sdim  }
404360784Sdim
405360784Sdim  /// Setup per-MF selector state.
406360784Sdim  virtual void setupMF(MachineFunction &mf,
407360784Sdim                       GISelKnownBits &KB,
408360784Sdim                       CodeGenCoverage &covinfo) {
409360784Sdim    CoverageInfo = &covinfo;
410360784Sdim    KnownBits = &KB;
411360784Sdim    MF = &mf;
412360784Sdim    setupGeneratedPerFunctionState(mf);
413360784Sdim  }
414360784Sdim
415311116Sdimprotected:
416327952Sdim  using ComplexRendererFns =
417327952Sdim      Optional<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>;
418321369Sdim  using RecordedMIVector = SmallVector<MachineInstr *, 4>;
419321369Sdim  using NewMIVector = SmallVector<MachineInstrBuilder, 4>;
420321369Sdim
421321369Sdim  struct MatcherState {
422327952Sdim    std::vector<ComplexRendererFns::value_type> Renderers;
423321369Sdim    RecordedMIVector MIs;
424327952Sdim    DenseMap<unsigned, unsigned> TempRegisters;
425321369Sdim
426321369Sdim    MatcherState(unsigned MaxRenderers);
427321369Sdim  };
428321369Sdim
429321369Sdimpublic:
430341825Sdim  template <class PredicateBitset, class ComplexMatcherMemFn,
431341825Sdim            class CustomRendererFn>
432341825Sdim  struct ISelInfoTy {
433341825Sdim    ISelInfoTy(const LLT *TypeObjects, size_t NumTypeObjects,
434341825Sdim               const PredicateBitset *FeatureBitsets,
435341825Sdim               const ComplexMatcherMemFn *ComplexPredicates,
436341825Sdim               const CustomRendererFn *CustomRenderers)
437341825Sdim        : TypeObjects(TypeObjects),
438341825Sdim          FeatureBitsets(FeatureBitsets),
439341825Sdim          ComplexPredicates(ComplexPredicates),
440341825Sdim          CustomRenderers(CustomRenderers) {
441341825Sdim
442341825Sdim      for (size_t I = 0; I < NumTypeObjects; ++I)
443341825Sdim        TypeIDMap[TypeObjects[I]] = I;
444341825Sdim    }
445321369Sdim    const LLT *TypeObjects;
446321369Sdim    const PredicateBitset *FeatureBitsets;
447327952Sdim    const ComplexMatcherMemFn *ComplexPredicates;
448341825Sdim    const CustomRendererFn *CustomRenderers;
449341825Sdim
450341825Sdim    SmallDenseMap<LLT, unsigned, 64> TypeIDMap;
451321369Sdim  };
452321369Sdim
453321369Sdimprotected:
454311116Sdim  InstructionSelector();
455311116Sdim
456321369Sdim  /// Execute a given matcher table and return true if the match was successful
457321369Sdim  /// and false otherwise.
458321369Sdim  template <class TgtInstructionSelector, class PredicateBitset,
459341825Sdim            class ComplexMatcherMemFn, class CustomRendererFn>
460321369Sdim  bool executeMatchTable(
461321369Sdim      TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
462341825Sdim      const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
463341825Sdim          &ISelInfo,
464321369Sdim      const int64_t *MatchTable, const TargetInstrInfo &TII,
465321369Sdim      MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
466327952Sdim      const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
467327952Sdim      CodeGenCoverage &CoverageInfo) const;
468321369Sdim
469341825Sdim  virtual const int64_t *getMatchTable() const {
470341825Sdim    llvm_unreachable("Should have been overridden by tablegen if used");
471341825Sdim  }
472341825Sdim
473327952Sdim  virtual bool testImmPredicate_I64(unsigned, int64_t) const {
474341825Sdim    llvm_unreachable(
475341825Sdim        "Subclasses must override this with a tablegen-erated function");
476327952Sdim  }
477327952Sdim  virtual bool testImmPredicate_APInt(unsigned, const APInt &) const {
478341825Sdim    llvm_unreachable(
479341825Sdim        "Subclasses must override this with a tablegen-erated function");
480327952Sdim  }
481327952Sdim  virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const {
482341825Sdim    llvm_unreachable(
483341825Sdim        "Subclasses must override this with a tablegen-erated function");
484327952Sdim  }
485341825Sdim  virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const {
486341825Sdim    llvm_unreachable(
487341825Sdim        "Subclasses must override this with a tablegen-erated function");
488341825Sdim  }
489327952Sdim
490321369Sdim  /// Constrain a register operand of an instruction \p I to a specified
491321369Sdim  /// register class. This could involve inserting COPYs before (for uses) or
492321369Sdim  /// after (for defs) and may replace the operand of \p I.
493321369Sdim  /// \returns whether operand regclass constraining succeeded.
494321369Sdim  bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx,
495321369Sdim                                     const TargetRegisterClass &RC,
496321369Sdim                                     const TargetInstrInfo &TII,
497321369Sdim                                     const TargetRegisterInfo &TRI,
498321369Sdim                                     const RegisterBankInfo &RBI) const;
499321369Sdim
500321369Sdim  bool isOperandImmEqual(const MachineOperand &MO, int64_t Value,
501321369Sdim                         const MachineRegisterInfo &MRI) const;
502321369Sdim
503360784Sdim  /// Return true if the specified operand is a G_PTR_ADD with a G_CONSTANT on the
504327952Sdim  /// right-hand side. GlobalISel's separation of pointer and integer types
505327952Sdim  /// means that we don't need to worry about G_OR with equivalent semantics.
506327952Sdim  bool isBaseWithConstantOffset(const MachineOperand &Root,
507327952Sdim                                const MachineRegisterInfo &MRI) const;
508327952Sdim
509327952Sdim  /// Return true if MI can obviously be folded into IntoMI.
510327952Sdim  /// MI and IntoMI do not need to be in the same basic blocks, but MI must
511327952Sdim  /// preceed IntoMI.
512327952Sdim  bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const;
513311116Sdim};
514311116Sdim
515321369Sdim} // end namespace llvm
516311116Sdim
517321369Sdim#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
518