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
Build a new instruction.
Merge all memory operands into instruction.
Add an implicit register def to the specified instruction.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
std::vector< ComplexRendererFns::value_type > Renderers
Check the operand is a specific integer.
void push_back(const T &Elt)
Definition: SmallVector.h:211
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 specified operands are identical.
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.
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
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:365
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
Check a memory operation has the specified atomic ordering.
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
Check an immediate predicate on the specified instruction via an APInt.
const ComplexMatcherMemFn * ComplexPredicates
Copy an operand to the specified instruction.
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
Check the operand matches a complex predicate.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Record the specified instruction.
Render complex operands to the specified instruction.
#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.
Add an immediate to the specified instruction.
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.
Constrain an instruction operand to a register class.
Check the size of the memory access for the given machine memory operand against the size of an opera...
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
Render a G_CONSTANT operator as a sign-extended immediate.
Check the operand is a specific intrinsic ID.
Switch over the opcode on the specified instruction.
DenseMap< unsigned, unsigned > TempRegisters
SmallDenseMap< LLT, unsigned, 64 > TypeIDMap
AtomicOrdering
Atomic ordering for LLVM&#39;s memory model.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:255
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.
Render a G_FCONSTANT operator as a sign-extended immediate.
unsigned const MachineRegisterInfo * MRI
virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const
Copy an operand to the specified instruction.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Render sub-operands of complex operands to the specified instruction.
Type::TypeID TypeID
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...
Mutate an instruction.
Render operands to the specified instruction using a custom function.
void setCovered(uint64_t RuleID)
Check a generic C++ instruction predicate.
Increment the rule coverage counter.
Check the opcode on the specified instruction.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Constrain an instructions operands according to the instruction description.
Check the operand is a specific literal integer (i.e.
Add an register to the specified instruction.
Check the type for the specified operand.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Check an immediate predicate on the specified instruction.
bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
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:839
Check the register bank for the specified operand.
Intrinsic::ID getIntrinsicID() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:26
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:373
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
Add an implicit register use to the specified instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Class for arbitrary precision integers.
Definition: APInt.h:69
A successful emission.
bool isPointer() const
Check the specified operand is an MBB.
Switch over the LLT on the specified instruction operand.
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
Check the type of a pointer to any address space.
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
Check the feature bits.
Check the size of the memory access for the given machine memory operand.
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
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 if the specified operand is safe to fold into the current instruction.
LLVM Value Representation.
Definition: Value.h:72
Fail the current try-block, or completely fail to match if there is no current try-block.
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
Check the instruction has the right number of operands.
const ConstantInt * getCImm() const
Create a new temporary register that&#39;s not constrained.
Add a temporary register to the specified instruction.
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:343