Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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