LLVM  9.0.0svn
InstructionSelectorImpl.h
Go to the documentation of this file.
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"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/Support/Debug.h"
32 #include <cassert>
33 #include <cstddef>
34 #include <cstdint>
35 
36 namespace llvm {
37 
38 /// GlobalISel PatFrag Predicates
39 enum {
44 };
45 
46 template <class TgtInstructionSelector, class PredicateBitset,
47  class ComplexMatcherMemFn, class CustomRendererFn>
49  TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
51  &ISelInfo,
52  const int64_t *MatchTable, const TargetInstrInfo &TII,
54  const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
55  CodeGenCoverage &CoverageInfo) const {
56 
57  uint64_t CurrentIdx = 0;
58  SmallVector<uint64_t, 4> OnFailResumeAt;
59 
60  enum RejectAction { RejectAndGiveUp, RejectAndResume };
61  auto handleReject = [&]() -> RejectAction {
63  dbgs() << CurrentIdx << ": Rejected\n");
64  if (OnFailResumeAt.empty())
65  return RejectAndGiveUp;
66  CurrentIdx = OnFailResumeAt.pop_back_val();
68  dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
69  << OnFailResumeAt.size() << " try-blocks remain)\n");
70  return RejectAndResume;
71  };
72 
73  while (true) {
74  assert(CurrentIdx != ~0u && "Invalid MatchTable index");
75  int64_t MatcherOpcode = MatchTable[CurrentIdx++];
76  switch (MatcherOpcode) {
77  case GIM_Try: {
79  dbgs() << CurrentIdx << ": Begin try-block\n");
80  OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
81  break;
82  }
83 
84  case GIM_RecordInsn: {
85  int64_t NewInsnID = MatchTable[CurrentIdx++];
86  int64_t InsnID = MatchTable[CurrentIdx++];
87  int64_t OpIdx = MatchTable[CurrentIdx++];
88 
89  // As an optimisation we require that MIs[0] is always the root. Refuse
90  // any attempt to modify it.
91  assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
92 
93  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
94  if (!MO.isReg()) {
96  dbgs() << CurrentIdx << ": Not a register\n");
97  if (handleReject() == RejectAndGiveUp)
98  return false;
99  break;
100  }
101  if (TRI.isPhysicalRegister(MO.getReg())) {
103  dbgs() << CurrentIdx << ": Is a physical register\n");
104  if (handleReject() == RejectAndGiveUp)
105  return false;
106  break;
107  }
108 
109  MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
110  if ((size_t)NewInsnID < State.MIs.size())
111  State.MIs[NewInsnID] = NewMI;
112  else {
113  assert((size_t)NewInsnID == State.MIs.size() &&
114  "Expected to store MIs in order");
115  State.MIs.push_back(NewMI);
116  }
118  dbgs() << CurrentIdx << ": MIs[" << NewInsnID
119  << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
120  << ")\n");
121  break;
122  }
123 
124  case GIM_CheckFeatures: {
125  int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
127  dbgs() << CurrentIdx
128  << ": GIM_CheckFeatures(ExpectedBitsetID="
129  << ExpectedBitsetID << ")\n");
130  if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
131  ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
132  if (handleReject() == RejectAndGiveUp)
133  return false;
134  }
135  break;
136  }
137 
138  case GIM_CheckOpcode: {
139  int64_t InsnID = MatchTable[CurrentIdx++];
140  int64_t Expected = MatchTable[CurrentIdx++];
141 
142  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
143  unsigned Opcode = State.MIs[InsnID]->getOpcode();
144 
146  dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
147  << "], ExpectedOpcode=" << Expected
148  << ") // Got=" << Opcode << "\n");
149  if (Opcode != Expected) {
150  if (handleReject() == RejectAndGiveUp)
151  return false;
152  }
153  break;
154  }
155 
156  case GIM_SwitchOpcode: {
157  int64_t InsnID = MatchTable[CurrentIdx++];
158  int64_t LowerBound = MatchTable[CurrentIdx++];
159  int64_t UpperBound = MatchTable[CurrentIdx++];
160  int64_t Default = MatchTable[CurrentIdx++];
161 
162  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
163  const int64_t Opcode = State.MIs[InsnID]->getOpcode();
164 
166  dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
167  << LowerBound << ", " << UpperBound << "), Default=" << Default
168  << ", JumpTable...) // Got=" << Opcode << "\n";
169  });
170  if (Opcode < LowerBound || UpperBound <= Opcode) {
171  CurrentIdx = Default;
172  break;
173  }
174  CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
175  if (!CurrentIdx) {
176  CurrentIdx = Default;
177  break;
178  }
179  OnFailResumeAt.push_back(Default);
180  break;
181  }
182 
183  case GIM_SwitchType: {
184  int64_t InsnID = MatchTable[CurrentIdx++];
185  int64_t OpIdx = MatchTable[CurrentIdx++];
186  int64_t LowerBound = MatchTable[CurrentIdx++];
187  int64_t UpperBound = MatchTable[CurrentIdx++];
188  int64_t Default = MatchTable[CurrentIdx++];
189 
190  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
191  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
192 
194  dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
195  << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
196  << UpperBound << "), Default=" << Default
197  << ", JumpTable...) // Got=";
198  if (!MO.isReg())
199  dbgs() << "Not a VReg\n";
200  else
201  dbgs() << MRI.getType(MO.getReg()) << "\n";
202  });
203  if (!MO.isReg()) {
204  CurrentIdx = Default;
205  break;
206  }
207  const LLT Ty = MRI.getType(MO.getReg());
208  const auto TyI = ISelInfo.TypeIDMap.find(Ty);
209  if (TyI == ISelInfo.TypeIDMap.end()) {
210  CurrentIdx = Default;
211  break;
212  }
213  const int64_t TypeID = TyI->second;
214  if (TypeID < LowerBound || UpperBound <= TypeID) {
215  CurrentIdx = Default;
216  break;
217  }
218  CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
219  if (!CurrentIdx) {
220  CurrentIdx = Default;
221  break;
222  }
223  OnFailResumeAt.push_back(Default);
224  break;
225  }
226 
227  case GIM_CheckNumOperands: {
228  int64_t InsnID = MatchTable[CurrentIdx++];
229  int64_t Expected = MatchTable[CurrentIdx++];
231  dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
232  << InsnID << "], Expected=" << Expected << ")\n");
233  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
234  if (State.MIs[InsnID]->getNumOperands() != Expected) {
235  if (handleReject() == RejectAndGiveUp)
236  return false;
237  }
238  break;
239  }
241  int64_t InsnID = MatchTable[CurrentIdx++];
242  int64_t Predicate = MatchTable[CurrentIdx++];
244  dbgs()
245  << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
246  << InsnID << "], Predicate=" << Predicate << ")\n");
247  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
248  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
249  "Expected G_CONSTANT");
250  assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
251  int64_t Value = 0;
252  if (State.MIs[InsnID]->getOperand(1).isCImm())
253  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
254  else if (State.MIs[InsnID]->getOperand(1).isImm())
255  Value = State.MIs[InsnID]->getOperand(1).getImm();
256  else
257  llvm_unreachable("Expected Imm or CImm operand");
258 
259  if (!testImmPredicate_I64(Predicate, Value))
260  if (handleReject() == RejectAndGiveUp)
261  return false;
262  break;
263  }
265  int64_t InsnID = MatchTable[CurrentIdx++];
266  int64_t Predicate = MatchTable[CurrentIdx++];
268  dbgs()
269  << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
270  << InsnID << "], Predicate=" << Predicate << ")\n");
271  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
272  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
273  "Expected G_CONSTANT");
274  assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
275  APInt Value;
276  if (State.MIs[InsnID]->getOperand(1).isCImm())
277  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
278  else
279  llvm_unreachable("Expected Imm or CImm operand");
280 
281  if (!testImmPredicate_APInt(Predicate, Value))
282  if (handleReject() == RejectAndGiveUp)
283  return false;
284  break;
285  }
287  int64_t InsnID = MatchTable[CurrentIdx++];
288  int64_t Predicate = MatchTable[CurrentIdx++];
290  dbgs()
291  << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
292  << InsnID << "], Predicate=" << Predicate << ")\n");
293  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
294  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
295  "Expected G_FCONSTANT");
296  assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
297  assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
298  APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
299 
300  if (!testImmPredicate_APFloat(Predicate, Value))
301  if (handleReject() == RejectAndGiveUp)
302  return false;
303  break;
304  }
306  int64_t InsnID = MatchTable[CurrentIdx++];
307  int64_t Predicate = MatchTable[CurrentIdx++];
309  dbgs()
310  << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
311  << InsnID << "], Predicate=" << Predicate << ")\n");
312  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
313  assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
314 
315  if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID]))
316  if (handleReject() == RejectAndGiveUp)
317  return false;
318  break;
319  }
321  int64_t InsnID = MatchTable[CurrentIdx++];
322  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
324  dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
325  << InsnID << "], " << (uint64_t)Ordering << ")\n");
326  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
327  if (!State.MIs[InsnID]->hasOneMemOperand())
328  if (handleReject() == RejectAndGiveUp)
329  return false;
330 
331  for (const auto &MMO : State.MIs[InsnID]->memoperands())
332  if (MMO->getOrdering() != Ordering)
333  if (handleReject() == RejectAndGiveUp)
334  return false;
335  break;
336  }
338  int64_t InsnID = MatchTable[CurrentIdx++];
339  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
341  dbgs() << CurrentIdx
342  << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
343  << InsnID << "], " << (uint64_t)Ordering << ")\n");
344  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
345  if (!State.MIs[InsnID]->hasOneMemOperand())
346  if (handleReject() == RejectAndGiveUp)
347  return false;
348 
349  for (const auto &MMO : State.MIs[InsnID]->memoperands())
350  if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering))
351  if (handleReject() == RejectAndGiveUp)
352  return false;
353  break;
354  }
356  int64_t InsnID = MatchTable[CurrentIdx++];
357  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
359  dbgs() << CurrentIdx
360  << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
361  << InsnID << "], " << (uint64_t)Ordering << ")\n");
362  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
363  if (!State.MIs[InsnID]->hasOneMemOperand())
364  if (handleReject() == RejectAndGiveUp)
365  return false;
366 
367  for (const auto &MMO : State.MIs[InsnID]->memoperands())
368  if (!isStrongerThan(Ordering, MMO->getOrdering()))
369  if (handleReject() == RejectAndGiveUp)
370  return false;
371  break;
372  }
374  int64_t InsnID = MatchTable[CurrentIdx++];
375  int64_t MMOIdx = MatchTable[CurrentIdx++];
376  uint64_t Size = MatchTable[CurrentIdx++];
377 
379  dbgs() << CurrentIdx
380  << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
381  << "]->memoperands() + " << MMOIdx
382  << ", Size=" << Size << ")\n");
383  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
384 
385  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
386  if (handleReject() == RejectAndGiveUp)
387  return false;
388  break;
389  }
390 
391  MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
392 
394  dbgs() << MMO->getSize() << " bytes vs " << Size
395  << " bytes\n");
396  if (MMO->getSize() != Size)
397  if (handleReject() == RejectAndGiveUp)
398  return false;
399 
400  break;
401  }
405  int64_t InsnID = MatchTable[CurrentIdx++];
406  int64_t MMOIdx = MatchTable[CurrentIdx++];
407  int64_t OpIdx = MatchTable[CurrentIdx++];
408 
411  dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
412  << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
413  ? "EqualTo"
414  : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
415  ? "GreaterThan"
416  : "LessThan")
417  << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
418  << ", OpIdx=" << OpIdx << ")\n");
419  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
420 
421  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
422  if (!MO.isReg()) {
424  dbgs() << CurrentIdx << ": Not a register\n");
425  if (handleReject() == RejectAndGiveUp)
426  return false;
427  break;
428  }
429 
430  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
431  if (handleReject() == RejectAndGiveUp)
432  return false;
433  break;
434  }
435 
436  MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
437 
438  unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
439  if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
440  MMO->getSize() * 8 != Size) {
441  if (handleReject() == RejectAndGiveUp)
442  return false;
443  } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
444  MMO->getSize() * 8 >= Size) {
445  if (handleReject() == RejectAndGiveUp)
446  return false;
447  } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
448  MMO->getSize() * 8 <= Size)
449  if (handleReject() == RejectAndGiveUp)
450  return false;
451 
452  break;
453  }
454  case GIM_CheckType: {
455  int64_t InsnID = MatchTable[CurrentIdx++];
456  int64_t OpIdx = MatchTable[CurrentIdx++];
457  int64_t TypeID = MatchTable[CurrentIdx++];
459  dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
460  << "]->getOperand(" << OpIdx
461  << "), TypeID=" << TypeID << ")\n");
462  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
463  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
464  if (!MO.isReg() ||
465  MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
466  if (handleReject() == RejectAndGiveUp)
467  return false;
468  }
469  break;
470  }
471  case GIM_CheckPointerToAny: {
472  int64_t InsnID = MatchTable[CurrentIdx++];
473  int64_t OpIdx = MatchTable[CurrentIdx++];
474  int64_t SizeInBits = MatchTable[CurrentIdx++];
475 
477  dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
478  << InsnID << "]->getOperand(" << OpIdx
479  << "), SizeInBits=" << SizeInBits << ")\n");
480  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
481  // iPTR must be looked up in the target.
482  if (SizeInBits == 0) {
483  MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
484  SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
485  }
486 
487  assert(SizeInBits != 0 && "Pointer size must be known");
488 
489  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
490  if (MO.isReg()) {
491  const LLT &Ty = MRI.getType(MO.getReg());
492  if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
493  if (handleReject() == RejectAndGiveUp)
494  return false;
495  } else if (handleReject() == RejectAndGiveUp)
496  return false;
497 
498  break;
499  }
501  int64_t InsnID = MatchTable[CurrentIdx++];
502  int64_t OpIdx = MatchTable[CurrentIdx++];
503  int64_t RCEnum = MatchTable[CurrentIdx++];
505  dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
506  << InsnID << "]->getOperand(" << OpIdx
507  << "), RCEnum=" << RCEnum << ")\n");
508  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
509  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
510  if (!MO.isReg() ||
511  &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
512  RBI.getRegBank(MO.getReg(), MRI, TRI)) {
513  if (handleReject() == RejectAndGiveUp)
514  return false;
515  }
516  break;
517  }
518 
520  int64_t InsnID = MatchTable[CurrentIdx++];
521  int64_t OpIdx = MatchTable[CurrentIdx++];
522  int64_t RendererID = MatchTable[CurrentIdx++];
523  int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
525  dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
526  << "] = GIM_CheckComplexPattern(MIs[" << InsnID
527  << "]->getOperand(" << OpIdx
528  << "), ComplexPredicateID=" << ComplexPredicateID
529  << ")\n");
530  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
531  // FIXME: Use std::invoke() when it's available.
532  ComplexRendererFns Renderer =
533  (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
534  State.MIs[InsnID]->getOperand(OpIdx));
535  if (Renderer.hasValue())
536  State.Renderers[RendererID] = Renderer.getValue();
537  else
538  if (handleReject() == RejectAndGiveUp)
539  return false;
540  break;
541  }
542 
543  case GIM_CheckConstantInt: {
544  int64_t InsnID = MatchTable[CurrentIdx++];
545  int64_t OpIdx = MatchTable[CurrentIdx++];
546  int64_t Value = MatchTable[CurrentIdx++];
548  dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
549  << InsnID << "]->getOperand(" << OpIdx
550  << "), Value=" << Value << ")\n");
551  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
552  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
553  if (MO.isReg()) {
554  // isOperandImmEqual() will sign-extend to 64-bits, so should we.
555  LLT Ty = MRI.getType(MO.getReg());
556  Value = SignExtend64(Value, Ty.getSizeInBits());
557 
558  if (!isOperandImmEqual(MO, Value, MRI)) {
559  if (handleReject() == RejectAndGiveUp)
560  return false;
561  }
562  } else if (handleReject() == RejectAndGiveUp)
563  return false;
564 
565  break;
566  }
567 
568  case GIM_CheckLiteralInt: {
569  int64_t InsnID = MatchTable[CurrentIdx++];
570  int64_t OpIdx = MatchTable[CurrentIdx++];
571  int64_t Value = MatchTable[CurrentIdx++];
573  dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
574  << InsnID << "]->getOperand(" << OpIdx
575  << "), Value=" << Value << ")\n");
576  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
577  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
578  if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
579  if (handleReject() == RejectAndGiveUp)
580  return false;
581  }
582  break;
583  }
584 
585  case GIM_CheckIntrinsicID: {
586  int64_t InsnID = MatchTable[CurrentIdx++];
587  int64_t OpIdx = MatchTable[CurrentIdx++];
588  int64_t Value = MatchTable[CurrentIdx++];
590  dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
591  << InsnID << "]->getOperand(" << OpIdx
592  << "), Value=" << Value << ")\n");
593  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
594  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
595  if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
596  if (handleReject() == RejectAndGiveUp)
597  return false;
598  break;
599  }
600 
601  case GIM_CheckIsMBB: {
602  int64_t InsnID = MatchTable[CurrentIdx++];
603  int64_t OpIdx = MatchTable[CurrentIdx++];
605  dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
606  << "]->getOperand(" << OpIdx << "))\n");
607  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
608  if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
609  if (handleReject() == RejectAndGiveUp)
610  return false;
611  }
612  break;
613  }
614 
615  case GIM_CheckIsSafeToFold: {
616  int64_t InsnID = MatchTable[CurrentIdx++];
618  dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
619  << InsnID << "])\n");
620  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
621  if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
622  if (handleReject() == RejectAndGiveUp)
623  return false;
624  }
625  break;
626  }
627  case GIM_CheckIsSameOperand: {
628  int64_t InsnID = MatchTable[CurrentIdx++];
629  int64_t OpIdx = MatchTable[CurrentIdx++];
630  int64_t OtherInsnID = MatchTable[CurrentIdx++];
631  int64_t OtherOpIdx = MatchTable[CurrentIdx++];
633  dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
634  << InsnID << "][" << OpIdx << "], MIs["
635  << OtherInsnID << "][" << OtherOpIdx << "])\n");
636  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
637  assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
638  if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
639  State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
640  if (handleReject() == RejectAndGiveUp)
641  return false;
642  }
643  break;
644  }
645  case GIM_Reject:
647  dbgs() << CurrentIdx << ": GIM_Reject\n");
648  if (handleReject() == RejectAndGiveUp)
649  return false;
650  break;
651 
652  case GIR_MutateOpcode: {
653  int64_t OldInsnID = MatchTable[CurrentIdx++];
654  uint64_t NewInsnID = MatchTable[CurrentIdx++];
655  int64_t NewOpcode = MatchTable[CurrentIdx++];
656  if (NewInsnID >= OutMIs.size())
657  OutMIs.resize(NewInsnID + 1);
658 
659  OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
660  State.MIs[OldInsnID]);
661  OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
663  dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
664  << NewInsnID << "], MIs[" << OldInsnID << "], "
665  << NewOpcode << ")\n");
666  break;
667  }
668 
669  case GIR_BuildMI: {
670  uint64_t NewInsnID = MatchTable[CurrentIdx++];
671  int64_t Opcode = MatchTable[CurrentIdx++];
672  if (NewInsnID >= OutMIs.size())
673  OutMIs.resize(NewInsnID + 1);
674 
675  OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
676  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
678  dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
679  << NewInsnID << "], " << Opcode << ")\n");
680  break;
681  }
682 
683  case GIR_Copy: {
684  int64_t NewInsnID = MatchTable[CurrentIdx++];
685  int64_t OldInsnID = MatchTable[CurrentIdx++];
686  int64_t OpIdx = MatchTable[CurrentIdx++];
687  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
688  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
690  dbgs()
691  << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
692  << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
693  break;
694  }
695 
696  case GIR_CopyOrAddZeroReg: {
697  int64_t NewInsnID = MatchTable[CurrentIdx++];
698  int64_t OldInsnID = MatchTable[CurrentIdx++];
699  int64_t OpIdx = MatchTable[CurrentIdx++];
700  int64_t ZeroReg = MatchTable[CurrentIdx++];
701  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
702  MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
703  if (isOperandImmEqual(MO, 0, MRI))
704  OutMIs[NewInsnID].addReg(ZeroReg);
705  else
706  OutMIs[NewInsnID].add(MO);
708  dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
709  << NewInsnID << "], MIs[" << OldInsnID << "], "
710  << OpIdx << ", " << ZeroReg << ")\n");
711  break;
712  }
713 
714  case GIR_CopySubReg: {
715  int64_t NewInsnID = MatchTable[CurrentIdx++];
716  int64_t OldInsnID = MatchTable[CurrentIdx++];
717  int64_t OpIdx = MatchTable[CurrentIdx++];
718  int64_t SubRegIdx = MatchTable[CurrentIdx++];
719  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
720  OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
721  0, SubRegIdx);
723  dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
724  << NewInsnID << "], MIs[" << OldInsnID << "], "
725  << OpIdx << ", " << SubRegIdx << ")\n");
726  break;
727  }
728 
729  case GIR_AddImplicitDef: {
730  int64_t InsnID = MatchTable[CurrentIdx++];
731  int64_t RegNum = MatchTable[CurrentIdx++];
732  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
733  OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
735  dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
736  << InsnID << "], " << RegNum << ")\n");
737  break;
738  }
739 
740  case GIR_AddImplicitUse: {
741  int64_t InsnID = MatchTable[CurrentIdx++];
742  int64_t RegNum = MatchTable[CurrentIdx++];
743  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
744  OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
746  dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
747  << InsnID << "], " << RegNum << ")\n");
748  break;
749  }
750 
751  case GIR_AddRegister: {
752  int64_t InsnID = MatchTable[CurrentIdx++];
753  int64_t RegNum = MatchTable[CurrentIdx++];
754  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
755  OutMIs[InsnID].addReg(RegNum);
757  dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
758  << InsnID << "], " << RegNum << ")\n");
759  break;
760  }
761 
762  case GIR_AddTempRegister: {
763  int64_t InsnID = MatchTable[CurrentIdx++];
764  int64_t TempRegID = MatchTable[CurrentIdx++];
765  uint64_t TempRegFlags = MatchTable[CurrentIdx++];
766  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
767  OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
769  dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
770  << InsnID << "], TempRegisters[" << TempRegID
771  << "], " << TempRegFlags << ")\n");
772  break;
773  }
774 
775  case GIR_AddImm: {
776  int64_t InsnID = MatchTable[CurrentIdx++];
777  int64_t Imm = MatchTable[CurrentIdx++];
778  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
779  OutMIs[InsnID].addImm(Imm);
781  dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
782  << "], " << Imm << ")\n");
783  break;
784  }
785 
786  case GIR_ComplexRenderer: {
787  int64_t InsnID = MatchTable[CurrentIdx++];
788  int64_t RendererID = MatchTable[CurrentIdx++];
789  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
790  for (const auto &RenderOpFn : State.Renderers[RendererID])
791  RenderOpFn(OutMIs[InsnID]);
793  dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
794  << InsnID << "], " << RendererID << ")\n");
795  break;
796  }
798  int64_t InsnID = MatchTable[CurrentIdx++];
799  int64_t RendererID = MatchTable[CurrentIdx++];
800  int64_t RenderOpID = MatchTable[CurrentIdx++];
801  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
802  State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
804  dbgs() << CurrentIdx
805  << ": GIR_ComplexSubOperandRenderer(OutMIs["
806  << InsnID << "], " << RendererID << ", "
807  << RenderOpID << ")\n");
808  break;
809  }
810 
811  case GIR_CopyConstantAsSImm: {
812  int64_t NewInsnID = MatchTable[CurrentIdx++];
813  int64_t OldInsnID = MatchTable[CurrentIdx++];
814  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
815  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
816  if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
817  OutMIs[NewInsnID].addImm(
818  State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
819  } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
820  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
821  else
822  llvm_unreachable("Expected Imm or CImm operand");
824  dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
825  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
826  break;
827  }
828 
829  // TODO: Needs a test case once we have a pattern that uses this.
831  int64_t NewInsnID = MatchTable[CurrentIdx++];
832  int64_t OldInsnID = MatchTable[CurrentIdx++];
833  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
834  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
835  if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
836  OutMIs[NewInsnID].addFPImm(
837  State.MIs[OldInsnID]->getOperand(1).getFPImm());
838  else
839  llvm_unreachable("Expected FPImm operand");
841  dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
842  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
843  break;
844  }
845 
846  case GIR_CustomRenderer: {
847  int64_t InsnID = MatchTable[CurrentIdx++];
848  int64_t OldInsnID = MatchTable[CurrentIdx++];
849  int64_t RendererFnID = MatchTable[CurrentIdx++];
850  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
852  dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
853  << InsnID << "], MIs[" << OldInsnID << "], "
854  << RendererFnID << ")\n");
855  (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
856  *State.MIs[OldInsnID]);
857  break;
858  }
859  case GIR_ConstrainOperandRC: {
860  int64_t InsnID = MatchTable[CurrentIdx++];
861  int64_t OpIdx = MatchTable[CurrentIdx++];
862  int64_t RCEnum = MatchTable[CurrentIdx++];
863  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
864  constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
865  *TRI.getRegClass(RCEnum), TII, TRI, RBI);
867  dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
868  << InsnID << "], " << OpIdx << ", " << RCEnum
869  << ")\n");
870  break;
871  }
872 
874  int64_t InsnID = MatchTable[CurrentIdx++];
875  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
876  constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
877  RBI);
879  dbgs() << CurrentIdx
880  << ": GIR_ConstrainSelectedInstOperands(OutMIs["
881  << InsnID << "])\n");
882  break;
883  }
884 
885  case GIR_MergeMemOperands: {
886  int64_t InsnID = MatchTable[CurrentIdx++];
887  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
888 
890  dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
891  << InsnID << "]");
892  int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
893  while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
896  dbgs() << ", MIs[" << MergeInsnID << "]");
897  for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
898  OutMIs[InsnID].addMemOperand(MMO);
899  }
901  break;
902  }
903 
904  case GIR_EraseFromParent: {
905  int64_t InsnID = MatchTable[CurrentIdx++];
906  assert(State.MIs[InsnID] &&
907  "Attempted to erase an undefined instruction");
908  State.MIs[InsnID]->eraseFromParent();
910  dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
911  << InsnID << "])\n");
912  break;
913  }
914 
915  case GIR_MakeTempReg: {
916  int64_t TempRegID = MatchTable[CurrentIdx++];
917  int64_t TypeID = MatchTable[CurrentIdx++];
918 
919  State.TempRegisters[TempRegID] =
920  MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
922  dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
923  << "] = GIR_MakeTempReg(" << TypeID << ")\n");
924  break;
925  }
926 
927  case GIR_Coverage: {
928  int64_t RuleID = MatchTable[CurrentIdx++];
929  CoverageInfo.setCovered(RuleID);
930 
932  dbgs()
933  << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
934  break;
935  }
936 
937  case GIR_Done:
939  dbgs() << CurrentIdx << ": GIR_Done\n");
940  return true;
941 
942  default:
943  llvm_unreachable("Unexpected command");
944  }
945  }
946 }
947 
948 } // end namespace llvm
949 
950 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
Copy an operand to the specified instruction.
Check the specified operand is an MBB.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
std::vector< ComplexRendererFns::value_type > Renderers
void push_back(const T &Elt)
Definition: SmallVector.h:211
Build a new instruction.
unsigned getReg() const
getReg - Returns the register number.
bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx, const TargetRegisterClass &RC, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Constrain a register operand of an instruction I to a specified register class.
Check the register bank for the specified operand.
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
uint64_t getSize() const
Return the size in bytes of the memory reference.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Definition: DataLayout.h:388
unsigned const TargetRegisterInfo * TRI
bool equalsInt(uint64_t V) const
A helper method that can be used to determine if the constant contained within is equal to a constant...
Definition: Constants.h:164
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
Create a new temporary register that&#39;s not constrained.
const ComplexMatcherMemFn * ComplexPredicates
Switch over the opcode on the specified instruction.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Check the size of the memory access for the given machine memory operand against the size of an opera...
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
bool isIntrinsicID() const
Holds all the information related to register banks.
A description of a memory reference used in the backend.
Check the instruction has the right number of operands.
const HexagonInstrInfo * TII
bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice, which is based on C++&#39;s definition.
static StringRef getName(Value *V)
Check the specified operands are identical.
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
Merge all memory operands into instruction.
Check the operand matches a complex predicate.
DenseMap< unsigned, unsigned > TempRegisters
SmallDenseMap< LLT, unsigned, 64 > TypeIDMap
AtomicOrdering
Atomic ordering for LLVM&#39;s memory model.
Check the feature bits.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Mutate an instruction.
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:255
Record the specified instruction.
Render a G_FCONSTANT operator as a sign-extended immediate.
Add an implicit register use to the specified instruction.
Fail the current try-block, or completely fail to match if there is no current try-block.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
TargetInstrInfo - Interface to description of machine instruction set.
bool isAtLeastOrStrongerThan(AtomicOrdering ao, AtomicOrdering other)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Add a temporary register to the specified instruction.
unsigned const MachineRegisterInfo * MRI
virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const
Render complex operands to the specified instruction.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Check an immediate predicate on the specified instruction via an APInt.
Check the opcode on the specified instruction.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Type::TypeID TypeID
Render operands to the specified instruction using a custom function.
Check a memory operation has the specified atomic ordering.
bool 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) const
Execute a given matcher table and return true if the match was successful and false otherwise...
void setCovered(uint64_t RuleID)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
Constrain an instructions operands according to the instruction description.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Check the type of a pointer to any address space.
Check a generic C++ instruction predicate.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Check the size of the memory access for the given machine memory operand.
Check if the specified operand is safe to fold into the current instruction.
bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const
Add an register to the specified instruction.
Check the operand is a specific literal integer (i.e.
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Copy an operand to the specified instruction.
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:841
Intrinsic::ID getIntrinsicID() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:26
Switch over the LLT on the specified instruction operand.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:374
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition: Utils.cpp:87
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Increment the rule coverage counter.
Class for arbitrary precision integers.
Definition: APInt.h:69
Add an immediate to the specified instruction.
Render a G_CONSTANT operator as a sign-extended immediate.
bool isPointer() const
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
bool hasValue() const
Definition: Optional.h:259
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
virtual bool testImmPredicate_I64(unsigned, int64_t) const
Render sub-operands of complex operands to the specified instruction.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:44
Check the operand is a specific intrinsic ID.
Add an implicit register def to the specified instruction.
uint32_t Size
Definition: Profile.cpp:46
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition: MathExtras.h:748
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Check the type for the specified operand.
Check the operand is a specific integer.
LLVM Value Representation.
Definition: Value.h:72
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Check a floating point immediate predicate on the specified instruction.
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
Check an immediate predicate on the specified instruction.
const ConstantInt * getCImm() const
Constrain an instruction operand to a register class.
A successful emission.
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const
Get a register bank that covers RC.
bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const
Return true if MI can obviously be folded into IntoMI.
void resize(size_type N)
Definition: SmallVector.h:344