16 #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H 17 #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H 47 template <
class TgtInstructionSelector,
class PredicateBitset,
48 class ComplexMatcherMemFn,
class CustomRendererFn>
58 uint64_t CurrentIdx = 0;
61 enum RejectAction { RejectAndGiveUp, RejectAndResume };
62 auto handleReject = [&]() -> RejectAction {
64 dbgs() << CurrentIdx <<
": Rejected\n");
65 if (OnFailResumeAt.
empty())
66 return RejectAndGiveUp;
69 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" (" 70 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
71 return RejectAndResume;
75 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
76 int64_t MatcherOpcode = MatchTable[CurrentIdx++];
77 switch (MatcherOpcode) {
80 dbgs() << CurrentIdx <<
": Begin try-block\n");
81 OnFailResumeAt.
push_back(MatchTable[CurrentIdx++]);
86 int64_t NewInsnID = MatchTable[CurrentIdx++];
87 int64_t InsnID = MatchTable[CurrentIdx++];
88 int64_t OpIdx = MatchTable[CurrentIdx++];
92 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
97 dbgs() << CurrentIdx <<
": Not a register\n");
98 if (handleReject() == RejectAndGiveUp)
104 dbgs() << CurrentIdx <<
": Is a physical register\n");
105 if (handleReject() == RejectAndGiveUp)
111 if ((
size_t)NewInsnID < State.
MIs.
size())
112 State.
MIs[NewInsnID] = NewMI;
115 "Expected to store MIs in order");
119 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
120 <<
"] = GIM_RecordInsn(" << InsnID <<
", " << OpIdx
126 int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
129 <<
": GIM_CheckFeatures(ExpectedBitsetID=" 130 << ExpectedBitsetID <<
")\n");
131 if ((AvailableFeatures & ISelInfo.
FeatureBitsets[ExpectedBitsetID]) !=
133 if (handleReject() == RejectAndGiveUp)
140 int64_t InsnID = MatchTable[CurrentIdx++];
141 int64_t
Expected = MatchTable[CurrentIdx++];
143 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
144 unsigned Opcode = State.
MIs[InsnID]->getOpcode();
147 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
148 <<
"], ExpectedOpcode=" << Expected
149 <<
") // Got=" << Opcode <<
"\n");
150 if (Opcode != Expected) {
151 if (handleReject() == RejectAndGiveUp)
158 int64_t InsnID = MatchTable[CurrentIdx++];
159 int64_t LowerBound = MatchTable[CurrentIdx++];
160 int64_t UpperBound = MatchTable[CurrentIdx++];
161 int64_t
Default = MatchTable[CurrentIdx++];
163 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
164 const int64_t Opcode = State.
MIs[InsnID]->getOpcode();
167 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], [" 168 << LowerBound <<
", " << UpperBound <<
"), Default=" << Default
169 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
171 if (Opcode < LowerBound || UpperBound <= Opcode) {
175 CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
185 int64_t InsnID = MatchTable[CurrentIdx++];
186 int64_t OpIdx = MatchTable[CurrentIdx++];
187 int64_t LowerBound = MatchTable[CurrentIdx++];
188 int64_t UpperBound = MatchTable[CurrentIdx++];
189 int64_t
Default = MatchTable[CurrentIdx++];
191 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
195 dbgs() << CurrentIdx <<
": GIM_SwitchType(MIs[" << InsnID
196 <<
"]->getOperand(" << OpIdx <<
"), [" << LowerBound <<
", " 197 << UpperBound <<
"), Default=" << Default
198 <<
", JumpTable...) // Got=";
200 dbgs() <<
"Not a VReg\n";
209 const auto TyI = ISelInfo.
TypeIDMap.find(Ty);
214 const int64_t
TypeID = TyI->second;
215 if (TypeID < LowerBound || UpperBound <= TypeID) {
219 CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
229 int64_t InsnID = MatchTable[CurrentIdx++];
230 int64_t
Expected = MatchTable[CurrentIdx++];
232 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs[" 233 << InsnID <<
"], Expected=" << Expected <<
")\n");
234 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
235 if (State.
MIs[InsnID]->getNumOperands() != Expected) {
236 if (handleReject() == RejectAndGiveUp)
242 int64_t InsnID = MatchTable[CurrentIdx++];
243 int64_t
Predicate = MatchTable[CurrentIdx++];
246 << CurrentIdx <<
": GIM_CheckI64ImmPredicate(MIs[" 247 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
248 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
249 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
250 "Expected G_CONSTANT");
253 if (State.
MIs[InsnID]->getOperand(1).isCImm())
254 Value = State.
MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
255 else if (State.
MIs[InsnID]->getOperand(1).isImm())
256 Value = State.
MIs[InsnID]->getOperand(1).getImm();
261 if (handleReject() == RejectAndGiveUp)
266 int64_t InsnID = MatchTable[CurrentIdx++];
267 int64_t
Predicate = MatchTable[CurrentIdx++];
270 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs[" 271 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
272 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
273 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
274 "Expected G_CONSTANT");
277 if (State.
MIs[InsnID]->getOperand(1).isCImm())
278 Value = State.
MIs[InsnID]->getOperand(1).getCImm()->getValue();
283 if (handleReject() == RejectAndGiveUp)
288 int64_t InsnID = MatchTable[CurrentIdx++];
289 int64_t
Predicate = MatchTable[CurrentIdx++];
292 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs[" 293 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
294 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
295 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
296 "Expected G_FCONSTANT");
297 assert(State.
MIs[InsnID]->getOperand(1).isFPImm() &&
"Expected FPImm operand");
299 APFloat Value = State.
MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
302 if (handleReject() == RejectAndGiveUp)
307 int64_t InsnID = MatchTable[CurrentIdx++];
308 int64_t
Predicate = MatchTable[CurrentIdx++];
311 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs[" 312 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
313 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
317 if (handleReject() == RejectAndGiveUp)
322 int64_t InsnID = MatchTable[CurrentIdx++];
325 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs[" 326 << InsnID <<
"], " << (uint64_t)Ordering <<
")\n");
327 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
328 if (!State.
MIs[InsnID]->hasOneMemOperand())
329 if (handleReject() == RejectAndGiveUp)
332 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
333 if (MMO->getOrdering() != Ordering)
334 if (handleReject() == RejectAndGiveUp)
339 int64_t InsnID = MatchTable[CurrentIdx++];
343 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs[" 344 << InsnID <<
"], " << (uint64_t)Ordering <<
")\n");
345 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
346 if (!State.
MIs[InsnID]->hasOneMemOperand())
347 if (handleReject() == RejectAndGiveUp)
350 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
352 if (handleReject() == RejectAndGiveUp)
357 int64_t InsnID = MatchTable[CurrentIdx++];
361 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs[" 362 << InsnID <<
"], " << (uint64_t)Ordering <<
")\n");
363 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
364 if (!State.
MIs[InsnID]->hasOneMemOperand())
365 if (handleReject() == RejectAndGiveUp)
368 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
370 if (handleReject() == RejectAndGiveUp)
375 int64_t InsnID = MatchTable[CurrentIdx++];
376 int64_t MMOIdx = MatchTable[CurrentIdx++];
377 uint64_t
Size = MatchTable[CurrentIdx++];
381 <<
": GIM_CheckMemorySizeEqual(MIs[" << InsnID
382 <<
"]->memoperands() + " << MMOIdx
383 <<
", Size=" << Size <<
")\n");
384 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
386 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
387 if (handleReject() == RejectAndGiveUp)
398 if (handleReject() == RejectAndGiveUp)
406 int64_t InsnID = MatchTable[CurrentIdx++];
407 int64_t MMOIdx = MatchTable[CurrentIdx++];
408 int64_t OpIdx = MatchTable[CurrentIdx++];
412 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize" 418 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
419 <<
", OpIdx=" << OpIdx <<
")\n");
420 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
425 dbgs() << CurrentIdx <<
": Not a register\n");
426 if (handleReject() == RejectAndGiveUp)
431 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
432 if (handleReject() == RejectAndGiveUp)
442 if (handleReject() == RejectAndGiveUp)
446 if (handleReject() == RejectAndGiveUp)
450 if (handleReject() == RejectAndGiveUp)
456 int64_t InsnID = MatchTable[CurrentIdx++];
457 int64_t OpIdx = MatchTable[CurrentIdx++];
458 int64_t
TypeID = MatchTable[CurrentIdx++];
460 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
461 <<
"]->getOperand(" << OpIdx
462 <<
"), TypeID=" << TypeID <<
")\n");
463 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
467 if (handleReject() == RejectAndGiveUp)
473 int64_t InsnID = MatchTable[CurrentIdx++];
474 int64_t OpIdx = MatchTable[CurrentIdx++];
475 int64_t SizeInBits = MatchTable[CurrentIdx++];
478 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs[" 479 << InsnID <<
"]->getOperand(" << OpIdx
480 <<
"), SizeInBits=" << SizeInBits <<
")\n");
481 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
483 if (SizeInBits == 0) {
488 assert(SizeInBits != 0 &&
"Pointer size must be known");
494 if (handleReject() == RejectAndGiveUp)
496 }
else if (handleReject() == RejectAndGiveUp)
502 int64_t InsnID = MatchTable[CurrentIdx++];
503 int64_t OpIdx = MatchTable[CurrentIdx++];
504 int64_t RCEnum = MatchTable[CurrentIdx++];
506 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs[" 507 << InsnID <<
"]->getOperand(" << OpIdx
508 <<
"), RCEnum=" << RCEnum <<
")\n");
509 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
514 if (handleReject() == RejectAndGiveUp)
521 int64_t InsnID = MatchTable[CurrentIdx++];
522 int64_t OpIdx = MatchTable[CurrentIdx++];
523 int64_t RendererID = MatchTable[CurrentIdx++];
524 int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
526 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
527 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
528 <<
"]->getOperand(" << OpIdx
529 <<
"), ComplexPredicateID=" << ComplexPredicateID
531 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
535 State.
MIs[InsnID]->getOperand(OpIdx));
539 if (handleReject() == RejectAndGiveUp)
545 int64_t InsnID = MatchTable[CurrentIdx++];
546 int64_t OpIdx = MatchTable[CurrentIdx++];
547 int64_t
Value = MatchTable[CurrentIdx++];
549 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs[" 550 << InsnID <<
"]->getOperand(" << OpIdx
551 <<
"), Value=" << Value <<
")\n");
552 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
560 if (handleReject() == RejectAndGiveUp)
563 }
else if (handleReject() == RejectAndGiveUp)
570 int64_t InsnID = MatchTable[CurrentIdx++];
571 int64_t OpIdx = MatchTable[CurrentIdx++];
572 int64_t
Value = MatchTable[CurrentIdx++];
574 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs[" 575 << InsnID <<
"]->getOperand(" << OpIdx
576 <<
"), Value=" << Value <<
")\n");
577 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
580 if (handleReject() == RejectAndGiveUp)
587 int64_t InsnID = MatchTable[CurrentIdx++];
588 int64_t OpIdx = MatchTable[CurrentIdx++];
589 int64_t
Value = MatchTable[CurrentIdx++];
591 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs[" 592 << InsnID <<
"]->getOperand(" << OpIdx
593 <<
"), Value=" << Value <<
")\n");
594 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
597 if (handleReject() == RejectAndGiveUp)
603 int64_t InsnID = MatchTable[CurrentIdx++];
604 int64_t OpIdx = MatchTable[CurrentIdx++];
606 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
607 <<
"]->getOperand(" << OpIdx <<
"))\n");
608 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
609 if (!State.
MIs[InsnID]->getOperand(OpIdx).isMBB()) {
610 if (handleReject() == RejectAndGiveUp)
617 int64_t InsnID = MatchTable[CurrentIdx++];
619 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(MIs[" 620 << InsnID <<
"])\n");
621 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
623 if (handleReject() == RejectAndGiveUp)
629 int64_t InsnID = MatchTable[CurrentIdx++];
630 int64_t OpIdx = MatchTable[CurrentIdx++];
631 int64_t OtherInsnID = MatchTable[CurrentIdx++];
632 int64_t OtherOpIdx = MatchTable[CurrentIdx++];
634 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs[" 635 << InsnID <<
"][" << OpIdx <<
"], MIs[" 636 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
637 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
638 assert(State.
MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
639 if (!State.
MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
640 State.
MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
641 if (handleReject() == RejectAndGiveUp)
648 dbgs() << CurrentIdx <<
": GIM_Reject\n");
649 if (handleReject() == RejectAndGiveUp)
654 int64_t OldInsnID = MatchTable[CurrentIdx++];
655 uint64_t NewInsnID = MatchTable[CurrentIdx++];
656 int64_t NewOpcode = MatchTable[CurrentIdx++];
657 if (NewInsnID >= OutMIs.
size())
658 OutMIs.
resize(NewInsnID + 1);
661 State.
MIs[OldInsnID]);
662 OutMIs[NewInsnID]->setDesc(TII.
get(NewOpcode));
664 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs[" 665 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], " 666 << NewOpcode <<
")\n");
671 uint64_t NewInsnID = MatchTable[CurrentIdx++];
672 int64_t Opcode = MatchTable[CurrentIdx++];
673 if (NewInsnID >= OutMIs.
size())
674 OutMIs.
resize(NewInsnID + 1);
676 OutMIs[NewInsnID] =
BuildMI(*State.
MIs[0]->getParent(), State.
MIs[0],
677 State.
MIs[0]->getDebugLoc(), TII.
get(Opcode));
679 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs[" 680 << NewInsnID <<
"], " << Opcode <<
")\n");
685 int64_t NewInsnID = MatchTable[CurrentIdx++];
686 int64_t OldInsnID = MatchTable[CurrentIdx++];
687 int64_t OpIdx = MatchTable[CurrentIdx++];
688 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
689 OutMIs[NewInsnID].add(State.
MIs[OldInsnID]->getOperand(OpIdx));
692 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
693 <<
"], MIs[" << OldInsnID <<
"], " << OpIdx <<
")\n");
698 int64_t NewInsnID = MatchTable[CurrentIdx++];
699 int64_t OldInsnID = MatchTable[CurrentIdx++];
700 int64_t OpIdx = MatchTable[CurrentIdx++];
701 int64_t ZeroReg = MatchTable[CurrentIdx++];
702 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
705 OutMIs[NewInsnID].addReg(ZeroReg);
707 OutMIs[NewInsnID].add(MO);
709 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs[" 710 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], " 711 << OpIdx <<
", " << ZeroReg <<
")\n");
716 int64_t NewInsnID = MatchTable[CurrentIdx++];
717 int64_t OldInsnID = MatchTable[CurrentIdx++];
718 int64_t OpIdx = MatchTable[CurrentIdx++];
719 int64_t SubRegIdx = MatchTable[CurrentIdx++];
720 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
721 OutMIs[NewInsnID].addReg(State.
MIs[OldInsnID]->getOperand(OpIdx).getReg(),
724 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs[" 725 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], " 726 << OpIdx <<
", " << SubRegIdx <<
")\n");
731 int64_t InsnID = MatchTable[CurrentIdx++];
732 int64_t RegNum = MatchTable[CurrentIdx++];
733 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
736 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs[" 737 << InsnID <<
"], " << RegNum <<
")\n");
742 int64_t InsnID = MatchTable[CurrentIdx++];
743 int64_t RegNum = MatchTable[CurrentIdx++];
744 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
747 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs[" 748 << InsnID <<
"], " << RegNum <<
")\n");
753 int64_t InsnID = MatchTable[CurrentIdx++];
754 int64_t RegNum = MatchTable[CurrentIdx++];
755 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
756 OutMIs[InsnID].addReg(RegNum);
758 dbgs() << CurrentIdx <<
": GIR_AddRegister(OutMIs[" 759 << InsnID <<
"], " << RegNum <<
")\n");
764 int64_t InsnID = MatchTable[CurrentIdx++];
765 int64_t TempRegID = MatchTable[CurrentIdx++];
766 uint64_t TempRegFlags = MatchTable[CurrentIdx++];
767 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
768 OutMIs[InsnID].addReg(State.
TempRegisters[TempRegID], TempRegFlags);
770 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" 771 << InsnID <<
"], TempRegisters[" << TempRegID
772 <<
"], " << TempRegFlags <<
")\n");
777 int64_t InsnID = MatchTable[CurrentIdx++];
778 int64_t Imm = MatchTable[CurrentIdx++];
779 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
780 OutMIs[InsnID].addImm(Imm);
782 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
783 <<
"], " << Imm <<
")\n");
788 int64_t InsnID = MatchTable[CurrentIdx++];
789 int64_t RendererID = MatchTable[CurrentIdx++];
790 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
791 for (
const auto &RenderOpFn : State.
Renderers[RendererID])
792 RenderOpFn(OutMIs[InsnID]);
794 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs[" 795 << InsnID <<
"], " << RendererID <<
")\n");
799 int64_t InsnID = MatchTable[CurrentIdx++];
800 int64_t RendererID = MatchTable[CurrentIdx++];
801 int64_t RenderOpID = MatchTable[CurrentIdx++];
802 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
803 State.
Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
806 <<
": GIR_ComplexSubOperandRenderer(OutMIs[" 807 << InsnID <<
"], " << RendererID <<
", " 808 << RenderOpID <<
")\n");
813 int64_t NewInsnID = MatchTable[CurrentIdx++];
814 int64_t OldInsnID = MatchTable[CurrentIdx++];
815 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
816 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
"Expected G_CONSTANT");
817 if (State.
MIs[OldInsnID]->getOperand(1).isCImm()) {
818 OutMIs[NewInsnID].addImm(
819 State.
MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
820 }
else if (State.
MIs[OldInsnID]->getOperand(1).isImm())
821 OutMIs[NewInsnID].
add(State.
MIs[OldInsnID]->getOperand(1));
825 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs[" 826 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
832 int64_t NewInsnID = MatchTable[CurrentIdx++];
833 int64_t OldInsnID = MatchTable[CurrentIdx++];
834 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
835 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
"Expected G_FCONSTANT");
836 if (State.
MIs[OldInsnID]->getOperand(1).isFPImm())
837 OutMIs[NewInsnID].addFPImm(
838 State.
MIs[OldInsnID]->getOperand(1).getFPImm());
842 dbgs() << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs[" 843 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
848 int64_t InsnID = MatchTable[CurrentIdx++];
849 int64_t OldInsnID = MatchTable[CurrentIdx++];
850 int64_t RendererFnID = MatchTable[CurrentIdx++];
851 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
853 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs[" 854 << InsnID <<
"], MIs[" << OldInsnID <<
"], " 855 << RendererFnID <<
")\n");
857 *State.
MIs[OldInsnID]);
861 int64_t InsnID = MatchTable[CurrentIdx++];
862 int64_t OpIdx = MatchTable[CurrentIdx++];
863 int64_t RCEnum = MatchTable[CurrentIdx++];
864 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
868 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs[" 869 << InsnID <<
"], " << OpIdx <<
", " << RCEnum
875 int64_t InsnID = MatchTable[CurrentIdx++];
876 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
881 <<
": GIR_ConstrainSelectedInstOperands(OutMIs[" 882 << InsnID <<
"])\n");
887 int64_t InsnID = MatchTable[CurrentIdx++];
888 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
891 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs[" 894 while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
897 dbgs() <<
", MIs[" << MergeInsnID <<
"]");
898 for (
const auto &MMO : State.
MIs[MergeInsnID]->memoperands())
899 OutMIs[InsnID].addMemOperand(MMO);
906 int64_t InsnID = MatchTable[CurrentIdx++];
908 "Attempted to erase an undefined instruction");
909 State.
MIs[InsnID]->eraseFromParent();
911 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs[" 912 << InsnID <<
"])\n");
917 int64_t TempRegID = MatchTable[CurrentIdx++];
918 int64_t
TypeID = MatchTable[CurrentIdx++];
923 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
924 <<
"] = GIR_MakeTempReg(" << TypeID <<
")\n");
929 int64_t RuleID = MatchTable[CurrentIdx++];
934 << CurrentIdx <<
": GIR_Coverage(" << RuleID <<
")");
940 dbgs() << CurrentIdx <<
": GIR_Done\n");
951 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H Check an immediate predicate on the specified instruction.
This class represents lattice values for constants.
std::vector< ComplexRendererFns::value_type > Renderers
void push_back(const T &Elt)
unsigned getReg() const
getReg - Returns the register number.
Increment the rule coverage counter.
Check the opcode on the specified instruction.
bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx, const TargetRegisterClass &RC, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Constrain a register operand of an instruction I to a specified register class.
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
uint64_t getSize() const
Return the size in bytes of the memory reference.
const PredicateBitset * FeatureBitsets
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
unsigned const TargetRegisterInfo * TRI
bool equalsInt(uint64_t V) const
A helper method that can be used to determine if the constant contained within is equal to a constant...
const CustomRendererFn * CustomRenderers
Check the size of the memory access for the given machine memory operand against the size of an opera...
Render operands to the specified instruction using a custom function.
Add a temporary register to the specified instruction.
const ComplexMatcherMemFn * ComplexPredicates
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Merge all memory operands into instruction.
Check the specified operands are identical.
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
Check the operand matches a complex predicate.
Copy an operand to the specified instruction.
bool isIntrinsicID() const
Record the specified instruction.
Add an implicit register use to the specified instruction.
Check the operand is a specific literal integer (i.e.
Switch over the opcode on the specified instruction.
Holds all the information related to register banks.
A description of a memory reference used in the backend.
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++'s definition.
Fail the current try-block, or completely fail to match if there is no current try-block.
Switch over the LLT on the specified instruction operand.
static StringRef getName(Value *V)
Constrain an instruction operand to a register class.
Tagged union holding either a T or a Error.
Check the specified operand is an MBB.
DenseMap< unsigned, unsigned > TempRegisters
Check an immediate predicate on the specified instruction via an APInt.
SmallDenseMap< LLT, unsigned, 64 > TypeIDMap
AtomicOrdering
Atomic ordering for LLVM's memory model.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const T & getValue() const LLVM_LVALUE_FUNCTION
Check a generic C++ instruction predicate.
Create a new temporary register that's not constrained.
Check the type of a pointer to any address space.
Render a G_CONSTANT operator as a sign-extended immediate.
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 is a specific intrinsic ID.
Copy an operand to the specified instruction.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const
Check the register bank for the specified operand.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
Render sub-operands of complex operands to the specified instruction.
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)
Check the size of the memory access for the given machine memory operand.
Check a memory operation has the specified atomic ordering.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Add an immediate to the specified instruction.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
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 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Intrinsic::ID getIntrinsicID() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Check the operand is a specific integer.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
LLVM_NODISCARD T pop_back_val()
Check if the specified operand is safe to fold into the current instruction.
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...
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode...
Check the type for the specified operand.
Add an implicit register def to the specified instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
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.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Constrain an instructions operands according to the instruction description.
virtual bool testImmPredicate_I64(unsigned, int64_t) const
LLVM_NODISCARD bool empty() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Check a floating point immediate predicate on the specified instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
LLVM Value Representation.
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Render complex operands to the specified instruction.
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
Add an register to the specified instruction.
const ConstantInt * getCImm() const
Check the instruction has the right number of operands.
Render a G_FCONSTANT operator as a sign-extended immediate.
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.