LLVM  10.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  }
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  // This accepts a list of possible address spaces.
377  const int NumAddrSpace = MatchTable[CurrentIdx++];
378 
379  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
380  if (handleReject() == RejectAndGiveUp)
381  return false;
382  break;
383  }
384 
385  // Need to still jump to the end of the list of address spaces if we find
386  // a match earlier.
387  const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
388 
389  const MachineMemOperand *MMO
390  = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
391  const unsigned MMOAddrSpace = MMO->getAddrSpace();
392 
393  bool Success = false;
394  for (int I = 0; I != NumAddrSpace; ++I) {
395  unsigned AddrSpace = MatchTable[CurrentIdx++];
398  dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
399  << AddrSpace << '\n');
400 
401  if (AddrSpace == MMOAddrSpace) {
402  Success = true;
403  break;
404  }
405  }
406 
407  CurrentIdx = LastIdx;
408  if (!Success && handleReject() == RejectAndGiveUp)
409  return false;
410  break;
411  }
413  int64_t InsnID = MatchTable[CurrentIdx++];
414  int64_t MMOIdx = MatchTable[CurrentIdx++];
415  unsigned MinAlign = MatchTable[CurrentIdx++];
416 
417  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
418 
419  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
420  if (handleReject() == RejectAndGiveUp)
421  return false;
422  break;
423  }
424 
425  MachineMemOperand *MMO
426  = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
428  dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
429  << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
430  << ")->getAlignment() >= " << MinAlign << ")\n");
431  if (MMO->getAlignment() < MinAlign && handleReject() == RejectAndGiveUp)
432  return false;
433 
434  break;
435  }
437  int64_t InsnID = MatchTable[CurrentIdx++];
438  int64_t MMOIdx = MatchTable[CurrentIdx++];
439  uint64_t Size = MatchTable[CurrentIdx++];
440 
442  dbgs() << CurrentIdx
443  << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
444  << "]->memoperands() + " << MMOIdx
445  << ", Size=" << Size << ")\n");
446  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
447 
448  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
449  if (handleReject() == RejectAndGiveUp)
450  return false;
451  break;
452  }
453 
454  MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
455 
457  dbgs() << MMO->getSize() << " bytes vs " << Size
458  << " bytes\n");
459  if (MMO->getSize() != Size)
460  if (handleReject() == RejectAndGiveUp)
461  return false;
462 
463  break;
464  }
468  int64_t InsnID = MatchTable[CurrentIdx++];
469  int64_t MMOIdx = MatchTable[CurrentIdx++];
470  int64_t OpIdx = MatchTable[CurrentIdx++];
471 
474  dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
475  << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
476  ? "EqualTo"
477  : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
478  ? "GreaterThan"
479  : "LessThan")
480  << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
481  << ", OpIdx=" << OpIdx << ")\n");
482  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
483 
484  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
485  if (!MO.isReg()) {
487  dbgs() << CurrentIdx << ": Not a register\n");
488  if (handleReject() == RejectAndGiveUp)
489  return false;
490  break;
491  }
492 
493  if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
494  if (handleReject() == RejectAndGiveUp)
495  return false;
496  break;
497  }
498 
499  MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
500 
501  unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
502  if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
503  MMO->getSizeInBits() != Size) {
504  if (handleReject() == RejectAndGiveUp)
505  return false;
506  } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
507  MMO->getSizeInBits() >= Size) {
508  if (handleReject() == RejectAndGiveUp)
509  return false;
510  } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
511  MMO->getSizeInBits() <= Size)
512  if (handleReject() == RejectAndGiveUp)
513  return false;
514 
515  break;
516  }
517  case GIM_CheckType: {
518  int64_t InsnID = MatchTable[CurrentIdx++];
519  int64_t OpIdx = MatchTable[CurrentIdx++];
520  int64_t TypeID = MatchTable[CurrentIdx++];
522  dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
523  << "]->getOperand(" << OpIdx
524  << "), TypeID=" << TypeID << ")\n");
525  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
526  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
527  if (!MO.isReg() ||
528  MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
529  if (handleReject() == RejectAndGiveUp)
530  return false;
531  }
532  break;
533  }
534  case GIM_CheckPointerToAny: {
535  int64_t InsnID = MatchTable[CurrentIdx++];
536  int64_t OpIdx = MatchTable[CurrentIdx++];
537  int64_t SizeInBits = MatchTable[CurrentIdx++];
538 
540  dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
541  << InsnID << "]->getOperand(" << OpIdx
542  << "), SizeInBits=" << SizeInBits << ")\n");
543  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
544  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
545  const LLT Ty = MRI.getType(MO.getReg());
546 
547  // iPTR must be looked up in the target.
548  if (SizeInBits == 0) {
549  MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
550  const unsigned AddrSpace = Ty.getAddressSpace();
551  SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
552  }
553 
554  assert(SizeInBits != 0 && "Pointer size must be known");
555 
556  if (MO.isReg()) {
557  if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
558  if (handleReject() == RejectAndGiveUp)
559  return false;
560  } else if (handleReject() == RejectAndGiveUp)
561  return false;
562 
563  break;
564  }
566  int64_t InsnID = MatchTable[CurrentIdx++];
567  int64_t OpIdx = MatchTable[CurrentIdx++];
568  int64_t RCEnum = MatchTable[CurrentIdx++];
570  dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
571  << InsnID << "]->getOperand(" << OpIdx
572  << "), RCEnum=" << RCEnum << ")\n");
573  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
574  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
575  if (!MO.isReg() ||
576  &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
577  RBI.getRegBank(MO.getReg(), MRI, TRI)) {
578  if (handleReject() == RejectAndGiveUp)
579  return false;
580  }
581  break;
582  }
583 
585  int64_t InsnID = MatchTable[CurrentIdx++];
586  int64_t OpIdx = MatchTable[CurrentIdx++];
587  int64_t RendererID = MatchTable[CurrentIdx++];
588  int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
590  dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
591  << "] = GIM_CheckComplexPattern(MIs[" << InsnID
592  << "]->getOperand(" << OpIdx
593  << "), ComplexPredicateID=" << ComplexPredicateID
594  << ")\n");
595  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
596  // FIXME: Use std::invoke() when it's available.
597  ComplexRendererFns Renderer =
598  (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
599  State.MIs[InsnID]->getOperand(OpIdx));
600  if (Renderer.hasValue())
601  State.Renderers[RendererID] = Renderer.getValue();
602  else
603  if (handleReject() == RejectAndGiveUp)
604  return false;
605  break;
606  }
607 
608  case GIM_CheckConstantInt: {
609  int64_t InsnID = MatchTable[CurrentIdx++];
610  int64_t OpIdx = MatchTable[CurrentIdx++];
611  int64_t Value = MatchTable[CurrentIdx++];
613  dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
614  << InsnID << "]->getOperand(" << OpIdx
615  << "), Value=" << Value << ")\n");
616  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
617  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
618  if (MO.isReg()) {
619  // isOperandImmEqual() will sign-extend to 64-bits, so should we.
620  LLT Ty = MRI.getType(MO.getReg());
621  Value = SignExtend64(Value, Ty.getSizeInBits());
622 
623  if (!isOperandImmEqual(MO, Value, MRI)) {
624  if (handleReject() == RejectAndGiveUp)
625  return false;
626  }
627  } else if (handleReject() == RejectAndGiveUp)
628  return false;
629 
630  break;
631  }
632 
633  case GIM_CheckLiteralInt: {
634  int64_t InsnID = MatchTable[CurrentIdx++];
635  int64_t OpIdx = MatchTable[CurrentIdx++];
636  int64_t Value = MatchTable[CurrentIdx++];
638  dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
639  << InsnID << "]->getOperand(" << OpIdx
640  << "), Value=" << Value << ")\n");
641  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
642  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
643  if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
644  if (handleReject() == RejectAndGiveUp)
645  return false;
646  }
647  break;
648  }
649 
650  case GIM_CheckIntrinsicID: {
651  int64_t InsnID = MatchTable[CurrentIdx++];
652  int64_t OpIdx = MatchTable[CurrentIdx++];
653  int64_t Value = MatchTable[CurrentIdx++];
655  dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
656  << InsnID << "]->getOperand(" << OpIdx
657  << "), Value=" << Value << ")\n");
658  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
659  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
660  if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
661  if (handleReject() == RejectAndGiveUp)
662  return false;
663  break;
664  }
665 
666  case GIM_CheckIsMBB: {
667  int64_t InsnID = MatchTable[CurrentIdx++];
668  int64_t OpIdx = MatchTable[CurrentIdx++];
670  dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
671  << "]->getOperand(" << OpIdx << "))\n");
672  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
673  if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
674  if (handleReject() == RejectAndGiveUp)
675  return false;
676  }
677  break;
678  }
679 
680  case GIM_CheckIsSafeToFold: {
681  int64_t InsnID = MatchTable[CurrentIdx++];
683  dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
684  << InsnID << "])\n");
685  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
686  if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
687  if (handleReject() == RejectAndGiveUp)
688  return false;
689  }
690  break;
691  }
692  case GIM_CheckIsSameOperand: {
693  int64_t InsnID = MatchTable[CurrentIdx++];
694  int64_t OpIdx = MatchTable[CurrentIdx++];
695  int64_t OtherInsnID = MatchTable[CurrentIdx++];
696  int64_t OtherOpIdx = MatchTable[CurrentIdx++];
698  dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
699  << InsnID << "][" << OpIdx << "], MIs["
700  << OtherInsnID << "][" << OtherOpIdx << "])\n");
701  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
702  assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
703  if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
704  State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
705  if (handleReject() == RejectAndGiveUp)
706  return false;
707  }
708  break;
709  }
710  case GIM_Reject:
712  dbgs() << CurrentIdx << ": GIM_Reject\n");
713  if (handleReject() == RejectAndGiveUp)
714  return false;
715  break;
716 
717  case GIR_MutateOpcode: {
718  int64_t OldInsnID = MatchTable[CurrentIdx++];
719  uint64_t NewInsnID = MatchTable[CurrentIdx++];
720  int64_t NewOpcode = MatchTable[CurrentIdx++];
721  if (NewInsnID >= OutMIs.size())
722  OutMIs.resize(NewInsnID + 1);
723 
724  OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
725  State.MIs[OldInsnID]);
726  OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
728  dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
729  << NewInsnID << "], MIs[" << OldInsnID << "], "
730  << NewOpcode << ")\n");
731  break;
732  }
733 
734  case GIR_BuildMI: {
735  uint64_t NewInsnID = MatchTable[CurrentIdx++];
736  int64_t Opcode = MatchTable[CurrentIdx++];
737  if (NewInsnID >= OutMIs.size())
738  OutMIs.resize(NewInsnID + 1);
739 
740  OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
741  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
743  dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
744  << NewInsnID << "], " << Opcode << ")\n");
745  break;
746  }
747 
748  case GIR_Copy: {
749  int64_t NewInsnID = MatchTable[CurrentIdx++];
750  int64_t OldInsnID = MatchTable[CurrentIdx++];
751  int64_t OpIdx = MatchTable[CurrentIdx++];
752  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
753  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
755  dbgs()
756  << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
757  << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
758  break;
759  }
760 
761  case GIR_CopyOrAddZeroReg: {
762  int64_t NewInsnID = MatchTable[CurrentIdx++];
763  int64_t OldInsnID = MatchTable[CurrentIdx++];
764  int64_t OpIdx = MatchTable[CurrentIdx++];
765  int64_t ZeroReg = MatchTable[CurrentIdx++];
766  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
767  MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
768  if (isOperandImmEqual(MO, 0, MRI))
769  OutMIs[NewInsnID].addReg(ZeroReg);
770  else
771  OutMIs[NewInsnID].add(MO);
773  dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
774  << NewInsnID << "], MIs[" << OldInsnID << "], "
775  << OpIdx << ", " << ZeroReg << ")\n");
776  break;
777  }
778 
779  case GIR_CopySubReg: {
780  int64_t NewInsnID = MatchTable[CurrentIdx++];
781  int64_t OldInsnID = MatchTable[CurrentIdx++];
782  int64_t OpIdx = MatchTable[CurrentIdx++];
783  int64_t SubRegIdx = MatchTable[CurrentIdx++];
784  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
785  OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
786  0, SubRegIdx);
788  dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
789  << NewInsnID << "], MIs[" << OldInsnID << "], "
790  << OpIdx << ", " << SubRegIdx << ")\n");
791  break;
792  }
793 
794  case GIR_AddImplicitDef: {
795  int64_t InsnID = MatchTable[CurrentIdx++];
796  int64_t RegNum = MatchTable[CurrentIdx++];
797  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
798  OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
800  dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
801  << InsnID << "], " << RegNum << ")\n");
802  break;
803  }
804 
805  case GIR_AddImplicitUse: {
806  int64_t InsnID = MatchTable[CurrentIdx++];
807  int64_t RegNum = MatchTable[CurrentIdx++];
808  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
809  OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
811  dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
812  << InsnID << "], " << RegNum << ")\n");
813  break;
814  }
815 
816  case GIR_AddRegister: {
817  int64_t InsnID = MatchTable[CurrentIdx++];
818  int64_t RegNum = MatchTable[CurrentIdx++];
819  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
820  OutMIs[InsnID].addReg(RegNum);
822  dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
823  << InsnID << "], " << RegNum << ")\n");
824  break;
825  }
826 
827  case GIR_AddTempRegister: {
828  int64_t InsnID = MatchTable[CurrentIdx++];
829  int64_t TempRegID = MatchTable[CurrentIdx++];
830  uint64_t TempRegFlags = MatchTable[CurrentIdx++];
831  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
832  OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
834  dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
835  << InsnID << "], TempRegisters[" << TempRegID
836  << "], " << TempRegFlags << ")\n");
837  break;
838  }
839 
840  case GIR_AddImm: {
841  int64_t InsnID = MatchTable[CurrentIdx++];
842  int64_t Imm = MatchTable[CurrentIdx++];
843  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
844  OutMIs[InsnID].addImm(Imm);
846  dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
847  << "], " << Imm << ")\n");
848  break;
849  }
850 
851  case GIR_ComplexRenderer: {
852  int64_t InsnID = MatchTable[CurrentIdx++];
853  int64_t RendererID = MatchTable[CurrentIdx++];
854  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
855  for (const auto &RenderOpFn : State.Renderers[RendererID])
856  RenderOpFn(OutMIs[InsnID]);
858  dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
859  << InsnID << "], " << RendererID << ")\n");
860  break;
861  }
863  int64_t InsnID = MatchTable[CurrentIdx++];
864  int64_t RendererID = MatchTable[CurrentIdx++];
865  int64_t RenderOpID = MatchTable[CurrentIdx++];
866  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
867  State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
869  dbgs() << CurrentIdx
870  << ": GIR_ComplexSubOperandRenderer(OutMIs["
871  << InsnID << "], " << RendererID << ", "
872  << RenderOpID << ")\n");
873  break;
874  }
875 
876  case GIR_CopyConstantAsSImm: {
877  int64_t NewInsnID = MatchTable[CurrentIdx++];
878  int64_t OldInsnID = MatchTable[CurrentIdx++];
879  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
880  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
881  if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
882  OutMIs[NewInsnID].addImm(
883  State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
884  } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
885  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
886  else
887  llvm_unreachable("Expected Imm or CImm operand");
889  dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
890  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
891  break;
892  }
893 
894  // TODO: Needs a test case once we have a pattern that uses this.
896  int64_t NewInsnID = MatchTable[CurrentIdx++];
897  int64_t OldInsnID = MatchTable[CurrentIdx++];
898  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
899  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
900  if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
901  OutMIs[NewInsnID].addFPImm(
902  State.MIs[OldInsnID]->getOperand(1).getFPImm());
903  else
904  llvm_unreachable("Expected FPImm operand");
906  dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
907  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
908  break;
909  }
910 
911  case GIR_CustomRenderer: {
912  int64_t InsnID = MatchTable[CurrentIdx++];
913  int64_t OldInsnID = MatchTable[CurrentIdx++];
914  int64_t RendererFnID = MatchTable[CurrentIdx++];
915  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
917  dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
918  << InsnID << "], MIs[" << OldInsnID << "], "
919  << RendererFnID << ")\n");
920  (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
921  *State.MIs[OldInsnID]);
922  break;
923  }
924  case GIR_ConstrainOperandRC: {
925  int64_t InsnID = MatchTable[CurrentIdx++];
926  int64_t OpIdx = MatchTable[CurrentIdx++];
927  int64_t RCEnum = MatchTable[CurrentIdx++];
928  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
929  constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
930  *TRI.getRegClass(RCEnum), TII, TRI, RBI);
932  dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
933  << InsnID << "], " << OpIdx << ", " << RCEnum
934  << ")\n");
935  break;
936  }
937 
939  int64_t InsnID = MatchTable[CurrentIdx++];
940  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
941  constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
942  RBI);
944  dbgs() << CurrentIdx
945  << ": GIR_ConstrainSelectedInstOperands(OutMIs["
946  << InsnID << "])\n");
947  break;
948  }
949 
950  case GIR_MergeMemOperands: {
951  int64_t InsnID = MatchTable[CurrentIdx++];
952  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
953 
955  dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
956  << InsnID << "]");
957  int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
958  while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
961  dbgs() << ", MIs[" << MergeInsnID << "]");
962  for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
963  OutMIs[InsnID].addMemOperand(MMO);
964  }
966  break;
967  }
968 
969  case GIR_EraseFromParent: {
970  int64_t InsnID = MatchTable[CurrentIdx++];
971  assert(State.MIs[InsnID] &&
972  "Attempted to erase an undefined instruction");
973  State.MIs[InsnID]->eraseFromParent();
975  dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
976  << InsnID << "])\n");
977  break;
978  }
979 
980  case GIR_MakeTempReg: {
981  int64_t TempRegID = MatchTable[CurrentIdx++];
982  int64_t TypeID = MatchTable[CurrentIdx++];
983 
984  State.TempRegisters[TempRegID] =
985  MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
987  dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
988  << "] = GIR_MakeTempReg(" << TypeID << ")\n");
989  break;
990  }
991 
992  case GIR_Coverage: {
993  int64_t RuleID = MatchTable[CurrentIdx++];
994  CoverageInfo.setCovered(RuleID);
995 
997  dbgs()
998  << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
999  break;
1000  }
1001 
1002  case GIR_Done:
1004  dbgs() << CurrentIdx << ": GIR_Done\n");
1005  return true;
1006 
1007  default:
1008  llvm_unreachable("Unexpected command");
1009  }
1010  }
1011 }
1012 
1013 } // end namespace llvm
1014 
1015 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
Constrain an instruction operand to a register class.
Check an immediate predicate on the specified instruction via an APInt.
Record the specified instruction.
unsigned getAddrSpace() const
This class represents lattice values for constants.
Definition: AllocatorList.h:23
std::vector< ComplexRendererFns::value_type > Renderers
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
void push_back(const T &Elt)
Definition: SmallVector.h:211
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
Add an implicit register use to the specified instruction.
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 operand is a specific literal integer (i.e.
Increment the rule coverage counter.
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:389
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 the operand is a specific intrinsic ID.
Check the opcode on the specified instruction.
const ComplexMatcherMemFn * ComplexPredicates
A successful emission.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Check an immediate predicate on 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.
Check the specified operand is an MBB.
Check the type for the specified operand.
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.
Render sub-operands of complex operands to the specified instruction.
static StringRef getName(Value *V)
Check a generic C++ instruction predicate.
Switch over the LLT on the specified instruction operand.
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
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 ...
Check the feature bits.
Check the size of the memory access for the given machine memory operand against the size of an opera...
Copy an operand to the specified instruction.
Build a new instruction.
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:255
uint64_t getSizeInBits() const
Return the size in bits of the memory reference.
Create a new temporary register that&#39;s not constrained.
Check the address space of the memory access for the given machine memory operand.
Check a floating point immediate predicate on the specified instruction.
Add an register to the specified instruction.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Check the instruction has the right number of operands.
TargetInstrInfo - Interface to description of machine instruction set.
bool isAtLeastOrStrongerThan(AtomicOrdering ao, AtomicOrdering other)
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
Definition: MathExtras.h:614
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Merge all memory operands into instruction.
unsigned const MachineRegisterInfo * MRI
virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const
Render a G_CONSTANT operator as a sign-extended immediate.
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
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.
Check the minimum alignment of the memory access for the given machine memory operand.
Type::TypeID TypeID
Check the size of the memory access for the given machine memory operand.
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...
Render operands to the specified instruction using a custom function.
Check the register bank for the specified operand.
unsigned getAddressSpace() const
void setCovered(uint64_t RuleID)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Render a G_FCONSTANT operator as a sign-extended immediate.
size_t size() const
Definition: SmallVector.h:52
Check the specified operands are identical.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getAlignment() const
Return the minimum known alignment in bytes of the actual memory reference.
Add a temporary register to the specified instruction.
Check the type of a pointer to any address space.
bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:243
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:837
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:374
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
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:111
Add an immediate 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
Add an implicit register def to the specified instruction.
bool isPointer() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
#define Success
Mutate an instruction.
Representation of each machine instruction.
Definition: MachineInstr.h:64
bool hasValue() const
Definition: Optional.h:259
virtual bool testImmPredicate_I64(unsigned, int64_t) const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
Switch over the opcode on the specified instruction.
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 integer.
#define I(x, y, z)
Definition: MD5.cpp:58
Constrain an instructions operands according to the instruction description.
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:740
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
LLVM Value Representation.
Definition: Value.h:73
Check if the specified operand is safe to fold into the current instruction.
Render complex operands to the specified instruction.
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Register getReg() const
getReg - Returns the register number.
const ConstantInt * getCImm() const
Fail the current try-block, or completely fail to match if there is no current try-block.
Check the operand matches a complex predicate.
Check a memory operation has the specified atomic ordering.
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