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
37 namespace llvm {
38
39 /// GlobalISel PatFrag Predicates
40 enum {
41 GIPFP_I64_Invalid = 0,
42 GIPFP_APInt_Invalid = 0,
43 GIPFP_APFloat_Invalid = 0,
44 GIPFP_MI_Invalid = 0,
45 };
46
47 template <class TgtInstructionSelector, class PredicateBitset,
48 class ComplexMatcherMemFn, class CustomRendererFn>
executeMatchTable(TgtInstructionSelector & ISel,NewMIVector & OutMIs,MatcherState & State,const ISelInfoTy<PredicateBitset,ComplexMatcherMemFn,CustomRendererFn> & ISelInfo,const int64_t * MatchTable,const TargetInstrInfo & TII,MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI,const RegisterBankInfo & RBI,const PredicateBitset & AvailableFeatures,CodeGenCoverage & CoverageInfo)49 bool 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