15#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
16#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
43template <
class TgtExecutor,
class PredicateBitset,
class ComplexMatcherMemFn,
44 class CustomRendererFn>
52 const PredicateBitset &AvailableFeatures,
61 bool NoFPException = !State.
MIs[0]->getDesc().mayRaiseFPException();
65 enum RejectAction { RejectAndGiveUp, RejectAndResume };
66 auto handleReject = [&]() -> RejectAction {
68 dbgs() << CurrentIdx <<
": Rejected\n");
69 if (OnFailResumeAt.
empty())
70 return RejectAndGiveUp;
73 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
74 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
75 return RejectAndResume;
78 const auto propagateFlags = [&]() {
79 for (
auto MIB : OutMIs) {
83 if (NoFPException && MIB->mayRaiseFPException())
87 MIB.setMIFlags(MIBFlags);
95 auto getTypeFromIdx = [&](int64_t
Idx) ->
LLT {
102 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
103 int64_t MatcherOpcode = MatchTable[CurrentIdx++];
104 switch (MatcherOpcode) {
107 dbgs() << CurrentIdx <<
": Begin try-block\n");
108 OnFailResumeAt.
push_back(MatchTable[CurrentIdx++]);
114 int64_t NewInsnID = MatchTable[CurrentIdx++];
115 int64_t InsnID = MatchTable[CurrentIdx++];
116 int64_t OpIdx = MatchTable[CurrentIdx++];
120 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
125 dbgs() << CurrentIdx <<
": Not a register\n");
126 if (handleReject() == RejectAndGiveUp)
132 dbgs() << CurrentIdx <<
": Is a physical register\n");
133 if (handleReject() == RejectAndGiveUp)
144 if ((
size_t)NewInsnID < State.
MIs.
size())
145 State.
MIs[NewInsnID] = NewMI;
148 "Expected to store MIs in order");
152 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
153 <<
"] = GIM_RecordInsn(" << InsnID <<
", " << OpIdx
159 int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
162 <<
": GIM_CheckFeatures(ExpectedBitsetID="
163 << ExpectedBitsetID <<
")\n");
164 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
166 if (handleReject() == RejectAndGiveUp)
173 int64_t InsnID = MatchTable[CurrentIdx++];
174 int64_t Expected0 = MatchTable[CurrentIdx++];
175 int64_t Expected1 = -1;
177 Expected1 = MatchTable[CurrentIdx++];
179 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
180 unsigned Opcode = State.
MIs[InsnID]->getOpcode();
183 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
184 <<
"], ExpectedOpcode=" << Expected0;
186 <<
" || " << Expected1;
190 if (handleReject() == RejectAndGiveUp)
196 int64_t InsnID = MatchTable[CurrentIdx++];
197 int64_t LowerBound = MatchTable[CurrentIdx++];
198 int64_t UpperBound = MatchTable[CurrentIdx++];
199 int64_t
Default = MatchTable[CurrentIdx++];
201 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
202 const int64_t
Opcode = State.
MIs[InsnID]->getOpcode();
205 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
206 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
207 <<
", JumpTable...) // Got=" <<
Opcode <<
"\n";
213 CurrentIdx = MatchTable[CurrentIdx + (
Opcode - LowerBound)];
223 int64_t InsnID = MatchTable[CurrentIdx++];
224 int64_t OpIdx = MatchTable[CurrentIdx++];
225 int64_t LowerBound = MatchTable[CurrentIdx++];
226 int64_t UpperBound = MatchTable[CurrentIdx++];
227 int64_t
Default = MatchTable[CurrentIdx++];
229 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
233 dbgs() << CurrentIdx <<
": GIM_SwitchType(MIs[" << InsnID
234 <<
"]->getOperand(" << OpIdx <<
"), [" << LowerBound <<
", "
235 << UpperBound <<
"), Default=" <<
Default
236 <<
", JumpTable...) // Got=";
238 dbgs() <<
"Not a VReg\n";
247 const auto TyI = ExecInfo.
TypeIDMap.find(Ty);
252 const int64_t
TypeID = TyI->second;
257 CurrentIdx = MatchTable[CurrentIdx + (
TypeID - LowerBound)];
267 int64_t InsnID = MatchTable[CurrentIdx++];
268 int64_t
Expected = MatchTable[CurrentIdx++];
270 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
271 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
272 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
273 if (State.
MIs[InsnID]->getNumOperands() !=
Expected) {
274 if (handleReject() == RejectAndGiveUp)
281 int64_t InsnID = MatchTable[CurrentIdx++];
283 ? MatchTable[CurrentIdx++]
285 int64_t Predicate = MatchTable[CurrentIdx++];
287 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
288 << InsnID <<
"]->getOperand(" << OpIdx
289 <<
"), Predicate=" << Predicate <<
")\n");
290 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
291 assert((State.
MIs[InsnID]->getOperand(OpIdx).isImm() ||
292 State.
MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
293 "Expected immediate operand");
296 if (State.
MIs[InsnID]->getOperand(OpIdx).isCImm())
297 Value = State.
MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
298 else if (State.
MIs[InsnID]->getOperand(OpIdx).isImm())
299 Value = State.
MIs[InsnID]->getOperand(OpIdx).getImm();
304 if (handleReject() == RejectAndGiveUp)
309 int64_t InsnID = MatchTable[CurrentIdx++];
310 int64_t Predicate = MatchTable[CurrentIdx++];
313 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
314 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
315 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
316 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
317 "Expected G_CONSTANT");
319 if (!State.
MIs[InsnID]->getOperand(1).isCImm())
323 State.
MIs[InsnID]->getOperand(1).getCImm()->getValue();
325 if (handleReject() == RejectAndGiveUp)
330 int64_t InsnID = MatchTable[CurrentIdx++];
331 int64_t Predicate = MatchTable[CurrentIdx++];
334 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
335 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
336 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
337 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
338 "Expected G_FCONSTANT");
339 assert(State.
MIs[InsnID]->getOperand(1).isFPImm() &&
340 "Expected FPImm operand");
343 State.
MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
346 if (handleReject() == RejectAndGiveUp)
352 int64_t InsnID = MatchTable[CurrentIdx++];
356 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
357 << InsnID <<
"])\n");
358 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
361 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
362 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
363 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
367 if (handleReject() == RejectAndGiveUp)
372 if (handleReject() == RejectAndGiveUp)
383 int64_t Predicate = MatchTable[CurrentIdx++];
386 <<
": GIM_CheckSimplePredicate(Predicate="
387 << Predicate <<
")\n");
390 if (handleReject() == RejectAndGiveUp)
396 int64_t InsnID = MatchTable[CurrentIdx++];
397 int64_t Predicate = MatchTable[CurrentIdx++];
400 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
401 << InsnID <<
"], Predicate=" << Predicate <<
")\n");
402 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
406 if (handleReject() == RejectAndGiveUp)
411 int64_t InsnID = MatchTable[CurrentIdx++];
414 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
418 assert(
MI &&
"Used insn before defined");
419 assert(
MI->getNumDefs() > 0 &&
"No defs");
420 const Register Res =
MI->getOperand(0).getReg();
422 if (!
MRI.use_nodbg_empty(Res)) {
423 if (handleReject() == RejectAndGiveUp)
430 int64_t InsnID = MatchTable[CurrentIdx++];
433 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
434 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
435 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
436 if (!State.
MIs[InsnID]->hasOneMemOperand())
437 if (handleReject() == RejectAndGiveUp)
440 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
441 if (MMO->getMergedOrdering() != Ordering)
442 if (handleReject() == RejectAndGiveUp)
447 int64_t InsnID = MatchTable[CurrentIdx++];
451 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
452 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
453 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
454 if (!State.
MIs[InsnID]->hasOneMemOperand())
455 if (handleReject() == RejectAndGiveUp)
458 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
460 if (handleReject() == RejectAndGiveUp)
465 int64_t InsnID = MatchTable[CurrentIdx++];
469 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
470 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
471 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
472 if (!State.
MIs[InsnID]->hasOneMemOperand())
473 if (handleReject() == RejectAndGiveUp)
476 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
478 if (handleReject() == RejectAndGiveUp)
483 int64_t InsnID = MatchTable[CurrentIdx++];
484 int64_t MMOIdx = MatchTable[CurrentIdx++];
486 const int NumAddrSpace = MatchTable[CurrentIdx++];
488 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
489 if (handleReject() == RejectAndGiveUp)
496 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
499 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
503 for (
int I = 0;
I != NumAddrSpace; ++
I) {
504 unsigned AddrSpace = MatchTable[CurrentIdx++];
506 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
507 << AddrSpace <<
'\n');
509 if (AddrSpace == MMOAddrSpace) {
515 CurrentIdx = LastIdx;
516 if (!
Success && handleReject() == RejectAndGiveUp)
521 int64_t InsnID = MatchTable[CurrentIdx++];
522 int64_t MMOIdx = MatchTable[CurrentIdx++];
523 unsigned MinAlign = MatchTable[CurrentIdx++];
525 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
527 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
528 if (handleReject() == RejectAndGiveUp)
534 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
536 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
537 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
538 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
546 int64_t InsnID = MatchTable[CurrentIdx++];
547 int64_t MMOIdx = MatchTable[CurrentIdx++];
551 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
552 << InsnID <<
"]->memoperands() + " << MMOIdx
553 <<
", Size=" <<
Size <<
")\n");
554 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
556 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
557 if (handleReject() == RejectAndGiveUp)
563 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
566 <<
" bytes vs " <<
Size
569 if (handleReject() == RejectAndGiveUp)
577 int64_t InsnID = MatchTable[CurrentIdx++];
578 int64_t MMOIdx = MatchTable[CurrentIdx++];
579 int64_t OpIdx = MatchTable[CurrentIdx++];
582 TgtExecutor::getName(),
583 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
588 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
589 <<
", OpIdx=" << OpIdx <<
")\n");
590 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
595 dbgs() << CurrentIdx <<
": Not a register\n");
596 if (handleReject() == RejectAndGiveUp)
601 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
602 if (handleReject() == RejectAndGiveUp)
608 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
613 if (handleReject() == RejectAndGiveUp)
617 if (handleReject() == RejectAndGiveUp)
621 if (handleReject() == RejectAndGiveUp)
627 int64_t InsnID = MatchTable[CurrentIdx++];
628 int64_t OpIdx = MatchTable[CurrentIdx++];
629 int64_t
TypeID = MatchTable[CurrentIdx++];
631 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
632 <<
"]->getOperand(" << OpIdx
633 <<
"), TypeID=" <<
TypeID <<
")\n");
634 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
637 if (handleReject() == RejectAndGiveUp)
643 int64_t InsnID = MatchTable[CurrentIdx++];
644 int64_t OpIdx = MatchTable[CurrentIdx++];
645 uint64_t SizeInBits = MatchTable[CurrentIdx++];
648 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
649 << InsnID <<
"]->getOperand(" << OpIdx
650 <<
"), SizeInBits=" << SizeInBits <<
")\n");
651 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
656 if (SizeInBits == 0) {
662 assert(SizeInBits != 0 &&
"Pointer size must be known");
666 if (handleReject() == RejectAndGiveUp)
668 }
else if (handleReject() == RejectAndGiveUp)
674 int64_t InsnID = MatchTable[CurrentIdx++];
675 int64_t OpIdx = MatchTable[CurrentIdx++];
676 uint64_t StoreIdx = MatchTable[CurrentIdx++];
679 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
680 << InsnID <<
"]->getOperand(" << OpIdx
681 <<
"), StoreIdx=" << StoreIdx <<
")\n");
682 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
688 int64_t InsnID = MatchTable[CurrentIdx++];
689 int64_t OpIdx = MatchTable[CurrentIdx++];
690 int64_t TypeIdx = MatchTable[CurrentIdx++];
693 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
694 << InsnID <<
"]->getOperand(" << OpIdx
695 <<
"), TypeIdx=" << TypeIdx <<
")\n");
696 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
697 assert(TypeIdx <= 0 &&
"Temp types always have negative indexes!");
699 TypeIdx = 1 - TypeIdx;
700 const auto &
Op = State.
MIs[InsnID]->getOperand(OpIdx);
707 int64_t InsnID = MatchTable[CurrentIdx++];
708 int64_t OpIdx = MatchTable[CurrentIdx++];
709 int64_t RCEnum = MatchTable[CurrentIdx++];
711 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
712 << InsnID <<
"]->getOperand(" << OpIdx
713 <<
"), RCEnum=" << RCEnum <<
")\n");
714 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
720 if (handleReject() == RejectAndGiveUp)
727 int64_t InsnID = MatchTable[CurrentIdx++];
728 int64_t OpIdx = MatchTable[CurrentIdx++];
729 int64_t RendererID = MatchTable[CurrentIdx++];
730 int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
732 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
733 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
734 <<
"]->getOperand(" << OpIdx
735 <<
"), ComplexPredicateID=" << ComplexPredicateID
737 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
741 State.
MIs[InsnID]->getOperand(OpIdx));
744 else if (handleReject() == RejectAndGiveUp)
750 int64_t InsnID = MatchTable[CurrentIdx++];
751 int64_t OpIdx = MatchTable[CurrentIdx++];
752 int64_t
Value = MatchTable[CurrentIdx++];
754 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
755 << InsnID <<
"]->getOperand(" << OpIdx
756 <<
"), Value=" <<
Value <<
")\n");
757 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
765 if (handleReject() == RejectAndGiveUp)
772 if (handleReject() == RejectAndGiveUp)
775 }
else if (handleReject() == RejectAndGiveUp)
782 int64_t InsnID = MatchTable[CurrentIdx++];
783 int64_t OpIdx = MatchTable[CurrentIdx++];
784 int64_t
Value = MatchTable[CurrentIdx++];
786 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
787 << InsnID <<
"]->getOperand(" << OpIdx
788 <<
"), Value=" <<
Value <<
")\n");
789 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
797 if (handleReject() == RejectAndGiveUp)
804 int64_t InsnID = MatchTable[CurrentIdx++];
805 int64_t OpIdx = MatchTable[CurrentIdx++];
806 int64_t
Value = MatchTable[CurrentIdx++];
808 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
809 << InsnID <<
"]->getOperand(" << OpIdx
810 <<
"), Value=" <<
Value <<
")\n");
811 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
814 if (handleReject() == RejectAndGiveUp)
819 int64_t InsnID = MatchTable[CurrentIdx++];
820 int64_t OpIdx = MatchTable[CurrentIdx++];
821 int64_t
Value = MatchTable[CurrentIdx++];
823 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
824 << InsnID <<
"]->getOperand(" << OpIdx
825 <<
"), Value=" <<
Value <<
")\n");
826 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
829 if (handleReject() == RejectAndGiveUp)
834 int64_t InsnID = MatchTable[CurrentIdx++];
835 int64_t OpIdx = MatchTable[CurrentIdx++];
837 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
838 <<
"]->getOperand(" << OpIdx <<
"))\n");
839 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
840 if (!State.
MIs[InsnID]->getOperand(OpIdx).isMBB()) {
841 if (handleReject() == RejectAndGiveUp)
847 int64_t InsnID = MatchTable[CurrentIdx++];
848 int64_t OpIdx = MatchTable[CurrentIdx++];
850 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
851 <<
"]->getOperand(" << OpIdx <<
"))\n");
852 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
853 if (!State.
MIs[InsnID]->getOperand(OpIdx).isImm()) {
854 if (handleReject() == RejectAndGiveUp)
860 int64_t InsnID = MatchTable[CurrentIdx++];
862 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(MIs["
863 << InsnID <<
"])\n");
864 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
866 if (handleReject() == RejectAndGiveUp)
873 int64_t InsnID = MatchTable[CurrentIdx++];
874 int64_t OpIdx = MatchTable[CurrentIdx++];
875 int64_t OtherInsnID = MatchTable[CurrentIdx++];
876 int64_t OtherOpIdx = MatchTable[CurrentIdx++];
878 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
879 << InsnID <<
"][" << OpIdx <<
"], MIs["
880 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
881 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
882 assert(State.
MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
888 if (
Op.isReg() && OtherOp.
isReg()) {
895 if (!
Op.isIdenticalTo(OtherOp)) {
896 if (handleReject() == RejectAndGiveUp)
902 int64_t OldInsnID = MatchTable[CurrentIdx++];
903 int64_t OldOpIdx = MatchTable[CurrentIdx++];
904 int64_t NewInsnID = MatchTable[CurrentIdx++];
905 int64_t NewOpIdx = MatchTable[CurrentIdx++];
908 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
909 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
910 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
912 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
913 Register New = State.
MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
915 if (handleReject() == RejectAndGiveUp)
921 int64_t InsnID = MatchTable[CurrentIdx++];
925 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
926 <<
"], " << Flags <<
")\n");
927 if ((State.
MIs[InsnID]->getFlags() & Flags) != Flags) {
928 if (handleReject() == RejectAndGiveUp)
934 int64_t InsnID = MatchTable[CurrentIdx++];
938 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
939 <<
"], " << Flags <<
")\n");
940 if ((State.
MIs[InsnID]->getFlags() & Flags)) {
941 if (handleReject() == RejectAndGiveUp)
948 dbgs() << CurrentIdx <<
": GIM_Reject\n");
949 if (handleReject() == RejectAndGiveUp)
953 int64_t OldInsnID = MatchTable[CurrentIdx++];
954 uint64_t NewInsnID = MatchTable[CurrentIdx++];
955 int64_t NewOpcode = MatchTable[CurrentIdx++];
956 if (NewInsnID >= OutMIs.
size())
957 OutMIs.
resize(NewInsnID + 1);
963 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
967 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
968 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
969 << NewOpcode <<
")\n");
974 uint64_t NewInsnID = MatchTable[CurrentIdx++];
975 int64_t
Opcode = MatchTable[CurrentIdx++];
976 if (NewInsnID >= OutMIs.
size())
977 OutMIs.
resize(NewInsnID + 1);
981 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
982 << NewInsnID <<
"], " <<
Opcode <<
")\n");
987 int64_t TempRegID = MatchTable[CurrentIdx++];
988 int64_t Imm = MatchTable[CurrentIdx++];
991 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
992 << TempRegID <<
"], Imm=" << Imm <<
")\n");
997 int64_t NewInsnID = MatchTable[CurrentIdx++];
998 int64_t OldInsnID = MatchTable[CurrentIdx++];
999 int64_t OpIdx = MatchTable[CurrentIdx++];
1000 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1001 OutMIs[NewInsnID].add(State.
MIs[OldInsnID]->getOperand(OpIdx));
1004 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1005 <<
"], MIs[" << OldInsnID <<
"], " << OpIdx <<
")\n");
1010 int64_t NewInsnID = MatchTable[CurrentIdx++];
1011 int64_t OldInsnID = MatchTable[CurrentIdx++];
1012 int64_t OpIdx = MatchTable[CurrentIdx++];
1013 int64_t ZeroReg = MatchTable[CurrentIdx++];
1014 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1017 OutMIs[NewInsnID].addReg(ZeroReg);
1019 OutMIs[NewInsnID].add(MO);
1021 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1022 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1023 << OpIdx <<
", " << ZeroReg <<
")\n");
1028 int64_t NewInsnID = MatchTable[CurrentIdx++];
1029 int64_t OldInsnID = MatchTable[CurrentIdx++];
1030 int64_t OpIdx = MatchTable[CurrentIdx++];
1031 int64_t SubRegIdx = MatchTable[CurrentIdx++];
1032 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1033 OutMIs[NewInsnID].addReg(State.
MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1036 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1037 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1038 << OpIdx <<
", " << SubRegIdx <<
")\n");
1043 int64_t InsnID = MatchTable[CurrentIdx++];
1044 int64_t RegNum = MatchTable[CurrentIdx++];
1045 auto Flags = (
uint64_t)MatchTable[CurrentIdx++];
1046 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1048 OutMIs[InsnID].addDef(RegNum, Flags);
1050 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1051 << InsnID <<
"], " << RegNum <<
")\n");
1056 int64_t InsnID = MatchTable[CurrentIdx++];
1057 int64_t RegNum = MatchTable[CurrentIdx++];
1058 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1061 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1062 << InsnID <<
"], " << RegNum <<
")\n");
1067 int64_t InsnID = MatchTable[CurrentIdx++];
1068 int64_t RegNum = MatchTable[CurrentIdx++];
1069 uint64_t RegFlags = MatchTable[CurrentIdx++];
1070 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1071 OutMIs[InsnID].addReg(RegNum, RegFlags);
1074 << CurrentIdx <<
": GIR_AddRegister(OutMIs[" << InsnID
1075 <<
"], " << RegNum <<
", " << RegFlags <<
")\n");
1079 int64_t InsnID = MatchTable[CurrentIdx++];
1080 int64_t OpIdx = MatchTable[CurrentIdx++];
1082 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1083 << InsnID <<
"], OpIdx=" << OpIdx <<
")\n");
1085 assert(
MI &&
"Modifying undefined instruction");
1086 MI->getOperand(
MI->getNumExplicitOperands() + OpIdx).setIsDead();
1090 int64_t InsnID = MatchTable[CurrentIdx++];
1094 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1095 << InsnID <<
"], " << Flags <<
")\n");
1097 MI->setFlags(
MI->getFlags() | Flags);
1101 int64_t InsnID = MatchTable[CurrentIdx++];
1105 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1106 << InsnID <<
"], " << Flags <<
")\n");
1108 MI->setFlags(
MI->getFlags() & ~Flags);
1112 int64_t InsnID = MatchTable[CurrentIdx++];
1113 int64_t OldInsnID = MatchTable[CurrentIdx++];
1116 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1117 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1119 MI->setFlags(
MI->getFlags() | State.
MIs[OldInsnID]->getFlags());
1124 int64_t InsnID = MatchTable[CurrentIdx++];
1125 int64_t TempRegID = MatchTable[CurrentIdx++];
1126 uint64_t TempRegFlags = MatchTable[CurrentIdx++];
1129 SubReg = MatchTable[CurrentIdx++];
1131 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1133 OutMIs[InsnID].addReg(State.
TempRegisters[TempRegID], TempRegFlags,
1136 TgtExecutor::getName(),
1137 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1138 <<
"], TempRegisters[" << TempRegID <<
"]";
1140 dbgs() <<
", " << TempRegFlags <<
")\n");
1145 int64_t InsnID = MatchTable[CurrentIdx++];
1146 int64_t Imm = MatchTable[CurrentIdx++];
1147 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1148 OutMIs[InsnID].addImm(Imm);
1150 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1151 <<
"], " << Imm <<
")\n");
1156 int64_t InsnID = MatchTable[CurrentIdx++];
1157 int64_t
TypeID = MatchTable[CurrentIdx++];
1158 int64_t Imm = MatchTable[CurrentIdx++];
1159 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1163 OutMIs[InsnID].addCImm(
1166 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1167 <<
"], TypeID=" <<
TypeID <<
", Imm=" << Imm
1173 int64_t InsnID = MatchTable[CurrentIdx++];
1174 int64_t RendererID = MatchTable[CurrentIdx++];
1175 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1176 for (
const auto &RenderOpFn : State.
Renderers[RendererID])
1177 RenderOpFn(OutMIs[InsnID]);
1179 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1180 << InsnID <<
"], " << RendererID <<
")\n");
1184 int64_t InsnID = MatchTable[CurrentIdx++];
1185 int64_t RendererID = MatchTable[CurrentIdx++];
1186 int64_t RenderOpID = MatchTable[CurrentIdx++];
1187 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1188 State.
Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1190 dbgs() << CurrentIdx
1191 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1192 << InsnID <<
"], " << RendererID <<
", "
1193 << RenderOpID <<
")\n");
1197 int64_t InsnID = MatchTable[CurrentIdx++];
1198 int64_t RendererID = MatchTable[CurrentIdx++];
1199 int64_t RenderOpID = MatchTable[CurrentIdx++];
1200 int64_t SubRegIdx = MatchTable[CurrentIdx++];
1202 assert(
MI &&
"Attempted to add to undefined instruction");
1204 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1206 dbgs() << CurrentIdx
1207 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1208 << InsnID <<
"], " << RendererID <<
", "
1209 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1214 int64_t NewInsnID = MatchTable[CurrentIdx++];
1215 int64_t OldInsnID = MatchTable[CurrentIdx++];
1216 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1217 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1218 "Expected G_CONSTANT");
1219 if (State.
MIs[OldInsnID]->getOperand(1).isCImm()) {
1220 OutMIs[NewInsnID].addImm(
1221 State.
MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1222 }
else if (State.
MIs[OldInsnID]->getOperand(1).isImm())
1223 OutMIs[NewInsnID].add(State.
MIs[OldInsnID]->getOperand(1));
1227 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1228 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1234 int64_t NewInsnID = MatchTable[CurrentIdx++];
1235 int64_t OldInsnID = MatchTable[CurrentIdx++];
1236 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1237 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1238 "Expected G_FCONSTANT");
1239 if (State.
MIs[OldInsnID]->getOperand(1).isFPImm())
1240 OutMIs[NewInsnID].addFPImm(
1241 State.
MIs[OldInsnID]->getOperand(1).getFPImm());
1246 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1247 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1252 int64_t InsnID = MatchTable[CurrentIdx++];
1253 int64_t OldInsnID = MatchTable[CurrentIdx++];
1254 int64_t RendererFnID = MatchTable[CurrentIdx++];
1255 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1257 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1258 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1259 << RendererFnID <<
")\n");
1261 OutMIs[InsnID], *State.
MIs[OldInsnID],
1266 int64_t FnID = MatchTable[CurrentIdx++];
1268 dbgs() << CurrentIdx <<
": GIR_CustomAction(FnID=" << FnID
1275 int64_t InsnID = MatchTable[CurrentIdx++];
1276 int64_t OldInsnID = MatchTable[CurrentIdx++];
1277 int64_t OpIdx = MatchTable[CurrentIdx++];
1278 int64_t RendererFnID = MatchTable[CurrentIdx++];
1279 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1282 dbgs() << CurrentIdx
1283 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1284 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1285 << OpIdx <<
"), " << RendererFnID <<
")\n");
1287 OutMIs[InsnID], *State.
MIs[OldInsnID], OpIdx);
1291 int64_t InsnID = MatchTable[CurrentIdx++];
1292 int64_t OpIdx = MatchTable[CurrentIdx++];
1293 int64_t RCEnum = MatchTable[CurrentIdx++];
1294 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1302 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1303 << InsnID <<
"], " << OpIdx <<
", " << RCEnum
1309 int64_t InsnID = MatchTable[CurrentIdx++];
1310 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1314 dbgs() << CurrentIdx
1315 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1316 << InsnID <<
"])\n");
1321 int64_t InsnID = MatchTable[CurrentIdx++];
1322 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1325 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1328 while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
1331 dbgs() <<
", MIs[" << MergeInsnID <<
"]");
1332 for (
const auto &MMO : State.
MIs[MergeInsnID]->memoperands())
1333 OutMIs[InsnID].addMemOperand(MMO);
1340 int64_t InsnID = MatchTable[CurrentIdx++];
1342 assert(
MI &&
"Attempted to erase an undefined instruction");
1344 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1345 << InsnID <<
"])\n");
1352 MI->eraseFromParent();
1357 int64_t TempRegID = MatchTable[CurrentIdx++];
1358 int64_t
TypeID = MatchTable[CurrentIdx++];
1361 MRI.createGenericVirtualRegister(getTypeFromIdx(
TypeID));
1363 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1364 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1368 int64_t OldInsnID = MatchTable[CurrentIdx++];
1369 int64_t OldOpIdx = MatchTable[CurrentIdx++];
1370 int64_t NewInsnID = MatchTable[CurrentIdx++];
1371 int64_t NewOpIdx = MatchTable[CurrentIdx++];
1374 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1375 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1376 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1378 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1379 Register New = State.
MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1382 MRI.replaceRegWith(Old, New);
1388 int64_t OldInsnID = MatchTable[CurrentIdx++];
1389 int64_t OldOpIdx = MatchTable[CurrentIdx++];
1390 int64_t TempRegID = MatchTable[CurrentIdx++];
1393 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1394 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1395 << TempRegID <<
"])\n");
1397 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1401 MRI.replaceRegWith(Old, New);
1407 int64_t RuleID = MatchTable[CurrentIdx++];
1412 <<
": GIR_Coverage("
1419 dbgs() << CurrentIdx <<
": GIR_Done\n");
unsigned const MachineRegisterInfo * MRI
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static constexpr uint32_t Opcode
Class for arbitrary precision integers.
void setCovered(uint64_t RuleID)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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...
This class represents an Operation in the Expression.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Tagged union holding either a T or a Error.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
virtual bool testSimplePredicate(unsigned) const
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
virtual bool testImmPredicate_APInt(unsigned, const APInt &) const
virtual bool testMIPredicate_MI(unsigned, const MachineInstr &, const MatcherState &State) const
virtual bool testImmPredicate_I64(unsigned, int64_t) const
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
bool executeMatchTable(TgtExecutor &Exec, MatcherState &State, const ExecInfoTy< PredicateBitset, ComplexMatcherMemFn, CustomRendererFn > &ExecInfo, MachineIRBuilder &Builder, 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.
bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI, bool Splat=false) const
virtual void runCustomAction(unsigned, const MatcherState &State, NewMIVector &OutMIs) const
bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const
Return true if MI can obviously be folded into IntoMI.
CodeGenCoverage * CoverageInfo
Abstract class that contains various methods for clients to notify about changes.
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
void finishedChangingAllUsesOfReg()
All instructions reported as changing by changingAllUsesOfReg() have finished being changed.
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
virtual void erasingInstr(MachineInstr &MI)=0
An instruction is about to be erased.
void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg)
All the instructions using the given register are being changed.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
constexpr unsigned getScalarSizeInBits() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
constexpr unsigned getAddressSpace() const
This is an important class for using LLVM in a threaded context.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Helper class to build MachineInstr.
GISelChangeObserver * getObserver()
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Representation of each machine instruction.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
A description of a memory reference used in the backend.
unsigned getAddrSpace() const
uint64_t getSize() const
Return the size in bytes of the memory reference.
uint64_t getSizeInBits() const
Return the size in bits of the memory reference.
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
bool isIntrinsicID() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
Intrinsic::ID getIntrinsicID() const
unsigned getPredicate() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Holds all the information related to register banks.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const
Get a register bank that covers RC.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
This is an optimization pass for GlobalISel generic memory operations.
bool isBuildVectorAllZeros(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
@ GIU_MergeMemOperands_EndOfList
Indicates the end of the variable-length MergeInsnID list in a GIR_MergeMemOperands opcode.
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...
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
bool isBuildVectorAllOnes(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ GIR_ComplexRenderer
Render complex operands to the specified instruction.
@ GIR_ReplaceRegWithTempReg
Replaces all references to a register with a temporary register.
@ GIR_ComplexSubOperandRenderer
Render sub-operands of complex operands to the specified instruction.
@ GIR_MakeTempReg
Create a new temporary register that's not constrained.
@ GIM_CheckMemorySizeEqualTo
Check the size of the memory access for the given machine memory operand.
@ GIR_Done
A successful emission.
@ GIM_RecordNamedOperand
Predicates with 'let PredicateCodeUsesOperands = 1' need to examine some named operands that will be ...
@ GIM_Try
Begin a try-block to attempt a match and jump to OnFail if it is unsuccessful.
@ GIM_CheckIsBuildVectorAllOnes
Check if this is a vector that can be treated as a vector splat constant.
@ GIM_CheckNumOperands
Check the instruction has the right number of operands.
@ GIR_AddCImm
Add an CImm to the specified instruction.
@ GIR_ConstrainOperandRC
Constrain an instruction operand to a register class.
@ GIM_CheckI64ImmPredicate
Check an immediate predicate on the specified instruction.
@ GIR_AddImplicitDef
Add an implicit register def to the specified instruction.
@ GIM_CheckAPIntImmPredicate
Check an immediate predicate on the specified instruction via an APInt.
@ GIM_CheckHasNoUse
Check if there's no use of the first result.
@ GIM_CheckPointerToAny
Check the type of a pointer to any address space.
@ GIM_CheckMemorySizeEqualToLLT
Check the size of the memory access for the given machine memory operand against the size of an opera...
@ GIM_CheckComplexPattern
Check the operand matches a complex predicate.
@ GIR_CopyConstantAsSImm
Render a G_CONSTANT operator as a sign-extended immediate.
@ GIR_EraseFromParent
Erase from parent.
@ GIR_CustomAction
Calls a C++ function to perform an action when a match is complete.
@ GIM_SwitchType
Switch over the LLT on the specified instruction operand.
@ GIR_CopySubReg
Copy an operand to the specified instruction.
@ GIR_MutateOpcode
Mutate an instruction.
@ GIM_CheckIsBuildVectorAllZeros
@ GIM_CheckAtomicOrderingOrStrongerThan
@ GIR_AddRegister
Add an register to the specified instruction.
@ GIR_AddTempSubRegister
Add a temporary register to the specified instruction.
@ GIM_CheckIsSafeToFold
Check if the specified operand is safe to fold into the current instruction.
@ GIM_CheckOpcode
Check the opcode on the specified instruction.
@ GIR_ReplaceReg
Replaces all references to a register from an instruction with another register from another instruct...
@ GIM_SwitchOpcode
Switch over the opcode on the specified instruction.
@ GIM_CheckAPFloatImmPredicate
Check a floating point immediate predicate on the specified instruction.
@ GIM_Reject
Fail the current try-block, or completely fail to match if there is no current try-block.
@ GIR_AddTempRegister
Add a temporary register to the specified instruction.
@ GIR_Copy
Copy an operand to the specified instruction.
@ GIR_AddImm
Add an immediate to the specified instruction.
@ GIR_CopyFConstantAsFPImm
Render a G_FCONSTANT operator as a sign-extended immediate.
@ GIM_MIFlags
Check that a matched instruction has, or doesn't have a MIFlag.
@ GIR_CopyOrAddZeroReg
Copy an operand to the specified instruction or add a zero register if the operand is a zero immediat...
@ GIM_CheckMemoryAlignment
Check the minimum alignment of the memory access for the given machine memory operand.
@ GIM_CheckIsSameOperand
Check the specified operands are identical.
@ GIM_CheckIsSameOperandIgnoreCopies
@ GIM_CheckIsMBB
Check the specified operand is an MBB.
@ GIM_CheckMemorySizeGreaterThanLLT
@ GIM_CheckRegBankForClass
Check the register bank for the specified operand.
@ GIM_CheckLiteralInt
Check the operand is a specific literal integer (i.e.
@ GIM_CheckMemorySizeLessThanLLT
@ GIM_RecordRegType
Records an operand's register type into the set of temporary types.
@ GIR_CopyMIFlags
Copy the MIFlags of a matched instruction into an output instruction.
@ GIR_BuildMI
Build a new instruction.
@ GIM_RecordInsn
Record the specified instruction.
@ GIM_CheckIsImm
Check the specified operand is an Imm.
@ GIM_CheckFeatures
Check the feature bits.
@ GIM_CheckCanReplaceReg
Check we can replace all uses of a register with another.
@ GIM_CheckMemoryAddressSpace
Check the address space of the memory access for the given machine memory operand.
@ GIR_CustomRenderer
Render operands to the specified instruction using a custom function.
@ GIM_CheckAtomicOrdering
Check a memory operation has the specified atomic ordering.
@ GIM_CheckType
Check the type for the specified operand.
@ GIM_CheckCmpPredicate
Check the operand is a specific predicate.
@ GIM_CheckOpcodeIsEither
Check the opcode on the specified instruction, checking 2 acceptable alternatives.
@ GIR_SetImplicitDefDead
Marks the implicit def of a register as dead.
@ GIR_BuildConstant
Builds a constant and stores its result in a TempReg.
@ GIR_AddImplicitUse
Add an implicit register use to the specified instruction.
@ GIR_Coverage
Increment the rule coverage counter.
@ GIR_MergeMemOperands
Merge all memory operands into instruction.
@ GIM_CheckImmOperandPredicate
Check an immediate predicate on the specified instruction.
@ GIM_CheckAtomicOrderingWeakerThan
@ GIR_SetMIFlags
Set or unset a MIFlag on an instruction.
@ GIM_CheckIntrinsicID
Check the operand is a specific intrinsic ID.
@ GIM_CheckConstantInt
Check the operand is a specific integer.
@ GIR_ComplexSubOperandSubRegRenderer
Render subregisters of suboperands of complex operands to the specified instruction.
@ GIM_RecordInsnIgnoreCopies
@ GIR_CustomOperandRenderer
Render operands to the specified instruction using a custom function, reading from a specific operand...
@ GIR_ConstrainSelectedInstOperands
Constrain an instructions operands according to the instruction description.
@ GIM_CheckCxxInsnPredicate
Check a generic C++ instruction predicate.
@ GIM_CheckSimplePredicate
Check a trivial predicate which takes no arguments.
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
@ GICXXCustomAction_Invalid
Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the source register for Reg, folding away any trivial copies.
@ Default
The result values are uniform if and only if all operands are uniform.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
const CustomRendererFn * CustomRenderers
SmallDenseMap< LLT, unsigned, 64 > TypeIDMap
const ComplexMatcherMemFn * ComplexPredicates
const PredicateBitset * FeatureBitsets
std::array< const MachineOperand *, 3 > RecordedOperands
Named operands that predicate with 'let PredicateCodeUsesOperands = 1' referenced in its argument lis...
SmallVector< LLT, 4 > RecordedTypes
Types extracted from an instruction's operand.
DenseMap< unsigned, unsigned > TempRegisters
std::vector< ComplexRendererFns::value_type > Renderers