LLVM  7.0.0svn
InstructionSelectorImpl.h
Go to the documentation of this file.
1 //===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file This file declares the API for the instruction selector.
11 /// This class is responsible for selecting machine instructions.
12 /// It's implemented by the target. It's used by the InstructionSelect pass.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
17 #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
18 
19 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/IR/Constants.h"
30 #include "llvm/Support/Debug.h"
33 #include <cassert>
34 #include <cstddef>
35 #include <cstdint>
36 
37 namespace llvm {
38 
39 /// GlobalISel PatFrag Predicates
40 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  uint64_t CurrentIdx = 0;
57  SmallVector<uint64_t, 8> OnFailResumeAt;
58 
59  enum RejectAction { RejectAndGiveUp, RejectAndResume };
60  auto handleReject = [&]() -> RejectAction {
62  dbgs() << CurrentIdx << ": Rejected\n");
63  if (OnFailResumeAt.empty())
64  return RejectAndGiveUp;
65  CurrentIdx = OnFailResumeAt.back();
66  OnFailResumeAt.pop_back();
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  switch (MatchTable[CurrentIdx++]) {
76  case GIM_Try: {
78  dbgs() << CurrentIdx << ": Begin try-block\n");
79  OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
80  break;
81  }
82 
83  case GIM_RecordInsn: {
84  int64_t NewInsnID = MatchTable[CurrentIdx++];
85  int64_t InsnID = MatchTable[CurrentIdx++];
86  int64_t OpIdx = MatchTable[CurrentIdx++];
87 
88  // As an optimisation we require that MIs[0] is always the root. Refuse
89  // any attempt to modify it.
90  assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
91 
92  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
93  if (!MO.isReg()) {
95  dbgs() << CurrentIdx << ": Not a register\n");
96  if (handleReject() == RejectAndGiveUp)
97  return false;
98  break;
99  }
100  if (TRI.isPhysicalRegister(MO.getReg())) {
102  dbgs() << CurrentIdx << ": Is a physical register\n");
103  if (handleReject() == RejectAndGiveUp)
104  return false;
105  break;
106  }
107 
108  MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
109  if ((size_t)NewInsnID < State.MIs.size())
110  State.MIs[NewInsnID] = NewMI;
111  else {
112  assert((size_t)NewInsnID == State.MIs.size() &&
113  "Expected to store MIs in order");
114  State.MIs.push_back(NewMI);
115  }
117  dbgs() << CurrentIdx << ": MIs[" << NewInsnID
118  << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
119  << ")\n");
120  break;
121  }
122 
123  case GIM_CheckFeatures: {
124  int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
126  dbgs() << CurrentIdx
127  << ": GIM_CheckFeatures(ExpectedBitsetID="
128  << ExpectedBitsetID << ")\n");
129  if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
130  ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
131  if (handleReject() == RejectAndGiveUp)
132  return false;
133  }
134  break;
135  }
136 
137  case GIM_CheckOpcode: {
138  int64_t InsnID = MatchTable[CurrentIdx++];
139  int64_t Expected = MatchTable[CurrentIdx++];
140 
141  unsigned Opcode = State.MIs[InsnID]->getOpcode();
143  dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
144  << "], ExpectedOpcode=" << Expected
145  << ") // Got=" << Opcode << "\n");
146  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
147  if (Opcode != Expected) {
148  if (handleReject() == RejectAndGiveUp)
149  return false;
150  }
151  break;
152  }
153 
154  case GIM_CheckNumOperands: {
155  int64_t InsnID = MatchTable[CurrentIdx++];
156  int64_t Expected = MatchTable[CurrentIdx++];
158  dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
159  << InsnID << "], Expected=" << Expected << ")\n");
160  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
161  if (State.MIs[InsnID]->getNumOperands() != Expected) {
162  if (handleReject() == RejectAndGiveUp)
163  return false;
164  }
165  break;
166  }
168  int64_t InsnID = MatchTable[CurrentIdx++];
169  int64_t Predicate = MatchTable[CurrentIdx++];
171  dbgs()
172  << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
173  << InsnID << "], Predicate=" << Predicate << ")\n");
174  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
175  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
176  "Expected G_CONSTANT");
177  assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
178  int64_t Value = 0;
179  if (State.MIs[InsnID]->getOperand(1).isCImm())
180  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
181  else if (State.MIs[InsnID]->getOperand(1).isImm())
182  Value = State.MIs[InsnID]->getOperand(1).getImm();
183  else
184  llvm_unreachable("Expected Imm or CImm operand");
185 
186  if (!testImmPredicate_I64(Predicate, Value))
187  if (handleReject() == RejectAndGiveUp)
188  return false;
189  break;
190  }
192  int64_t InsnID = MatchTable[CurrentIdx++];
193  int64_t Predicate = MatchTable[CurrentIdx++];
195  dbgs()
196  << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
197  << InsnID << "], Predicate=" << Predicate << ")\n");
198  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
199  assert(State.MIs[InsnID]->getOpcode() && "Expected G_CONSTANT");
200  assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
201  APInt Value;
202  if (State.MIs[InsnID]->getOperand(1).isCImm())
203  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
204  else
205  llvm_unreachable("Expected Imm or CImm operand");
206 
207  if (!testImmPredicate_APInt(Predicate, Value))
208  if (handleReject() == RejectAndGiveUp)
209  return false;
210  break;
211  }
213  int64_t InsnID = MatchTable[CurrentIdx++];
214  int64_t Predicate = MatchTable[CurrentIdx++];
216  dbgs()
217  << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
218  << InsnID << "], Predicate=" << Predicate << ")\n");
219  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
220  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
221  "Expected G_FCONSTANT");
222  assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
223  assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
224  APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
225 
226  if (!testImmPredicate_APFloat(Predicate, Value))
227  if (handleReject() == RejectAndGiveUp)
228  return false;
229  break;
230  }
232  int64_t InsnID = MatchTable[CurrentIdx++];
233  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
235  dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
236  << InsnID << "], " << (uint64_t)Ordering << ")\n");
237  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
238 
239  if (!State.MIs[InsnID]->hasOneMemOperand())
240  if (handleReject() == RejectAndGiveUp)
241  return false;
242 
243  for (const auto &MMO : State.MIs[InsnID]->memoperands())
244  if (MMO->getOrdering() != Ordering)
245  if (handleReject() == RejectAndGiveUp)
246  return false;
247  break;
248  }
250  int64_t InsnID = MatchTable[CurrentIdx++];
251  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
253  dbgs() << CurrentIdx
254  << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
255  << InsnID << "], " << (uint64_t)Ordering << ")\n");
256  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
257 
258  if (!State.MIs[InsnID]->hasOneMemOperand())
259  if (handleReject() == RejectAndGiveUp)
260  return false;
261 
262  for (const auto &MMO : State.MIs[InsnID]->memoperands())
263  if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering))
264  if (handleReject() == RejectAndGiveUp)
265  return false;
266  break;
267  }
269  int64_t InsnID = MatchTable[CurrentIdx++];
270  AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
272  dbgs() << CurrentIdx
273  << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
274  << InsnID << "], " << (uint64_t)Ordering << ")\n");
275  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
276 
277  if (!State.MIs[InsnID]->hasOneMemOperand())
278  if (handleReject() == RejectAndGiveUp)
279  return false;
280 
281  for (const auto &MMO : State.MIs[InsnID]->memoperands())
282  if (!isStrongerThan(Ordering, MMO->getOrdering()))
283  if (handleReject() == RejectAndGiveUp)
284  return false;
285  break;
286  }
287  case GIM_CheckType: {
288  int64_t InsnID = MatchTable[CurrentIdx++];
289  int64_t OpIdx = MatchTable[CurrentIdx++];
290  int64_t TypeID = MatchTable[CurrentIdx++];
292  dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
293  << "]->getOperand(" << OpIdx
294  << "), TypeID=" << TypeID << ")\n");
295  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
296 
297  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
298  if (!MO.isReg() ||
299  MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
300  if (handleReject() == RejectAndGiveUp)
301  return false;
302  }
303  break;
304  }
305  case GIM_CheckPointerToAny: {
306  int64_t InsnID = MatchTable[CurrentIdx++];
307  int64_t OpIdx = MatchTable[CurrentIdx++];
308  int64_t SizeInBits = MatchTable[CurrentIdx++];
309 
311  dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
312  << InsnID << "]->getOperand(" << OpIdx
313  << "), SizeInBits=" << SizeInBits << ")\n");
314  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
315 
316  // iPTR must be looked up in the target.
317  if (SizeInBits == 0) {
318  MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
319  SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
320  }
321 
322  assert(SizeInBits != 0 && "Pointer size must be known");
323 
324  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
325  if (MO.isReg()) {
326  const LLT &Ty = MRI.getType(MO.getReg());
327  if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
328  if (handleReject() == RejectAndGiveUp)
329  return false;
330  } else if (handleReject() == RejectAndGiveUp)
331  return false;
332 
333  break;
334  }
336  int64_t InsnID = MatchTable[CurrentIdx++];
337  int64_t OpIdx = MatchTable[CurrentIdx++];
338  int64_t RCEnum = MatchTable[CurrentIdx++];
340  dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
341  << InsnID << "]->getOperand(" << OpIdx
342  << "), RCEnum=" << RCEnum << ")\n");
343  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
344  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
345  if (!MO.isReg() ||
346  &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
347  RBI.getRegBank(MO.getReg(), MRI, TRI)) {
348  if (handleReject() == RejectAndGiveUp)
349  return false;
350  }
351  break;
352  }
353 
355  int64_t InsnID = MatchTable[CurrentIdx++];
356  int64_t OpIdx = MatchTable[CurrentIdx++];
357  int64_t RendererID = MatchTable[CurrentIdx++];
358  int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
360  dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
361  << "] = GIM_CheckComplexPattern(MIs[" << InsnID
362  << "]->getOperand(" << OpIdx
363  << "), ComplexPredicateID=" << ComplexPredicateID
364  << ")\n");
365  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
366  // FIXME: Use std::invoke() when it's available.
367  ComplexRendererFns Renderer =
368  (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
369  State.MIs[InsnID]->getOperand(OpIdx));
370  if (Renderer.hasValue())
371  State.Renderers[RendererID] = Renderer.getValue();
372  else
373  if (handleReject() == RejectAndGiveUp)
374  return false;
375  break;
376  }
377 
378  case GIM_CheckConstantInt: {
379  int64_t InsnID = MatchTable[CurrentIdx++];
380  int64_t OpIdx = MatchTable[CurrentIdx++];
381  int64_t Value = MatchTable[CurrentIdx++];
383  dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
384  << InsnID << "]->getOperand(" << OpIdx
385  << "), Value=" << Value << ")\n");
386  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
387 
388  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
389  if (MO.isReg()) {
390  // isOperandImmEqual() will sign-extend to 64-bits, so should we.
391  LLT Ty = MRI.getType(MO.getReg());
392  Value = SignExtend64(Value, Ty.getSizeInBits());
393 
394  if (!isOperandImmEqual(MO, Value, MRI)) {
395  if (handleReject() == RejectAndGiveUp)
396  return false;
397  }
398  } else if (handleReject() == RejectAndGiveUp)
399  return false;
400 
401  break;
402  }
403 
404  case GIM_CheckLiteralInt: {
405  int64_t InsnID = MatchTable[CurrentIdx++];
406  int64_t OpIdx = MatchTable[CurrentIdx++];
407  int64_t Value = MatchTable[CurrentIdx++];
409  dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
410  << InsnID << "]->getOperand(" << OpIdx
411  << "), Value=" << Value << ")\n");
412  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
413  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
414  if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
415  if (handleReject() == RejectAndGiveUp)
416  return false;
417  }
418  break;
419  }
420 
421  case GIM_CheckIntrinsicID: {
422  int64_t InsnID = MatchTable[CurrentIdx++];
423  int64_t OpIdx = MatchTable[CurrentIdx++];
424  int64_t Value = MatchTable[CurrentIdx++];
426  dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
427  << InsnID << "]->getOperand(" << OpIdx
428  << "), Value=" << Value << ")\n");
429  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
430  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
431  if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
432  if (handleReject() == RejectAndGiveUp)
433  return false;
434  break;
435  }
436 
437  case GIM_CheckIsMBB: {
438  int64_t InsnID = MatchTable[CurrentIdx++];
439  int64_t OpIdx = MatchTable[CurrentIdx++];
441  dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
442  << "]->getOperand(" << OpIdx << "))\n");
443  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
444  if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
445  if (handleReject() == RejectAndGiveUp)
446  return false;
447  }
448  break;
449  }
450 
451  case GIM_CheckIsSafeToFold: {
452  int64_t InsnID = MatchTable[CurrentIdx++];
454  dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
455  << InsnID << "])\n");
456  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
457  if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
458  if (handleReject() == RejectAndGiveUp)
459  return false;
460  }
461  break;
462  }
463  case GIM_CheckIsSameOperand: {
464  int64_t InsnID = MatchTable[CurrentIdx++];
465  int64_t OpIdx = MatchTable[CurrentIdx++];
466  int64_t OtherInsnID = MatchTable[CurrentIdx++];
467  int64_t OtherOpIdx = MatchTable[CurrentIdx++];
469  dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
470  << InsnID << "][" << OpIdx << "], MIs["
471  << OtherInsnID << "][" << OtherOpIdx << "])\n");
472  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
473  assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
474  if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
475  State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
476  if (handleReject() == RejectAndGiveUp)
477  return false;
478  }
479  break;
480  }
481  case GIM_Reject:
483  dbgs() << CurrentIdx << ": GIM_Reject");
484  if (handleReject() == RejectAndGiveUp)
485  return false;
486  break;
487 
488  case GIR_MutateOpcode: {
489  int64_t OldInsnID = MatchTable[CurrentIdx++];
490  uint64_t NewInsnID = MatchTable[CurrentIdx++];
491  int64_t NewOpcode = MatchTable[CurrentIdx++];
492  if (NewInsnID >= OutMIs.size())
493  OutMIs.resize(NewInsnID + 1);
494 
495  OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
496  State.MIs[OldInsnID]);
497  OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
499  dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
500  << NewInsnID << "], MIs[" << OldInsnID << "], "
501  << NewOpcode << ")\n");
502  break;
503  }
504 
505  case GIR_BuildMI: {
506  uint64_t NewInsnID = MatchTable[CurrentIdx++];
507  int64_t Opcode = MatchTable[CurrentIdx++];
508  if (NewInsnID >= OutMIs.size())
509  OutMIs.resize(NewInsnID + 1);
510 
511  OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
512  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
514  dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
515  << NewInsnID << "], " << Opcode << ")\n");
516  break;
517  }
518 
519  case GIR_Copy: {
520  int64_t NewInsnID = MatchTable[CurrentIdx++];
521  int64_t OldInsnID = MatchTable[CurrentIdx++];
522  int64_t OpIdx = MatchTable[CurrentIdx++];
523  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
524  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
526  dbgs()
527  << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
528  << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
529  break;
530  }
531 
532  case GIR_CopyOrAddZeroReg: {
533  int64_t NewInsnID = MatchTable[CurrentIdx++];
534  int64_t OldInsnID = MatchTable[CurrentIdx++];
535  int64_t OpIdx = MatchTable[CurrentIdx++];
536  int64_t ZeroReg = MatchTable[CurrentIdx++];
537  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
538  MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
539  if (isOperandImmEqual(MO, 0, MRI))
540  OutMIs[NewInsnID].addReg(ZeroReg);
541  else
542  OutMIs[NewInsnID].add(MO);
544  dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
545  << NewInsnID << "], MIs[" << OldInsnID << "], "
546  << OpIdx << ", " << ZeroReg << ")\n");
547  break;
548  }
549 
550  case GIR_CopySubReg: {
551  int64_t NewInsnID = MatchTable[CurrentIdx++];
552  int64_t OldInsnID = MatchTable[CurrentIdx++];
553  int64_t OpIdx = MatchTable[CurrentIdx++];
554  int64_t SubRegIdx = MatchTable[CurrentIdx++];
555  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
556  OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
557  0, SubRegIdx);
559  dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
560  << NewInsnID << "], MIs[" << OldInsnID << "], "
561  << OpIdx << ", " << SubRegIdx << ")\n");
562  break;
563  }
564 
565  case GIR_AddImplicitDef: {
566  int64_t InsnID = MatchTable[CurrentIdx++];
567  int64_t RegNum = MatchTable[CurrentIdx++];
568  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
569  OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
571  dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
572  << InsnID << "], " << RegNum << ")\n");
573  break;
574  }
575 
576  case GIR_AddImplicitUse: {
577  int64_t InsnID = MatchTable[CurrentIdx++];
578  int64_t RegNum = MatchTable[CurrentIdx++];
579  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
580  OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
582  dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
583  << InsnID << "], " << RegNum << ")\n");
584  break;
585  }
586 
587  case GIR_AddRegister: {
588  int64_t InsnID = MatchTable[CurrentIdx++];
589  int64_t RegNum = MatchTable[CurrentIdx++];
590  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
591  OutMIs[InsnID].addReg(RegNum);
593  dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
594  << InsnID << "], " << RegNum << ")\n");
595  break;
596  }
597 
598  case GIR_AddTempRegister: {
599  int64_t InsnID = MatchTable[CurrentIdx++];
600  int64_t TempRegID = MatchTable[CurrentIdx++];
601  uint64_t TempRegFlags = MatchTable[CurrentIdx++];
602  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
603  OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
605  dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
606  << InsnID << "], TempRegisters[" << TempRegID
607  << "], " << TempRegFlags << ")\n");
608  break;
609  }
610 
611  case GIR_AddImm: {
612  int64_t InsnID = MatchTable[CurrentIdx++];
613  int64_t Imm = MatchTable[CurrentIdx++];
614  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
615  OutMIs[InsnID].addImm(Imm);
617  dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
618  << "], " << Imm << ")\n");
619  break;
620  }
621 
622  case GIR_ComplexRenderer: {
623  int64_t InsnID = MatchTable[CurrentIdx++];
624  int64_t RendererID = MatchTable[CurrentIdx++];
625  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
626  for (const auto &RenderOpFn : State.Renderers[RendererID])
627  RenderOpFn(OutMIs[InsnID]);
629  dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
630  << InsnID << "], " << RendererID << ")\n");
631  break;
632  }
634  int64_t InsnID = MatchTable[CurrentIdx++];
635  int64_t RendererID = MatchTable[CurrentIdx++];
636  int64_t RenderOpID = MatchTable[CurrentIdx++];
637  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
638  State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
640  dbgs() << CurrentIdx
641  << ": GIR_ComplexSubOperandRenderer(OutMIs["
642  << InsnID << "], " << RendererID << ", "
643  << RenderOpID << ")\n");
644  break;
645  }
646 
647  case GIR_CopyConstantAsSImm: {
648  int64_t NewInsnID = MatchTable[CurrentIdx++];
649  int64_t OldInsnID = MatchTable[CurrentIdx++];
650  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
651  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
652  if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
653  OutMIs[NewInsnID].addImm(
654  State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
655  } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
656  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
657  else
658  llvm_unreachable("Expected Imm or CImm operand");
660  dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
661  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
662  break;
663  }
664 
665  case GIR_CustomRenderer: {
666  int64_t InsnID = MatchTable[CurrentIdx++];
667  int64_t OldInsnID = MatchTable[CurrentIdx++];
668  int64_t RendererFnID = MatchTable[CurrentIdx++];
669  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
671  dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
672  << InsnID << "], MIs[" << OldInsnID << "], "
673  << RendererFnID << ")\n");
674  (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
675  *State.MIs[OldInsnID]);
676  break;
677  }
678  case GIR_ConstrainOperandRC: {
679  int64_t InsnID = MatchTable[CurrentIdx++];
680  int64_t OpIdx = MatchTable[CurrentIdx++];
681  int64_t RCEnum = MatchTable[CurrentIdx++];
682  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
683  constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
684  *TRI.getRegClass(RCEnum), TII, TRI, RBI);
686  dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
687  << InsnID << "], " << OpIdx << ", " << RCEnum
688  << ")\n");
689  break;
690  }
691 
693  int64_t InsnID = MatchTable[CurrentIdx++];
694  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
695  constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
696  RBI);
698  dbgs() << CurrentIdx
699  << ": GIR_ConstrainSelectedInstOperands(OutMIs["
700  << InsnID << "])\n");
701  break;
702  }
703 
704  case GIR_MergeMemOperands: {
705  int64_t InsnID = MatchTable[CurrentIdx++];
706  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
707 
709  dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
710  << InsnID << "]");
711  int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
712  while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
715  dbgs() << ", MIs[" << MergeInsnID << "]");
716  for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
717  OutMIs[InsnID].addMemOperand(MMO);
718  }
720  break;
721  }
722 
723  case GIR_EraseFromParent: {
724  int64_t InsnID = MatchTable[CurrentIdx++];
725  assert(State.MIs[InsnID] &&
726  "Attempted to erase an undefined instruction");
727  State.MIs[InsnID]->eraseFromParent();
729  dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
730  << InsnID << "])\n");
731  break;
732  }
733 
734  case GIR_MakeTempReg: {
735  int64_t TempRegID = MatchTable[CurrentIdx++];
736  int64_t TypeID = MatchTable[CurrentIdx++];
737 
738  State.TempRegisters[TempRegID] =
739  MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
741  dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
742  << "] = GIR_MakeTempReg(" << TypeID << ")\n");
743  break;
744  }
745 
746  case GIR_Coverage: {
747  int64_t RuleID = MatchTable[CurrentIdx++];
748  CoverageInfo.setCovered(RuleID);
749 
751  dbgs()
752  << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
753  break;
754  }
755 
756  case GIR_Done:
758  dbgs() << CurrentIdx << ": GIR_Done");
759  return true;
760 
761  default:
762  llvm_unreachable("Unexpected command");
763  }
764  }
765 }
766 
767 } // end namespace llvm
768 
769 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
Check the operand matches a complex predicate.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
Build a new instruction.
std::vector< ComplexRendererFns::value_type > Renderers
Add a temporary register to the specified instruction.
Check the type of a pointer to any address space.
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.
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:360
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:165
const ComplexMatcherMemFn * ComplexPredicates
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
Render complex operands to the specified instruction.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Check the feature bits.
#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.
Merge all memory operands into 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.
Check the instruction has the right number of operands.
Constrain an instruction operand to a register class.
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
DenseMap< unsigned, unsigned > TempRegisters
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 ...
Render a G_CONSTANT operator as a sign-extended immediate.
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:179
Render sub-operands of complex operands to the specified instruction.
Check the type for the specified operand.
Check a memory operation has the specified atomic ordering.
Add an immediate to the specified instruction.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
TargetInstrInfo - Interface to description of machine instruction set.
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
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.
Check the opcode on the specified instruction.
Check the specified operands are identical.
unsigned const MachineRegisterInfo * MRI
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.
Type::TypeID TypeID
Record the specified instruction.
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...
Fail the current try-block, or completely fail to match if there is no current try-block.
Render operands to the specified instruction using a custom function.
void setCovered(uint64_t RuleID)
Increment the rule coverage counter.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Check the operand is a specific integer.
Add an implicit register use to the specified instruction.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Mutate an instruction.
bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI) const
Check if the specified operand is safe to fold into the current instruction.
Check an immediate predicate on the specified instruction.
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:862
Intrinsic::ID getIntrinsicID() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:27
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
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:80
Constrain an instructions operands according to the instruction description.
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
bool isPointer() const
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:60
bool hasValue() const
Definition: Optional.h:183
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Copy an operand to the specified instruction.
virtual bool testImmPredicate_I64(unsigned, int64_t) const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
Copy an operand to the specified instruction.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
Check the register bank for the specified operand.
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:741
Check the operand is a specific intrinsic ID.
Create a new temporary register that&#39;s not constrained.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
A successful emission.
Add an implicit register def to the specified instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
Check a floating point immediate predicate on the specified instruction.
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
Add an register to the specified instruction.
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
Check the specified operand is an MBB.
const ConstantInt * getCImm() const
Check an immediate predicate on the specified instruction via an APInt.
Check the operand is a specific literal integer (i.e.
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:353