LLVM  6.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"
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 {
43 };
44 
45 template <class TgtInstructionSelector, class PredicateBitset,
46  class ComplexMatcherMemFn>
48  TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
50  const int64_t *MatchTable, const TargetInstrInfo &TII,
52  const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
53  CodeGenCoverage &CoverageInfo) const {
54  uint64_t CurrentIdx = 0;
55  SmallVector<uint64_t, 8> OnFailResumeAt;
56 
57  enum RejectAction { RejectAndGiveUp, RejectAndResume };
58  auto handleReject = [&]() -> RejectAction {
60  dbgs() << CurrentIdx << ": Rejected\n");
61  if (OnFailResumeAt.empty())
62  return RejectAndGiveUp;
63  CurrentIdx = OnFailResumeAt.back();
64  OnFailResumeAt.pop_back();
66  dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
67  << OnFailResumeAt.size() << " try-blocks remain)\n");
68  return RejectAndResume;
69  };
70 
71  while (true) {
72  assert(CurrentIdx != ~0u && "Invalid MatchTable index");
73  switch (MatchTable[CurrentIdx++]) {
74  case GIM_Try: {
76  dbgs() << CurrentIdx << ": Begin try-block\n");
77  OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
78  break;
79  }
80 
81  case GIM_RecordInsn: {
82  int64_t NewInsnID = MatchTable[CurrentIdx++];
83  int64_t InsnID = MatchTable[CurrentIdx++];
84  int64_t OpIdx = MatchTable[CurrentIdx++];
85 
86  // As an optimisation we require that MIs[0] is always the root. Refuse
87  // any attempt to modify it.
88  assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
89 
90  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
91  if (!MO.isReg()) {
93  dbgs() << CurrentIdx << ": Not a register\n");
94  if (handleReject() == RejectAndGiveUp)
95  return false;
96  break;
97  }
98  if (TRI.isPhysicalRegister(MO.getReg())) {
100  dbgs() << CurrentIdx << ": Is a physical register\n");
101  if (handleReject() == RejectAndGiveUp)
102  return false;
103  break;
104  }
105 
106  MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
107  if ((size_t)NewInsnID < State.MIs.size())
108  State.MIs[NewInsnID] = NewMI;
109  else {
110  assert((size_t)NewInsnID == State.MIs.size() &&
111  "Expected to store MIs in order");
112  State.MIs.push_back(NewMI);
113  }
115  dbgs() << CurrentIdx << ": MIs[" << NewInsnID
116  << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
117  << ")\n");
118  break;
119  }
120 
121  case GIM_CheckFeatures: {
122  int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
124  dbgs() << CurrentIdx
125  << ": GIM_CheckFeatures(ExpectedBitsetID="
126  << ExpectedBitsetID << ")\n");
127  if ((AvailableFeatures & MatcherInfo.FeatureBitsets[ExpectedBitsetID]) !=
128  MatcherInfo.FeatureBitsets[ExpectedBitsetID]) {
129  if (handleReject() == RejectAndGiveUp)
130  return false;
131  }
132  break;
133  }
134 
135  case GIM_CheckOpcode: {
136  int64_t InsnID = MatchTable[CurrentIdx++];
137  int64_t Expected = MatchTable[CurrentIdx++];
138 
139  unsigned Opcode = State.MIs[InsnID]->getOpcode();
141  dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
142  << "], ExpectedOpcode=" << Expected
143  << ") // Got=" << Opcode << "\n");
144  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
145  if (Opcode != Expected) {
146  if (handleReject() == RejectAndGiveUp)
147  return false;
148  }
149  break;
150  }
151 
152  case GIM_CheckNumOperands: {
153  int64_t InsnID = MatchTable[CurrentIdx++];
154  int64_t Expected = MatchTable[CurrentIdx++];
156  dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
157  << InsnID << "], Expected=" << Expected << ")\n");
158  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
159  if (State.MIs[InsnID]->getNumOperands() != Expected) {
160  if (handleReject() == RejectAndGiveUp)
161  return false;
162  }
163  break;
164  }
166  int64_t InsnID = MatchTable[CurrentIdx++];
167  int64_t Predicate = MatchTable[CurrentIdx++];
169  dbgs()
170  << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
171  << InsnID << "], Predicate=" << Predicate << ")\n");
172  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
173  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
174  "Expected G_CONSTANT");
175  assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
176  int64_t Value = 0;
177  if (State.MIs[InsnID]->getOperand(1).isCImm())
178  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
179  else if (State.MIs[InsnID]->getOperand(1).isImm())
180  Value = State.MIs[InsnID]->getOperand(1).getImm();
181  else
182  llvm_unreachable("Expected Imm or CImm operand");
183 
184  if (!MatcherInfo.I64ImmPredicateFns[Predicate](Value))
185  if (handleReject() == RejectAndGiveUp)
186  return false;
187  break;
188  }
190  int64_t InsnID = MatchTable[CurrentIdx++];
191  int64_t Predicate = MatchTable[CurrentIdx++];
193  dbgs()
194  << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
195  << InsnID << "], Predicate=" << Predicate << ")\n");
196  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
197  assert(State.MIs[InsnID]->getOpcode() && "Expected G_CONSTANT");
198  assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
199  APInt Value;
200  if (State.MIs[InsnID]->getOperand(1).isCImm())
201  Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
202  else
203  llvm_unreachable("Expected Imm or CImm operand");
204 
205  if (!MatcherInfo.APIntImmPredicateFns[Predicate](Value))
206  if (handleReject() == RejectAndGiveUp)
207  return false;
208  break;
209  }
211  int64_t InsnID = MatchTable[CurrentIdx++];
212  int64_t Predicate = MatchTable[CurrentIdx++];
214  dbgs()
215  << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
216  << InsnID << "], Predicate=" << Predicate << ")\n");
217  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
218  assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
219  "Expected G_FCONSTANT");
220  assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
221  assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
222  APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
223 
224  if (!MatcherInfo.APFloatImmPredicateFns[Predicate](Value))
225  if (handleReject() == RejectAndGiveUp)
226  return false;
227  break;
228  }
229  case GIM_CheckNonAtomic: {
230  int64_t InsnID = MatchTable[CurrentIdx++];
232  dbgs() << CurrentIdx << ": GIM_CheckNonAtomic(MIs["
233  << InsnID << "])\n");
234  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
235  assert((State.MIs[InsnID]->getOpcode() == TargetOpcode::G_LOAD ||
236  State.MIs[InsnID]->getOpcode() == TargetOpcode::G_STORE) &&
237  "Expected G_LOAD/G_STORE");
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() != AtomicOrdering::NotAtomic)
245  if (handleReject() == RejectAndGiveUp)
246  return false;
247  break;
248  }
249 
250  case GIM_CheckType: {
251  int64_t InsnID = MatchTable[CurrentIdx++];
252  int64_t OpIdx = MatchTable[CurrentIdx++];
253  int64_t TypeID = MatchTable[CurrentIdx++];
255  dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
256  << "]->getOperand(" << OpIdx
257  << "), TypeID=" << TypeID << ")\n");
258  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
259  if (MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg()) !=
260  MatcherInfo.TypeObjects[TypeID]) {
261  if (handleReject() == RejectAndGiveUp)
262  return false;
263  }
264  break;
265  }
266  case GIM_CheckPointerToAny: {
267  int64_t InsnID = MatchTable[CurrentIdx++];
268  int64_t OpIdx = MatchTable[CurrentIdx++];
269  int64_t SizeInBits = MatchTable[CurrentIdx++];
270 
272  dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
273  << InsnID << "]->getOperand(" << OpIdx
274  << "), SizeInBits=" << SizeInBits << ")\n");
275  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
276 
277  // iPTR must be looked up in the target.
278  if (SizeInBits == 0) {
279  MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
280  SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
281  }
282 
283  assert(SizeInBits != 0 && "Pointer size must be known");
284 
285  const LLT &Ty = MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg());
286  if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) {
287  if (handleReject() == RejectAndGiveUp)
288  return false;
289  }
290  break;
291  }
293  int64_t InsnID = MatchTable[CurrentIdx++];
294  int64_t OpIdx = MatchTable[CurrentIdx++];
295  int64_t RCEnum = MatchTable[CurrentIdx++];
297  dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
298  << InsnID << "]->getOperand(" << OpIdx
299  << "), RCEnum=" << RCEnum << ")\n");
300  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
301  if (&RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
302  RBI.getRegBank(State.MIs[InsnID]->getOperand(OpIdx).getReg(), MRI,
303  TRI)) {
304  if (handleReject() == RejectAndGiveUp)
305  return false;
306  }
307  break;
308  }
309 
311  int64_t InsnID = MatchTable[CurrentIdx++];
312  int64_t OpIdx = MatchTable[CurrentIdx++];
313  int64_t RendererID = MatchTable[CurrentIdx++];
314  int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
316  dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
317  << "] = GIM_CheckComplexPattern(MIs[" << InsnID
318  << "]->getOperand(" << OpIdx
319  << "), ComplexPredicateID=" << ComplexPredicateID
320  << ")\n");
321  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
322  // FIXME: Use std::invoke() when it's available.
323  ComplexRendererFns Renderer =
324  (ISel.*MatcherInfo.ComplexPredicates[ComplexPredicateID])(
325  State.MIs[InsnID]->getOperand(OpIdx));
326  if (Renderer.hasValue())
327  State.Renderers[RendererID] = Renderer.getValue();
328  else
329  if (handleReject() == RejectAndGiveUp)
330  return false;
331  break;
332  }
333 
334  case GIM_CheckConstantInt: {
335  int64_t InsnID = MatchTable[CurrentIdx++];
336  int64_t OpIdx = MatchTable[CurrentIdx++];
337  int64_t Value = MatchTable[CurrentIdx++];
339  dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
340  << InsnID << "]->getOperand(" << OpIdx
341  << "), Value=" << Value << ")\n");
342  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
343  if (!isOperandImmEqual(State.MIs[InsnID]->getOperand(OpIdx), Value,
344  MRI)) {
345  if (handleReject() == RejectAndGiveUp)
346  return false;
347  }
348  break;
349  }
350 
351  case GIM_CheckLiteralInt: {
352  int64_t InsnID = MatchTable[CurrentIdx++];
353  int64_t OpIdx = MatchTable[CurrentIdx++];
354  int64_t Value = MatchTable[CurrentIdx++];
356  dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
357  << InsnID << "]->getOperand(" << OpIdx
358  << "), Value=" << Value << ")\n");
359  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
360  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
361  if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
362  if (handleReject() == RejectAndGiveUp)
363  return false;
364  }
365  break;
366  }
367 
368  case GIM_CheckIntrinsicID: {
369  int64_t InsnID = MatchTable[CurrentIdx++];
370  int64_t OpIdx = MatchTable[CurrentIdx++];
371  int64_t Value = MatchTable[CurrentIdx++];
373  dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
374  << InsnID << "]->getOperand(" << OpIdx
375  << "), Value=" << Value << ")\n");
376  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
377  MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
378  if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
379  if (handleReject() == RejectAndGiveUp)
380  return false;
381  break;
382  }
383 
384  case GIM_CheckIsMBB: {
385  int64_t InsnID = MatchTable[CurrentIdx++];
386  int64_t OpIdx = MatchTable[CurrentIdx++];
388  dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
389  << "]->getOperand(" << OpIdx << "))\n");
390  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
391  if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
392  if (handleReject() == RejectAndGiveUp)
393  return false;
394  }
395  break;
396  }
397 
398  case GIM_CheckIsSafeToFold: {
399  int64_t InsnID = MatchTable[CurrentIdx++];
401  dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
402  << InsnID << "])\n");
403  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
404  if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
405  if (handleReject() == RejectAndGiveUp)
406  return false;
407  }
408  break;
409  }
410  case GIM_CheckIsSameOperand: {
411  int64_t InsnID = MatchTable[CurrentIdx++];
412  int64_t OpIdx = MatchTable[CurrentIdx++];
413  int64_t OtherInsnID = MatchTable[CurrentIdx++];
414  int64_t OtherOpIdx = MatchTable[CurrentIdx++];
416  dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
417  << InsnID << "][" << OpIdx << "], MIs["
418  << OtherInsnID << "][" << OtherOpIdx << "])\n");
419  assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
420  assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
421  if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
422  State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
423  if (handleReject() == RejectAndGiveUp)
424  return false;
425  }
426  break;
427  }
428  case GIM_Reject:
430  dbgs() << CurrentIdx << ": GIM_Reject");
431  if (handleReject() == RejectAndGiveUp)
432  return false;
433  break;
434 
435  case GIR_MutateOpcode: {
436  int64_t OldInsnID = MatchTable[CurrentIdx++];
437  uint64_t NewInsnID = MatchTable[CurrentIdx++];
438  int64_t NewOpcode = MatchTable[CurrentIdx++];
439  if (NewInsnID >= OutMIs.size())
440  OutMIs.resize(NewInsnID + 1);
441 
442  OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
443  State.MIs[OldInsnID]);
444  OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
446  dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
447  << NewInsnID << "], MIs[" << OldInsnID << "], "
448  << NewOpcode << ")\n");
449  break;
450  }
451 
452  case GIR_BuildMI: {
453  uint64_t NewInsnID = MatchTable[CurrentIdx++];
454  int64_t Opcode = MatchTable[CurrentIdx++];
455  if (NewInsnID >= OutMIs.size())
456  OutMIs.resize(NewInsnID + 1);
457 
458  OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
459  State.MIs[0]->getDebugLoc(), TII.get(Opcode));
461  dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
462  << NewInsnID << "], " << Opcode << ")\n");
463  break;
464  }
465 
466  case GIR_Copy: {
467  int64_t NewInsnID = MatchTable[CurrentIdx++];
468  int64_t OldInsnID = MatchTable[CurrentIdx++];
469  int64_t OpIdx = MatchTable[CurrentIdx++];
470  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
471  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
473  dbgs()
474  << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
475  << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
476  break;
477  }
478 
479  case GIR_CopyOrAddZeroReg: {
480  int64_t NewInsnID = MatchTable[CurrentIdx++];
481  int64_t OldInsnID = MatchTable[CurrentIdx++];
482  int64_t OpIdx = MatchTable[CurrentIdx++];
483  int64_t ZeroReg = MatchTable[CurrentIdx++];
484  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
485  MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
486  if (isOperandImmEqual(MO, 0, MRI))
487  OutMIs[NewInsnID].addReg(ZeroReg);
488  else
489  OutMIs[NewInsnID].add(MO);
491  dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
492  << NewInsnID << "], MIs[" << OldInsnID << "], "
493  << OpIdx << ", " << ZeroReg << ")\n");
494  break;
495  }
496 
497  case GIR_CopySubReg: {
498  int64_t NewInsnID = MatchTable[CurrentIdx++];
499  int64_t OldInsnID = MatchTable[CurrentIdx++];
500  int64_t OpIdx = MatchTable[CurrentIdx++];
501  int64_t SubRegIdx = MatchTable[CurrentIdx++];
502  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
503  OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
504  0, SubRegIdx);
506  dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
507  << NewInsnID << "], MIs[" << OldInsnID << "], "
508  << OpIdx << ", " << SubRegIdx << ")\n");
509  break;
510  }
511 
512  case GIR_AddImplicitDef: {
513  int64_t InsnID = MatchTable[CurrentIdx++];
514  int64_t RegNum = MatchTable[CurrentIdx++];
515  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
516  OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
518  dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
519  << InsnID << "], " << RegNum << ")\n");
520  break;
521  }
522 
523  case GIR_AddImplicitUse: {
524  int64_t InsnID = MatchTable[CurrentIdx++];
525  int64_t RegNum = MatchTable[CurrentIdx++];
526  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
527  OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
529  dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
530  << InsnID << "], " << RegNum << ")\n");
531  break;
532  }
533 
534  case GIR_AddRegister: {
535  int64_t InsnID = MatchTable[CurrentIdx++];
536  int64_t RegNum = MatchTable[CurrentIdx++];
537  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
538  OutMIs[InsnID].addReg(RegNum);
540  dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
541  << InsnID << "], " << RegNum << ")\n");
542  break;
543  }
544 
545  case GIR_AddTempRegister: {
546  int64_t InsnID = MatchTable[CurrentIdx++];
547  int64_t TempRegID = MatchTable[CurrentIdx++];
548  uint64_t TempRegFlags = MatchTable[CurrentIdx++];
549  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
550  OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
552  dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
553  << InsnID << "], TempRegisters[" << TempRegID
554  << "], " << TempRegFlags << ")\n");
555  break;
556  }
557 
558  case GIR_AddImm: {
559  int64_t InsnID = MatchTable[CurrentIdx++];
560  int64_t Imm = MatchTable[CurrentIdx++];
561  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
562  OutMIs[InsnID].addImm(Imm);
564  dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
565  << "], " << Imm << ")\n");
566  break;
567  }
568 
569  case GIR_ComplexRenderer: {
570  int64_t InsnID = MatchTable[CurrentIdx++];
571  int64_t RendererID = MatchTable[CurrentIdx++];
572  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
573  for (const auto &RenderOpFn : State.Renderers[RendererID])
574  RenderOpFn(OutMIs[InsnID]);
576  dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
577  << InsnID << "], " << RendererID << ")\n");
578  break;
579  }
581  int64_t InsnID = MatchTable[CurrentIdx++];
582  int64_t RendererID = MatchTable[CurrentIdx++];
583  int64_t RenderOpID = MatchTable[CurrentIdx++];
584  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
585  State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
587  dbgs() << CurrentIdx
588  << ": GIR_ComplexSubOperandRenderer(OutMIs["
589  << InsnID << "], " << RendererID << ", "
590  << RenderOpID << ")\n");
591  break;
592  }
593 
594  case GIR_CopyConstantAsSImm: {
595  int64_t NewInsnID = MatchTable[CurrentIdx++];
596  int64_t OldInsnID = MatchTable[CurrentIdx++];
597  assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
598  assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
599  if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
600  OutMIs[NewInsnID].addImm(
601  State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
602  } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
603  OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
604  else
605  llvm_unreachable("Expected Imm or CImm operand");
607  dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
608  << NewInsnID << "], MIs[" << OldInsnID << "])\n");
609  break;
610  }
611 
612  case GIR_ConstrainOperandRC: {
613  int64_t InsnID = MatchTable[CurrentIdx++];
614  int64_t OpIdx = MatchTable[CurrentIdx++];
615  int64_t RCEnum = MatchTable[CurrentIdx++];
616  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
617  constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
618  *TRI.getRegClass(RCEnum), TII, TRI, RBI);
620  dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
621  << InsnID << "], " << OpIdx << ", " << RCEnum
622  << ")\n");
623  break;
624  }
625 
627  int64_t InsnID = MatchTable[CurrentIdx++];
628  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
629  constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
630  RBI);
632  dbgs() << CurrentIdx
633  << ": GIR_ConstrainSelectedInstOperands(OutMIs["
634  << InsnID << "])\n");
635  break;
636  }
637 
638  case GIR_MergeMemOperands: {
639  int64_t InsnID = MatchTable[CurrentIdx++];
640  assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
641 
643  dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
644  << InsnID << "]");
645  int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
646  while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
649  dbgs() << ", MIs[" << MergeInsnID << "]");
650  for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
651  OutMIs[InsnID].addMemOperand(MMO);
652  }
654  break;
655  }
656 
657  case GIR_EraseFromParent: {
658  int64_t InsnID = MatchTable[CurrentIdx++];
659  assert(State.MIs[InsnID] &&
660  "Attempted to erase an undefined instruction");
661  State.MIs[InsnID]->eraseFromParent();
663  dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
664  << InsnID << "])\n");
665  break;
666  }
667 
668  case GIR_MakeTempReg: {
669  int64_t TempRegID = MatchTable[CurrentIdx++];
670  int64_t TypeID = MatchTable[CurrentIdx++];
671 
672  State.TempRegisters[TempRegID] =
673  MRI.createGenericVirtualRegister(MatcherInfo.TypeObjects[TypeID]);
675  dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
676  << "] = GIR_MakeTempReg(" << TypeID << ")\n");
677  break;
678  }
679 
680  case GIR_Coverage: {
681  int64_t RuleID = MatchTable[CurrentIdx++];
682  CoverageInfo.setCovered(RuleID);
683 
685  dbgs()
686  << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
687  break;
688  }
689 
690  case GIR_Done:
692  dbgs() << CurrentIdx << ": GIR_Done");
693  return true;
694 
695  default:
696  llvm_unreachable("Unexpected command");
697  }
698  }
699 }
700 
701 } // end namespace llvm
702 
703 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
Check the type of a pointer to any address space.
Fail the current try-block, or completely fail to match if there is no current try-block.
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
Check if the specified operand is safe to fold into the current instruction.
bool executeMatchTable(TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, const MatcherInfoTy< PredicateBitset, ComplexMatcherMemFn > &MatcherInfo, 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...
std::vector< ComplexRendererFns::value_type > Renderers
Check the specified operands are identical.
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 the register bank for the specified operand.
Copy an operand to the specified instruction.
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
Constrain an instructions operands according to the instruction description.
Copy an operand to the specified instruction.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
Render complex operands to the specified instruction.
Render sub-operands of complex operands to the specified instruction.
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
bool isIntrinsicID() const
Holds all the information related to register banks.
const ComplexMatcherMemFn * ComplexPredicates
const HexagonInstrInfo * TII
Add an register to the specified instruction.
Record the specified instruction.
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
const APFloatImmediatePredicateFn * APFloatImmPredicateFns
DenseMap< unsigned, unsigned > TempRegisters
Check the operand is a specific integer.
Add an implicit register def to the specified instruction.
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:127
Merge all memory operands into instruction.
Check the opcode on the specified instruction.
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
const I64ImmediatePredicateFn * I64ImmPredicateFns
Check the feature bits.
Mutate an instruction.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
TargetInstrInfo - Interface to description of machine instruction set.
Add a a temporary register to the specified instruction.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Check the operand is a specific literal integer (i.e.
unsigned const MachineRegisterInfo * MRI
Check the specified operand is an MBB.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Check an immediate predicate on the specified instruction.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Type::TypeID TypeID
Constrain an instruction operand to a register class.
Increment the rule coverage counter.
void setCovered(uint64_t RuleID)
Add an immediate to the specified instruction.
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 a memory operation is non-atomic.
Add an implicit register use to the specified instruction.
Build a new instruction.
A successful emission.
Check an immediate predicate on the specified instruction via an APInt.
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:864
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.
Check the type for the specified operand.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Check a floating point immediate predicate on the specified instruction.
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
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.
const APIntImmediatePredicateFn * APIntImmPredicateFns
Check the operand is a specific intrinsic ID.
Representation of each machine instruction.
Definition: MachineInstr.h:59
bool hasValue() const
Definition: Optional.h:137
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Check the operand matches a complex predicate.
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...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
Create a new temporary register that&#39;s not constrained.
const ConstantInt * getCImm() const
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:355