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  if (MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg()) !=
297  ISelInfo.TypeObjects[TypeID]) {
298  if (handleReject() == RejectAndGiveUp)
299  return false;
300  }
301  break;
302  }
303  case GIM_CheckPointerToAny: {
304  int64_t InsnID = MatchTable[CurrentIdx++];
305  int64_t OpIdx = MatchTable[CurrentIdx++];
306  int64_t SizeInBits = MatchTable[CurrentIdx++];
307 
309  dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
310  << InsnID << "]->getOperand(" << OpIdx
311  << "), SizeInBits=" << SizeInBits << ")\n");
312  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
313 
314  // iPTR must be looked up in the target.
315  if (SizeInBits == 0) {
316  MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
317  SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
318  }
319 
320  assert(SizeInBits != 0 && "Pointer size must be known");
321 
322  const LLT &Ty = MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg());
323  if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) {
324  if (handleReject() == RejectAndGiveUp)
325  return false;
326  }
327  break;
328  }
330  int64_t InsnID = MatchTable[CurrentIdx++];
331  int64_t OpIdx = MatchTable[CurrentIdx++];
332  int64_t RCEnum = MatchTable[CurrentIdx++];
334  dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
335  << InsnID << "]->getOperand(" << OpIdx
336  << "), RCEnum=" << RCEnum << ")\n");
337  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
338  if (&RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
339  RBI.getRegBank(State.MIs[InsnID]->getOperand(OpIdx).getReg(), MRI,
340  TRI)) {
341  if (handleReject() == RejectAndGiveUp)
342  return false;
343  }
344  break;
345  }
346 
348  int64_t InsnID = MatchTable[CurrentIdx++];
349  int64_t OpIdx = MatchTable[CurrentIdx++];
350  int64_t RendererID = MatchTable[CurrentIdx++];
351  int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
353  dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
354  << "] = GIM_CheckComplexPattern(MIs[" << InsnID
355  << "]->getOperand(" << OpIdx
356  << "), ComplexPredicateID=" << ComplexPredicateID
357  << ")\n");
358  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
359  // FIXME: Use std::invoke() when it's available.
360  ComplexRendererFns Renderer =
361  (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
362  State.MIs[InsnID]->getOperand(OpIdx));
363  if (Renderer.hasValue())
364  State.Renderers[RendererID] = Renderer.getValue();
365  else
366  if (handleReject() == RejectAndGiveUp)
367  return false;
368  break;
369  }
370 
371  case GIM_CheckConstantInt: {
372  int64_t InsnID = MatchTable[CurrentIdx++];
373  int64_t OpIdx = MatchTable[CurrentIdx++];
374  int64_t Value = MatchTable[CurrentIdx++];
376  dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
377  << InsnID << "]->getOperand(" << OpIdx
378  << "), Value=" << Value << ")\n");
379  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
380 
381  // isOperandImmEqual() will sign-extend to 64-bits, so should we.
382  LLT Ty = MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg());
383  Value = SignExtend64(Value, Ty.getSizeInBits());
384 
385  if (!isOperandImmEqual(State.MIs[InsnID]->getOperand(OpIdx), Value,
386  MRI)) {
387  if (handleReject() == RejectAndGiveUp)
388  return false;
389  }
390  break;
391  }
392 
393  case GIM_CheckLiteralInt: {
394  int64_t InsnID = MatchTable[CurrentIdx++];
395  int64_t OpIdx = MatchTable[CurrentIdx++];
396  int64_t Value = MatchTable[CurrentIdx++];
398  dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
399  << InsnID << "]->getOperand(" << OpIdx
400  << "), Value=" << Value << ")\n");
401  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
402  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
403  if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
404  if (handleReject() == RejectAndGiveUp)
405  return false;
406  }
407  break;
408  }
409 
410  case GIM_CheckIntrinsicID: {
411  int64_t InsnID = MatchTable[CurrentIdx++];
412  int64_t OpIdx = MatchTable[CurrentIdx++];
413  int64_t Value = MatchTable[CurrentIdx++];
415  dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
416  << InsnID << "]->getOperand(" << OpIdx
417  << "), Value=" << Value << ")\n");
418  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
419  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
420  if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
421  if (handleReject() == RejectAndGiveUp)
422  return false;
423  break;
424  }
425 
426  case GIM_CheckIsMBB: {
427  int64_t InsnID = MatchTable[CurrentIdx++];
428  int64_t OpIdx = MatchTable[CurrentIdx++];
430  dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
431  << "]->getOperand(" << OpIdx << "))\n");
432  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
433  if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
434  if (handleReject() == RejectAndGiveUp)
435  return false;
436  }
437  break;
438  }
439 
440  case GIM_CheckIsSafeToFold: {
441  int64_t InsnID = MatchTable[CurrentIdx++];
443  dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
444  << InsnID << "])\n");
445  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
446  if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
447  if (handleReject() == RejectAndGiveUp)
448  return false;
449  }
450  break;
451  }
452  case GIM_CheckIsSameOperand: {
453  int64_t InsnID = MatchTable[CurrentIdx++];
454  int64_t OpIdx = MatchTable[CurrentIdx++];
455  int64_t OtherInsnID = MatchTable[CurrentIdx++];
456  int64_t OtherOpIdx = MatchTable[CurrentIdx++];
458  dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
459  << InsnID << "][" << OpIdx << "], MIs["
460  << OtherInsnID << "][" << OtherOpIdx << "])\n");
461  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
462  assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
463  if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
464  State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
465  if (handleReject() == RejectAndGiveUp)
466  return false;
467  }
468  break;
469  }
470  case GIM_Reject:
472  dbgs() << CurrentIdx << ": GIM_Reject");
473  if (handleReject() == RejectAndGiveUp)
474  return false;
475  break;
476 
477  case GIR_MutateOpcode: {
478  int64_t OldInsnID = MatchTable[CurrentIdx++];
479  uint64_t NewInsnID = MatchTable[CurrentIdx++];
480  int64_t NewOpcode = MatchTable[CurrentIdx++];
481  if (NewInsnID >= OutMIs.size())
482  OutMIs.resize(NewInsnID + 1);
483 
484  OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
485  State.MIs[OldInsnID]);
486  OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
488  dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
489  << NewInsnID << "], MIs[" << OldInsnID << "], "
490  << NewOpcode << ")\n");
491  break;
492  }
493 
494  case GIR_BuildMI: {
495  uint64_t NewInsnID = MatchTable[CurrentIdx++];
496  int64_t Opcode = MatchTable[CurrentIdx++];
497  if (NewInsnID >= OutMIs.size())
498  OutMIs.resize(NewInsnID + 1);
499 
500  OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
501  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
503  dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
504  << NewInsnID << "], " << Opcode << ")\n");
505  break;
506  }
507 
508  case GIR_Copy: {
509  int64_t NewInsnID = MatchTable[CurrentIdx++];
510  int64_t OldInsnID = MatchTable[CurrentIdx++];
511  int64_t OpIdx = MatchTable[CurrentIdx++];
512  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
513  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
515  dbgs()
516  << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
517  << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
518  break;
519  }
520 
521  case GIR_CopyOrAddZeroReg: {
522  int64_t NewInsnID = MatchTable[CurrentIdx++];
523  int64_t OldInsnID = MatchTable[CurrentIdx++];
524  int64_t OpIdx = MatchTable[CurrentIdx++];
525  int64_t ZeroReg = MatchTable[CurrentIdx++];
526  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
527  MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
528  if (isOperandImmEqual(MO, 0, MRI))
529  OutMIs[NewInsnID].addReg(ZeroReg);
530  else
531  OutMIs[NewInsnID].add(MO);
533  dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
534  << NewInsnID << "], MIs[" << OldInsnID << "], "
535  << OpIdx << ", " << ZeroReg << ")\n");
536  break;
537  }
538 
539  case GIR_CopySubReg: {
540  int64_t NewInsnID = MatchTable[CurrentIdx++];
541  int64_t OldInsnID = MatchTable[CurrentIdx++];
542  int64_t OpIdx = MatchTable[CurrentIdx++];
543  int64_t SubRegIdx = MatchTable[CurrentIdx++];
544  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
545  OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
546  0, SubRegIdx);
548  dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
549  << NewInsnID << "], MIs[" << OldInsnID << "], "
550  << OpIdx << ", " << SubRegIdx << ")\n");
551  break;
552  }
553 
554  case GIR_AddImplicitDef: {
555  int64_t InsnID = MatchTable[CurrentIdx++];
556  int64_t RegNum = MatchTable[CurrentIdx++];
557  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
558  OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
560  dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
561  << InsnID << "], " << RegNum << ")\n");
562  break;
563  }
564 
565  case GIR_AddImplicitUse: {
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].addUse(RegNum, RegState::Implicit);
571  dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
572  << InsnID << "], " << RegNum << ")\n");
573  break;
574  }
575 
576  case GIR_AddRegister: {
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].addReg(RegNum);
582  dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
583  << InsnID << "], " << RegNum << ")\n");
584  break;
585  }
586 
587  case GIR_AddTempRegister: {
588  int64_t InsnID = MatchTable[CurrentIdx++];
589  int64_t TempRegID = MatchTable[CurrentIdx++];
590  uint64_t TempRegFlags = MatchTable[CurrentIdx++];
591  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
592  OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
594  dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
595  << InsnID << "], TempRegisters[" << TempRegID
596  << "], " << TempRegFlags << ")\n");
597  break;
598  }
599 
600  case GIR_AddImm: {
601  int64_t InsnID = MatchTable[CurrentIdx++];
602  int64_t Imm = MatchTable[CurrentIdx++];
603  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
604  OutMIs[InsnID].addImm(Imm);
606  dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
607  << "], " << Imm << ")\n");
608  break;
609  }
610 
611  case GIR_ComplexRenderer: {
612  int64_t InsnID = MatchTable[CurrentIdx++];
613  int64_t RendererID = MatchTable[CurrentIdx++];
614  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
615  for (const auto &RenderOpFn : State.Renderers[RendererID])
616  RenderOpFn(OutMIs[InsnID]);
618  dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
619  << InsnID << "], " << RendererID << ")\n");
620  break;
621  }
623  int64_t InsnID = MatchTable[CurrentIdx++];
624  int64_t RendererID = MatchTable[CurrentIdx++];
625  int64_t RenderOpID = MatchTable[CurrentIdx++];
626  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
627  State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
629  dbgs() << CurrentIdx
630  << ": GIR_ComplexSubOperandRenderer(OutMIs["
631  << InsnID << "], " << RendererID << ", "
632  << RenderOpID << ")\n");
633  break;
634  }
635 
636  case GIR_CopyConstantAsSImm: {
637  int64_t NewInsnID = MatchTable[CurrentIdx++];
638  int64_t OldInsnID = MatchTable[CurrentIdx++];
639  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
640  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
641  if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
642  OutMIs[NewInsnID].addImm(
643  State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
644  } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
645  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
646  else
647  llvm_unreachable("Expected Imm or CImm operand");
649  dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
650  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
651  break;
652  }
653 
654  case GIR_CustomRenderer: {
655  int64_t InsnID = MatchTable[CurrentIdx++];
656  int64_t OldInsnID = MatchTable[CurrentIdx++];
657  int64_t RendererFnID = MatchTable[CurrentIdx++];
658  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
660  dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
661  << InsnID << "], MIs[" << OldInsnID << "], "
662  << RendererFnID << ")\n");
663  (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
664  *State.MIs[OldInsnID]);
665  break;
666  }
667  case GIR_ConstrainOperandRC: {
668  int64_t InsnID = MatchTable[CurrentIdx++];
669  int64_t OpIdx = MatchTable[CurrentIdx++];
670  int64_t RCEnum = MatchTable[CurrentIdx++];
671  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
672  constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
673  *TRI.getRegClass(RCEnum), TII, TRI, RBI);
675  dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
676  << InsnID << "], " << OpIdx << ", " << RCEnum
677  << ")\n");
678  break;
679  }
680 
682  int64_t InsnID = MatchTable[CurrentIdx++];
683  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
684  constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
685  RBI);
687  dbgs() << CurrentIdx
688  << ": GIR_ConstrainSelectedInstOperands(OutMIs["
689  << InsnID << "])\n");
690  break;
691  }
692 
693  case GIR_MergeMemOperands: {
694  int64_t InsnID = MatchTable[CurrentIdx++];
695  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
696 
698  dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
699  << InsnID << "]");
700  int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
701  while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
704  dbgs() << ", MIs[" << MergeInsnID << "]");
705  for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
706  OutMIs[InsnID].addMemOperand(MMO);
707  }
709  break;
710  }
711 
712  case GIR_EraseFromParent: {
713  int64_t InsnID = MatchTable[CurrentIdx++];
714  assert(State.MIs[InsnID] &&
715  "Attempted to erase an undefined instruction");
716  State.MIs[InsnID]->eraseFromParent();
718  dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
719  << InsnID << "])\n");
720  break;
721  }
722 
723  case GIR_MakeTempReg: {
724  int64_t TempRegID = MatchTable[CurrentIdx++];
725  int64_t TypeID = MatchTable[CurrentIdx++];
726 
727  State.TempRegisters[TempRegID] =
728  MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
730  dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
731  << "] = GIR_MakeTempReg(" << TypeID << ")\n");
732  break;
733  }
734 
735  case GIR_Coverage: {
736  int64_t RuleID = MatchTable[CurrentIdx++];
737  CoverageInfo.setCovered(RuleID);
738 
740  dbgs()
741  << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
742  break;
743  }
744 
745  case GIR_Done:
747  dbgs() << CurrentIdx << ": GIR_Done");
748  return true;
749 
750  default:
751  llvm_unreachable("Unexpected command");
752  }
753  }
754 }
755 
756 } // end namespace llvm
757 
758 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
Add an implicit register use to the specified instruction.
Add a a temporary register to the specified instruction.
Add an implicit register def to the specified instruction.
Render operands to the specified instruction using a custom function.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Render complex operands to the specified instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
std::vector< ComplexRendererFns::value_type > Renderers
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 instruction has the right number of operands.
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:344
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
Check an immediate predicate on the specified instruction.
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
Check the operand is a specific intrinsic ID.
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
const ComplexMatcherMemFn * ComplexPredicates
Check a floating point immediate predicate on the specified instruction.
Check the specified operands are identical.
Check the type for the specified operand.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
#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.
Check the type of a pointer to any address space.
Copy an operand to the specified instruction.
Check the feature bits.
const HexagonInstrInfo * TII
bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice, which is based on C++&#39;s definition.
static StringRef getName(Value *V)
Merge all memory operands into instruction.
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
DenseMap< unsigned, unsigned > TempRegisters
Render a G_CONSTANT operator as a sign-extended immediate.
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 ...
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
Create a new temporary register that&#39;s not constrained.
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:181
Check the opcode on the specified instruction.
Render sub-operands of complex operands 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.
bool isAtLeastOrStrongerThan(AtomicOrdering ao, AtomicOrdering other)
Check the operand matches a complex predicate.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Record the specified instruction.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Type::TypeID TypeID
Check an immediate predicate on the specified instruction via an APInt.
bool executeMatchTable(TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, const ISelInfoTy< PredicateBitset, ComplexMatcherMemFn, CustomRendererFn > &ISelInfo, const int64_t *MatchTable, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, CodeGenCoverage &CoverageInfo) const
Execute a given matcher table and return true if the match was successful and false otherwise...
void setCovered(uint64_t RuleID)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Constrain an instruction operand to a register class.
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: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.
Increment the rule coverage counter.
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:59
Check the specified operand is an MBB.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Mutate an instruction.
Class for arbitrary precision integers.
Definition: APInt.h:69
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
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:185
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
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
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 operand is a specific integer.
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
Add an immediate to the specified instruction.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Add an register to the specified instruction.
Fail the current try-block, or completely fail to match if there is no current try-block.
Check the register bank for the specified operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Check the operand is a specific literal integer (i.e.
Copy an operand to the specified instruction.
Build a new instruction.
LLVM Value Representation.
Definition: Value.h:73
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
Constrain an instructions operands according to the instruction description.
A successful emission.
const ConstantInt * getCImm() const
Check a memory operation has the specified atomic ordering.
Check if the specified operand is safe to fold into the current 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:353