InstructionSelectorImpl.h revision 360784
1//===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.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 API for the instruction selector.
10/// This class is responsible for selecting machine instructions.
11/// It's implemented by the target. It's used by the InstructionSelect pass.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
16#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
17
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
20#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
21#include "llvm/CodeGen/GlobalISel/Utils.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23#include "llvm/CodeGen/MachineOperand.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#include "llvm/CodeGen/TargetInstrInfo.h"
26#include "llvm/CodeGen/TargetOpcodes.h"
27#include "llvm/CodeGen/TargetRegisterInfo.h"
28#include "llvm/IR/Constants.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/Support/Debug.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/raw_ostream.h"
33#include <cassert>
34#include <cstddef>
35#include <cstdint>
36
37namespace llvm {
38
39/// GlobalISel PatFrag Predicates
40enum {
41  GIPFP_I64_Invalid = 0,
42  GIPFP_APInt_Invalid = 0,
43  GIPFP_APFloat_Invalid = 0,
44  GIPFP_MI_Invalid = 0,
45};
46
47template <class TgtInstructionSelector, class PredicateBitset,
48          class ComplexMatcherMemFn, class CustomRendererFn>
49bool InstructionSelector::executeMatchTable(
50    TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
51    const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
52        &ISelInfo,
53    const int64_t *MatchTable, const TargetInstrInfo &TII,
54    MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
55    const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
56    CodeGenCoverage &CoverageInfo) const {
57
58  uint64_t CurrentIdx = 0;
59  SmallVector<uint64_t, 4> OnFailResumeAt;
60
61  enum RejectAction { RejectAndGiveUp, RejectAndResume };
62  auto handleReject = [&]() -> RejectAction {
63    DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
64                    dbgs() << CurrentIdx << ": Rejected\n");
65    if (OnFailResumeAt.empty())
66      return RejectAndGiveUp;
67    CurrentIdx = OnFailResumeAt.pop_back_val();
68    DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
69                    dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
70                           << OnFailResumeAt.size() << " try-blocks remain)\n");
71    return RejectAndResume;
72  };
73
74  while (true) {
75    assert(CurrentIdx != ~0u && "Invalid MatchTable index");
76    int64_t MatcherOpcode = MatchTable[CurrentIdx++];
77    switch (MatcherOpcode) {
78    case GIM_Try: {
79      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
80                      dbgs() << CurrentIdx << ": Begin try-block\n");
81      OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
82      break;
83    }
84
85    case GIM_RecordInsn: {
86      int64_t NewInsnID = MatchTable[CurrentIdx++];
87      int64_t InsnID = MatchTable[CurrentIdx++];
88      int64_t OpIdx = MatchTable[CurrentIdx++];
89
90      // As an optimisation we require that MIs[0] is always the root. Refuse
91      // any attempt to modify it.
92      assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
93
94      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
95      if (!MO.isReg()) {
96        DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
97                        dbgs() << CurrentIdx << ": Not a register\n");
98        if (handleReject() == RejectAndGiveUp)
99          return false;
100        break;
101      }
102      if (Register::isPhysicalRegister(MO.getReg())) {
103        DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
104                        dbgs() << CurrentIdx << ": Is a physical register\n");
105        if (handleReject() == RejectAndGiveUp)
106          return false;
107        break;
108      }
109
110      MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
111      if ((size_t)NewInsnID < State.MIs.size())
112        State.MIs[NewInsnID] = NewMI;
113      else {
114        assert((size_t)NewInsnID == State.MIs.size() &&
115               "Expected to store MIs in order");
116        State.MIs.push_back(NewMI);
117      }
118      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
119                      dbgs() << CurrentIdx << ": MIs[" << NewInsnID
120                             << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
121                             << ")\n");
122      break;
123    }
124
125    case GIM_CheckFeatures: {
126      int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
127      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
128                      dbgs() << CurrentIdx
129                             << ": GIM_CheckFeatures(ExpectedBitsetID="
130                             << ExpectedBitsetID << ")\n");
131      if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
132          ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
133        if (handleReject() == RejectAndGiveUp)
134          return false;
135      }
136      break;
137    }
138
139    case GIM_CheckOpcode: {
140      int64_t InsnID = MatchTable[CurrentIdx++];
141      int64_t Expected = MatchTable[CurrentIdx++];
142
143      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
144      unsigned Opcode = State.MIs[InsnID]->getOpcode();
145
146      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
147                      dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
148                             << "], ExpectedOpcode=" << Expected
149                             << ") // Got=" << Opcode << "\n");
150      if (Opcode != Expected) {
151        if (handleReject() == RejectAndGiveUp)
152          return false;
153      }
154      break;
155    }
156
157    case GIM_SwitchOpcode: {
158      int64_t InsnID = MatchTable[CurrentIdx++];
159      int64_t LowerBound = MatchTable[CurrentIdx++];
160      int64_t UpperBound = MatchTable[CurrentIdx++];
161      int64_t Default = MatchTable[CurrentIdx++];
162
163      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
164      const int64_t Opcode = State.MIs[InsnID]->getOpcode();
165
166      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
167        dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
168               << LowerBound << ", " << UpperBound << "), Default=" << Default
169               << ", JumpTable...) // Got=" << Opcode << "\n";
170      });
171      if (Opcode < LowerBound || UpperBound <= Opcode) {
172        CurrentIdx = Default;
173        break;
174      }
175      CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
176      if (!CurrentIdx) {
177        CurrentIdx = Default;
178	break;
179      }
180      OnFailResumeAt.push_back(Default);
181      break;
182    }
183
184    case GIM_SwitchType: {
185      int64_t InsnID = MatchTable[CurrentIdx++];
186      int64_t OpIdx = MatchTable[CurrentIdx++];
187      int64_t LowerBound = MatchTable[CurrentIdx++];
188      int64_t UpperBound = MatchTable[CurrentIdx++];
189      int64_t Default = MatchTable[CurrentIdx++];
190
191      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
192      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
193
194      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
195        dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
196               << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
197               << UpperBound << "), Default=" << Default
198               << ", JumpTable...) // Got=";
199        if (!MO.isReg())
200          dbgs() << "Not a VReg\n";
201        else
202          dbgs() << MRI.getType(MO.getReg()) << "\n";
203      });
204      if (!MO.isReg()) {
205        CurrentIdx = Default;
206        break;
207      }
208      const LLT Ty = MRI.getType(MO.getReg());
209      const auto TyI = ISelInfo.TypeIDMap.find(Ty);
210      if (TyI == ISelInfo.TypeIDMap.end()) {
211        CurrentIdx = Default;
212        break;
213      }
214      const int64_t TypeID = TyI->second;
215      if (TypeID < LowerBound || UpperBound <= TypeID) {
216        CurrentIdx = Default;
217        break;
218      }
219      CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
220      if (!CurrentIdx) {
221        CurrentIdx = Default;
222        break;
223      }
224      OnFailResumeAt.push_back(Default);
225      break;
226    }
227
228    case GIM_CheckNumOperands: {
229      int64_t InsnID = MatchTable[CurrentIdx++];
230      int64_t Expected = MatchTable[CurrentIdx++];
231      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
232                      dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
233                             << InsnID << "], Expected=" << Expected << ")\n");
234      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
235      if (State.MIs[InsnID]->getNumOperands() != Expected) {
236        if (handleReject() == RejectAndGiveUp)
237          return false;
238      }
239      break;
240    }
241    case GIM_CheckI64ImmPredicate: {
242      int64_t InsnID = MatchTable[CurrentIdx++];
243      int64_t Predicate = MatchTable[CurrentIdx++];
244      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
245                      dbgs()
246                          << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
247                          << InsnID << "], Predicate=" << Predicate << ")\n");
248      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
249      assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
250             "Expected G_CONSTANT");
251      assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
252      int64_t Value = 0;
253      if (State.MIs[InsnID]->getOperand(1).isCImm())
254        Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
255      else if (State.MIs[InsnID]->getOperand(1).isImm())
256        Value = State.MIs[InsnID]->getOperand(1).getImm();
257      else
258        llvm_unreachable("Expected Imm or CImm operand");
259
260      if (!testImmPredicate_I64(Predicate, Value))
261        if (handleReject() == RejectAndGiveUp)
262          return false;
263      break;
264    }
265    case GIM_CheckAPIntImmPredicate: {
266      int64_t InsnID = MatchTable[CurrentIdx++];
267      int64_t Predicate = MatchTable[CurrentIdx++];
268      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
269                      dbgs()
270                          << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
271                          << InsnID << "], Predicate=" << Predicate << ")\n");
272      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
273      assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
274             "Expected G_CONSTANT");
275      assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
276      APInt Value;
277      if (State.MIs[InsnID]->getOperand(1).isCImm())
278        Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
279      else
280        llvm_unreachable("Expected Imm or CImm operand");
281
282      if (!testImmPredicate_APInt(Predicate, Value))
283        if (handleReject() == RejectAndGiveUp)
284          return false;
285      break;
286    }
287    case GIM_CheckAPFloatImmPredicate: {
288      int64_t InsnID = MatchTable[CurrentIdx++];
289      int64_t Predicate = MatchTable[CurrentIdx++];
290      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
291                      dbgs()
292                          << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
293                          << InsnID << "], Predicate=" << Predicate << ")\n");
294      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
295      assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
296             "Expected G_FCONSTANT");
297      assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
298      assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
299      APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
300
301      if (!testImmPredicate_APFloat(Predicate, Value))
302        if (handleReject() == RejectAndGiveUp)
303          return false;
304      break;
305    }
306    case GIM_CheckCxxInsnPredicate: {
307      int64_t InsnID = MatchTable[CurrentIdx++];
308      int64_t Predicate = MatchTable[CurrentIdx++];
309      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
310                      dbgs()
311                          << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
312                          << InsnID << "], Predicate=" << Predicate << ")\n");
313      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
314      assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
315
316      if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID]))
317        if (handleReject() == RejectAndGiveUp)
318          return false;
319      break;
320    }
321    case GIM_CheckAtomicOrdering: {
322      int64_t InsnID = MatchTable[CurrentIdx++];
323      AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
324      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
325                      dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
326                             << InsnID << "], " << (uint64_t)Ordering << ")\n");
327      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
328      if (!State.MIs[InsnID]->hasOneMemOperand())
329        if (handleReject() == RejectAndGiveUp)
330          return false;
331
332      for (const auto &MMO : State.MIs[InsnID]->memoperands())
333        if (MMO->getOrdering() != Ordering)
334          if (handleReject() == RejectAndGiveUp)
335            return false;
336      break;
337    }
338    case GIM_CheckAtomicOrderingOrStrongerThan: {
339      int64_t InsnID = MatchTable[CurrentIdx++];
340      AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
341      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
342                      dbgs() << CurrentIdx
343                             << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
344                             << InsnID << "], " << (uint64_t)Ordering << ")\n");
345      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
346      if (!State.MIs[InsnID]->hasOneMemOperand())
347        if (handleReject() == RejectAndGiveUp)
348          return false;
349
350      for (const auto &MMO : State.MIs[InsnID]->memoperands())
351        if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering))
352          if (handleReject() == RejectAndGiveUp)
353            return false;
354      break;
355    }
356    case GIM_CheckAtomicOrderingWeakerThan: {
357      int64_t InsnID = MatchTable[CurrentIdx++];
358      AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
359      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
360                      dbgs() << CurrentIdx
361                             << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
362                             << InsnID << "], " << (uint64_t)Ordering << ")\n");
363      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
364      if (!State.MIs[InsnID]->hasOneMemOperand())
365        if (handleReject() == RejectAndGiveUp)
366          return false;
367
368      for (const auto &MMO : State.MIs[InsnID]->memoperands())
369        if (!isStrongerThan(Ordering, MMO->getOrdering()))
370          if (handleReject() == RejectAndGiveUp)
371            return false;
372      break;
373    }
374    case GIM_CheckMemoryAddressSpace: {
375      int64_t InsnID = MatchTable[CurrentIdx++];
376      int64_t MMOIdx = MatchTable[CurrentIdx++];
377      // This accepts a list of possible address spaces.
378      const int NumAddrSpace = MatchTable[CurrentIdx++];
379
380      if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
381        if (handleReject() == RejectAndGiveUp)
382          return false;
383        break;
384      }
385
386      // Need to still jump to the end of the list of address spaces if we find
387      // a match earlier.
388      const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
389
390      const MachineMemOperand *MMO
391        = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
392      const unsigned MMOAddrSpace = MMO->getAddrSpace();
393
394      bool Success = false;
395      for (int I = 0; I != NumAddrSpace; ++I) {
396        unsigned AddrSpace = MatchTable[CurrentIdx++];
397        DEBUG_WITH_TYPE(
398          TgtInstructionSelector::getName(),
399          dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
400                 << AddrSpace << '\n');
401
402        if (AddrSpace == MMOAddrSpace) {
403          Success = true;
404          break;
405        }
406      }
407
408      CurrentIdx = LastIdx;
409      if (!Success && handleReject() == RejectAndGiveUp)
410        return false;
411      break;
412    }
413    case GIM_CheckMemoryAlignment: {
414      int64_t InsnID = MatchTable[CurrentIdx++];
415      int64_t MMOIdx = MatchTable[CurrentIdx++];
416      unsigned MinAlign = MatchTable[CurrentIdx++];
417
418      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
419
420      if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
421        if (handleReject() == RejectAndGiveUp)
422          return false;
423        break;
424      }
425
426      MachineMemOperand *MMO
427        = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
428      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
429                      dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
430                      << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
431                      << ")->getAlignment() >= " << MinAlign << ")\n");
432      if (MMO->getAlignment() < MinAlign && handleReject() == RejectAndGiveUp)
433        return false;
434
435      break;
436    }
437    case GIM_CheckMemorySizeEqualTo: {
438      int64_t InsnID = MatchTable[CurrentIdx++];
439      int64_t MMOIdx = MatchTable[CurrentIdx++];
440      uint64_t Size = MatchTable[CurrentIdx++];
441
442      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
443                      dbgs() << CurrentIdx
444                             << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
445                             << "]->memoperands() + " << MMOIdx
446                             << ", Size=" << Size << ")\n");
447      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
448
449      if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
450        if (handleReject() == RejectAndGiveUp)
451          return false;
452        break;
453      }
454
455      MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
456
457      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
458                      dbgs() << MMO->getSize() << " bytes vs " << Size
459                             << " bytes\n");
460      if (MMO->getSize() != Size)
461        if (handleReject() == RejectAndGiveUp)
462          return false;
463
464      break;
465    }
466    case GIM_CheckMemorySizeEqualToLLT:
467    case GIM_CheckMemorySizeLessThanLLT:
468    case GIM_CheckMemorySizeGreaterThanLLT: {
469      int64_t InsnID = MatchTable[CurrentIdx++];
470      int64_t MMOIdx = MatchTable[CurrentIdx++];
471      int64_t OpIdx = MatchTable[CurrentIdx++];
472
473      DEBUG_WITH_TYPE(
474          TgtInstructionSelector::getName(),
475          dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
476                 << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
477                         ? "EqualTo"
478                         : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
479                               ? "GreaterThan"
480                               : "LessThan")
481                 << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
482                 << ", OpIdx=" << OpIdx << ")\n");
483      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
484
485      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
486      if (!MO.isReg()) {
487        DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
488                        dbgs() << CurrentIdx << ": Not a register\n");
489        if (handleReject() == RejectAndGiveUp)
490          return false;
491        break;
492      }
493
494      if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
495        if (handleReject() == RejectAndGiveUp)
496          return false;
497        break;
498      }
499
500      MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
501
502      unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
503      if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
504          MMO->getSizeInBits() != Size) {
505        if (handleReject() == RejectAndGiveUp)
506          return false;
507      } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
508                 MMO->getSizeInBits() >= Size) {
509        if (handleReject() == RejectAndGiveUp)
510          return false;
511      } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
512                 MMO->getSizeInBits() <= Size)
513        if (handleReject() == RejectAndGiveUp)
514          return false;
515
516      break;
517    }
518    case GIM_CheckType: {
519      int64_t InsnID = MatchTable[CurrentIdx++];
520      int64_t OpIdx = MatchTable[CurrentIdx++];
521      int64_t TypeID = MatchTable[CurrentIdx++];
522      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
523                      dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
524                             << "]->getOperand(" << OpIdx
525                             << "), TypeID=" << TypeID << ")\n");
526      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
527      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
528      if (!MO.isReg() ||
529          MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
530        if (handleReject() == RejectAndGiveUp)
531          return false;
532      }
533      break;
534    }
535    case GIM_CheckPointerToAny: {
536      int64_t InsnID = MatchTable[CurrentIdx++];
537      int64_t OpIdx = MatchTable[CurrentIdx++];
538      int64_t SizeInBits = MatchTable[CurrentIdx++];
539
540      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
541                      dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
542                             << InsnID << "]->getOperand(" << OpIdx
543                             << "), SizeInBits=" << SizeInBits << ")\n");
544      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
545      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
546      const LLT Ty = MRI.getType(MO.getReg());
547
548      // iPTR must be looked up in the target.
549      if (SizeInBits == 0) {
550        MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
551        const unsigned AddrSpace = Ty.getAddressSpace();
552        SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
553      }
554
555      assert(SizeInBits != 0 && "Pointer size must be known");
556
557      if (MO.isReg()) {
558        if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
559          if (handleReject() == RejectAndGiveUp)
560            return false;
561      } else if (handleReject() == RejectAndGiveUp)
562        return false;
563
564      break;
565    }
566    case GIM_CheckRegBankForClass: {
567      int64_t InsnID = MatchTable[CurrentIdx++];
568      int64_t OpIdx = MatchTable[CurrentIdx++];
569      int64_t RCEnum = MatchTable[CurrentIdx++];
570      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
571                      dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
572                             << InsnID << "]->getOperand(" << OpIdx
573                             << "), RCEnum=" << RCEnum << ")\n");
574      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
575      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
576      if (!MO.isReg() ||
577          &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
578                                      MRI.getType(MO.getReg())) !=
579              RBI.getRegBank(MO.getReg(), MRI, TRI)) {
580        if (handleReject() == RejectAndGiveUp)
581          return false;
582      }
583      break;
584    }
585
586    case GIM_CheckComplexPattern: {
587      int64_t InsnID = MatchTable[CurrentIdx++];
588      int64_t OpIdx = MatchTable[CurrentIdx++];
589      int64_t RendererID = MatchTable[CurrentIdx++];
590      int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
591      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
592                      dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
593                             << "] = GIM_CheckComplexPattern(MIs[" << InsnID
594                             << "]->getOperand(" << OpIdx
595                             << "), ComplexPredicateID=" << ComplexPredicateID
596                             << ")\n");
597      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
598      // FIXME: Use std::invoke() when it's available.
599      ComplexRendererFns Renderer =
600          (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
601              State.MIs[InsnID]->getOperand(OpIdx));
602      if (Renderer.hasValue())
603        State.Renderers[RendererID] = Renderer.getValue();
604      else
605        if (handleReject() == RejectAndGiveUp)
606          return false;
607      break;
608    }
609
610    case GIM_CheckConstantInt: {
611      int64_t InsnID = MatchTable[CurrentIdx++];
612      int64_t OpIdx = MatchTable[CurrentIdx++];
613      int64_t Value = MatchTable[CurrentIdx++];
614      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
615                      dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
616                             << InsnID << "]->getOperand(" << OpIdx
617                             << "), Value=" << Value << ")\n");
618      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
619      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
620      if (MO.isReg()) {
621        // isOperandImmEqual() will sign-extend to 64-bits, so should we.
622        LLT Ty = MRI.getType(MO.getReg());
623        Value = SignExtend64(Value, Ty.getSizeInBits());
624
625        if (!isOperandImmEqual(MO, Value, MRI)) {
626          if (handleReject() == RejectAndGiveUp)
627            return false;
628        }
629      } else if (handleReject() == RejectAndGiveUp)
630        return false;
631
632      break;
633    }
634
635    case GIM_CheckLiteralInt: {
636      int64_t InsnID = MatchTable[CurrentIdx++];
637      int64_t OpIdx = MatchTable[CurrentIdx++];
638      int64_t Value = MatchTable[CurrentIdx++];
639      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
640                      dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
641                             << InsnID << "]->getOperand(" << OpIdx
642                             << "), Value=" << Value << ")\n");
643      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
644      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
645      if (MO.isImm() && MO.getImm() == Value)
646        break;
647
648      if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
649        break;
650
651      if (handleReject() == RejectAndGiveUp)
652        return false;
653
654      break;
655    }
656
657    case GIM_CheckIntrinsicID: {
658      int64_t InsnID = MatchTable[CurrentIdx++];
659      int64_t OpIdx = MatchTable[CurrentIdx++];
660      int64_t Value = MatchTable[CurrentIdx++];
661      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
662                      dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
663                             << InsnID << "]->getOperand(" << OpIdx
664                             << "), Value=" << Value << ")\n");
665      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
666      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
667      if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
668        if (handleReject() == RejectAndGiveUp)
669          return false;
670      break;
671    }
672    case GIM_CheckCmpPredicate: {
673      int64_t InsnID = MatchTable[CurrentIdx++];
674      int64_t OpIdx = MatchTable[CurrentIdx++];
675      int64_t Value = MatchTable[CurrentIdx++];
676      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
677                      dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
678                             << InsnID << "]->getOperand(" << OpIdx
679                             << "), Value=" << Value << ")\n");
680      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
681      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
682      if (!MO.isPredicate() || MO.getPredicate() != Value)
683        if (handleReject() == RejectAndGiveUp)
684          return false;
685      break;
686    }
687    case GIM_CheckIsMBB: {
688      int64_t InsnID = MatchTable[CurrentIdx++];
689      int64_t OpIdx = MatchTable[CurrentIdx++];
690      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
691                      dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
692                             << "]->getOperand(" << OpIdx << "))\n");
693      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
694      if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
695        if (handleReject() == RejectAndGiveUp)
696          return false;
697      }
698      break;
699    }
700    case GIM_CheckIsImm: {
701      int64_t InsnID = MatchTable[CurrentIdx++];
702      int64_t OpIdx = MatchTable[CurrentIdx++];
703      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
704                      dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
705                             << "]->getOperand(" << OpIdx << "))\n");
706      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
707      if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
708        if (handleReject() == RejectAndGiveUp)
709          return false;
710      }
711      break;
712    }
713    case GIM_CheckIsSafeToFold: {
714      int64_t InsnID = MatchTable[CurrentIdx++];
715      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
716                      dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
717                             << InsnID << "])\n");
718      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
719      if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
720        if (handleReject() == RejectAndGiveUp)
721          return false;
722      }
723      break;
724    }
725    case GIM_CheckIsSameOperand: {
726      int64_t InsnID = MatchTable[CurrentIdx++];
727      int64_t OpIdx = MatchTable[CurrentIdx++];
728      int64_t OtherInsnID = MatchTable[CurrentIdx++];
729      int64_t OtherOpIdx = MatchTable[CurrentIdx++];
730      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
731                      dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
732                             << InsnID << "][" << OpIdx << "], MIs["
733                             << OtherInsnID << "][" << OtherOpIdx << "])\n");
734      assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
735      assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
736      if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
737              State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
738        if (handleReject() == RejectAndGiveUp)
739          return false;
740      }
741      break;
742    }
743    case GIM_Reject:
744      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
745                      dbgs() << CurrentIdx << ": GIM_Reject\n");
746      if (handleReject() == RejectAndGiveUp)
747        return false;
748      break;
749
750    case GIR_MutateOpcode: {
751      int64_t OldInsnID = MatchTable[CurrentIdx++];
752      uint64_t NewInsnID = MatchTable[CurrentIdx++];
753      int64_t NewOpcode = MatchTable[CurrentIdx++];
754      if (NewInsnID >= OutMIs.size())
755        OutMIs.resize(NewInsnID + 1);
756
757      OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
758                                              State.MIs[OldInsnID]);
759      OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
760      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
761                      dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
762                             << NewInsnID << "], MIs[" << OldInsnID << "], "
763                             << NewOpcode << ")\n");
764      break;
765    }
766
767    case GIR_BuildMI: {
768      uint64_t NewInsnID = MatchTable[CurrentIdx++];
769      int64_t Opcode = MatchTable[CurrentIdx++];
770      if (NewInsnID >= OutMIs.size())
771        OutMIs.resize(NewInsnID + 1);
772
773      OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
774                                  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
775      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
776                      dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
777                             << NewInsnID << "], " << Opcode << ")\n");
778      break;
779    }
780
781    case GIR_Copy: {
782      int64_t NewInsnID = MatchTable[CurrentIdx++];
783      int64_t OldInsnID = MatchTable[CurrentIdx++];
784      int64_t OpIdx = MatchTable[CurrentIdx++];
785      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
786      OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
787      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
788                      dbgs()
789                          << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
790                          << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
791      break;
792    }
793
794    case GIR_CopyOrAddZeroReg: {
795      int64_t NewInsnID = MatchTable[CurrentIdx++];
796      int64_t OldInsnID = MatchTable[CurrentIdx++];
797      int64_t OpIdx = MatchTable[CurrentIdx++];
798      int64_t ZeroReg = MatchTable[CurrentIdx++];
799      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
800      MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
801      if (isOperandImmEqual(MO, 0, MRI))
802        OutMIs[NewInsnID].addReg(ZeroReg);
803      else
804        OutMIs[NewInsnID].add(MO);
805      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
806                      dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
807                             << NewInsnID << "], MIs[" << OldInsnID << "], "
808                             << OpIdx << ", " << ZeroReg << ")\n");
809      break;
810    }
811
812    case GIR_CopySubReg: {
813      int64_t NewInsnID = MatchTable[CurrentIdx++];
814      int64_t OldInsnID = MatchTable[CurrentIdx++];
815      int64_t OpIdx = MatchTable[CurrentIdx++];
816      int64_t SubRegIdx = MatchTable[CurrentIdx++];
817      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
818      OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
819                               0, SubRegIdx);
820      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
821                      dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
822                             << NewInsnID << "], MIs[" << OldInsnID << "], "
823                             << OpIdx << ", " << SubRegIdx << ")\n");
824      break;
825    }
826
827    case GIR_AddImplicitDef: {
828      int64_t InsnID = MatchTable[CurrentIdx++];
829      int64_t RegNum = MatchTable[CurrentIdx++];
830      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
831      OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
832      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
833                      dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
834                             << InsnID << "], " << RegNum << ")\n");
835      break;
836    }
837
838    case GIR_AddImplicitUse: {
839      int64_t InsnID = MatchTable[CurrentIdx++];
840      int64_t RegNum = MatchTable[CurrentIdx++];
841      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
842      OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
843      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
844                      dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
845                             << InsnID << "], " << RegNum << ")\n");
846      break;
847    }
848
849    case GIR_AddRegister: {
850      int64_t InsnID = MatchTable[CurrentIdx++];
851      int64_t RegNum = MatchTable[CurrentIdx++];
852      uint64_t RegFlags = MatchTable[CurrentIdx++];
853      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
854      OutMIs[InsnID].addReg(RegNum, RegFlags);
855      DEBUG_WITH_TYPE(
856        TgtInstructionSelector::getName(),
857        dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
858        << InsnID << "], " << RegNum << ", " << RegFlags << ")\n");
859      break;
860    }
861
862    case GIR_AddTempRegister: {
863      int64_t InsnID = MatchTable[CurrentIdx++];
864      int64_t TempRegID = MatchTable[CurrentIdx++];
865      uint64_t TempRegFlags = MatchTable[CurrentIdx++];
866      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
867      OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
868      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
869                      dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
870                             << InsnID << "], TempRegisters[" << TempRegID
871                             << "], " << TempRegFlags << ")\n");
872      break;
873    }
874
875    case GIR_AddImm: {
876      int64_t InsnID = MatchTable[CurrentIdx++];
877      int64_t Imm = MatchTable[CurrentIdx++];
878      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
879      OutMIs[InsnID].addImm(Imm);
880      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
881                      dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
882                             << "], " << Imm << ")\n");
883      break;
884    }
885
886    case GIR_ComplexRenderer: {
887      int64_t InsnID = MatchTable[CurrentIdx++];
888      int64_t RendererID = MatchTable[CurrentIdx++];
889      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
890      for (const auto &RenderOpFn : State.Renderers[RendererID])
891        RenderOpFn(OutMIs[InsnID]);
892      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
893                      dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
894                             << InsnID << "], " << RendererID << ")\n");
895      break;
896    }
897    case GIR_ComplexSubOperandRenderer: {
898      int64_t InsnID = MatchTable[CurrentIdx++];
899      int64_t RendererID = MatchTable[CurrentIdx++];
900      int64_t RenderOpID = MatchTable[CurrentIdx++];
901      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
902      State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
903      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
904                      dbgs() << CurrentIdx
905                             << ": GIR_ComplexSubOperandRenderer(OutMIs["
906                             << InsnID << "], " << RendererID << ", "
907                             << RenderOpID << ")\n");
908      break;
909    }
910
911    case GIR_CopyConstantAsSImm: {
912      int64_t NewInsnID = MatchTable[CurrentIdx++];
913      int64_t OldInsnID = MatchTable[CurrentIdx++];
914      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
915      assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
916      if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
917        OutMIs[NewInsnID].addImm(
918            State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
919      } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
920        OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
921      else
922        llvm_unreachable("Expected Imm or CImm operand");
923      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
924                      dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
925                             << NewInsnID << "], MIs[" << OldInsnID << "])\n");
926      break;
927    }
928
929    // TODO: Needs a test case once we have a pattern that uses this.
930    case GIR_CopyFConstantAsFPImm: {
931      int64_t NewInsnID = MatchTable[CurrentIdx++];
932      int64_t OldInsnID = MatchTable[CurrentIdx++];
933      assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
934      assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
935      if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
936        OutMIs[NewInsnID].addFPImm(
937            State.MIs[OldInsnID]->getOperand(1).getFPImm());
938      else
939        llvm_unreachable("Expected FPImm operand");
940      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
941                      dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
942                             << NewInsnID << "], MIs[" << OldInsnID << "])\n");
943      break;
944    }
945
946    case GIR_CustomRenderer: {
947      int64_t InsnID = MatchTable[CurrentIdx++];
948      int64_t OldInsnID = MatchTable[CurrentIdx++];
949      int64_t RendererFnID = MatchTable[CurrentIdx++];
950      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
951      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
952                      dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
953                             << InsnID << "], MIs[" << OldInsnID << "], "
954                             << RendererFnID << ")\n");
955      (ISel.*ISelInfo.CustomRenderers[RendererFnID])(
956        OutMIs[InsnID], *State.MIs[OldInsnID],
957        -1); // Not a source operand of the old instruction.
958      break;
959    }
960    case GIR_CustomOperandRenderer: {
961      int64_t InsnID = MatchTable[CurrentIdx++];
962      int64_t OldInsnID = MatchTable[CurrentIdx++];
963      int64_t OpIdx = MatchTable[CurrentIdx++];
964      int64_t RendererFnID = MatchTable[CurrentIdx++];
965      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
966
967      DEBUG_WITH_TYPE(
968        TgtInstructionSelector::getName(),
969        dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs["
970               << InsnID << "], MIs[" << OldInsnID << "]->getOperand("
971               << OpIdx << "), "
972        << RendererFnID << ")\n");
973      (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
974                                                     *State.MIs[OldInsnID],
975                                                     OpIdx);
976      break;
977    }
978    case GIR_ConstrainOperandRC: {
979      int64_t InsnID = MatchTable[CurrentIdx++];
980      int64_t OpIdx = MatchTable[CurrentIdx++];
981      int64_t RCEnum = MatchTable[CurrentIdx++];
982      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
983      constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
984                                    *TRI.getRegClass(RCEnum), TII, TRI, RBI);
985      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
986                      dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
987                             << InsnID << "], " << OpIdx << ", " << RCEnum
988                             << ")\n");
989      break;
990    }
991
992    case GIR_ConstrainSelectedInstOperands: {
993      int64_t InsnID = MatchTable[CurrentIdx++];
994      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
995      constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
996                                       RBI);
997      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
998                      dbgs() << CurrentIdx
999                             << ": GIR_ConstrainSelectedInstOperands(OutMIs["
1000                             << InsnID << "])\n");
1001      break;
1002    }
1003
1004    case GIR_MergeMemOperands: {
1005      int64_t InsnID = MatchTable[CurrentIdx++];
1006      assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1007
1008      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1009                      dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
1010                             << InsnID << "]");
1011      int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
1012      while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
1013             GIU_MergeMemOperands_EndOfList) {
1014        DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1015                        dbgs() << ", MIs[" << MergeInsnID << "]");
1016        for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
1017          OutMIs[InsnID].addMemOperand(MMO);
1018      }
1019      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n");
1020      break;
1021    }
1022
1023    case GIR_EraseFromParent: {
1024      int64_t InsnID = MatchTable[CurrentIdx++];
1025      assert(State.MIs[InsnID] &&
1026             "Attempted to erase an undefined instruction");
1027      State.MIs[InsnID]->eraseFromParent();
1028      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1029                      dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
1030                             << InsnID << "])\n");
1031      break;
1032    }
1033
1034    case GIR_MakeTempReg: {
1035      int64_t TempRegID = MatchTable[CurrentIdx++];
1036      int64_t TypeID = MatchTable[CurrentIdx++];
1037
1038      State.TempRegisters[TempRegID] =
1039          MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
1040      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1041                      dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
1042                             << "] = GIR_MakeTempReg(" << TypeID << ")\n");
1043      break;
1044    }
1045
1046    case GIR_Coverage: {
1047      int64_t RuleID = MatchTable[CurrentIdx++];
1048      CoverageInfo.setCovered(RuleID);
1049
1050      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1051                      dbgs()
1052                          << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
1053      break;
1054    }
1055
1056    case GIR_Done:
1057      DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1058                      dbgs() << CurrentIdx << ": GIR_Done\n");
1059      return true;
1060
1061    default:
1062      llvm_unreachable("Unexpected command");
1063    }
1064  }
1065}
1066
1067} // end namespace llvm
1068
1069#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
1070