15#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
16#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
44template <
class TgtExecutor,
class PredicateBitset,
class ComplexMatcherMemFn,
45 class CustomRendererFn>
53 const PredicateBitset &AvailableFeatures,
62 bool NoFPException = !State.
MIs[0]->getDesc().mayRaiseFPException();
66 enum RejectAction { RejectAndGiveUp, RejectAndResume };
67 auto handleReject = [&]() -> RejectAction {
69 dbgs() << CurrentIdx <<
": Rejected\n");
70 if (OnFailResumeAt.
empty())
71 return RejectAndGiveUp;
74 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
75 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
76 return RejectAndResume;
79 const auto propagateFlags = [&]() {
80 for (
auto MIB : OutMIs) {
83 uint32_t MIBFlags = Flags | MIB.getInstr()->getFlags();
84 if (NoFPException && MIB->mayRaiseFPException())
88 MIB.setMIFlags(MIBFlags);
96 const auto getTypeFromIdx = [&](int64_t
Idx) ->
LLT {
102 const auto readULEB = [&]() {
111 const auto readS8 = [&]() {
return (int8_t)MatchTable[CurrentIdx++]; };
113 const auto readU16 = [&]() {
114 auto V = readBytesAs<uint16_t>(MatchTable + CurrentIdx);
119 const auto readU32 = [&]() {
120 auto V = readBytesAs<uint32_t>(MatchTable + CurrentIdx);
125 const auto readU64 = [&]() {
126 auto V = readBytesAs<uint64_t>(MatchTable + CurrentIdx);
138 MI->eraseFromParent();
142 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
143 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
144 switch (MatcherOpcode) {
147 dbgs() << CurrentIdx <<
": Begin try-block\n");
160 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
165 dbgs() << CurrentIdx <<
": Not a register\n");
166 if (handleReject() == RejectAndGiveUp)
172 dbgs() << CurrentIdx <<
": Is a physical register\n");
173 if (handleReject() == RejectAndGiveUp)
184 if ((
size_t)NewInsnID < State.
MIs.
size())
185 State.
MIs[NewInsnID] = NewMI;
188 "Expected to store MIs in order");
192 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
193 <<
"] = GIM_RecordInsn(" << InsnID <<
", " <<
OpIdx
199 uint16_t ExpectedBitsetID = readU16();
202 <<
": GIM_CheckFeatures(ExpectedBitsetID="
203 << ExpectedBitsetID <<
")\n");
204 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
206 if (handleReject() == RejectAndGiveUp)
217 Expected1 = readU16();
219 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
220 unsigned Opcode = State.
MIs[InsnID]->getOpcode();
223 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
224 <<
"], ExpectedOpcode=" << Expected0;
226 dbgs() <<
" || " << Expected1;
227 dbgs() <<
") // Got=" << Opcode <<
"\n";
230 if (Opcode != Expected0 && Opcode != Expected1) {
231 if (handleReject() == RejectAndGiveUp)
242 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
243 const int64_t Opcode = State.
MIs[InsnID]->getOpcode();
246 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
247 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
248 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
250 if (Opcode < LowerBound || UpperBound <= Opcode) {
254 const auto EntryIdx = (Opcode - LowerBound);
257 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (EntryIdx * 4));
273 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
277 dbgs() << CurrentIdx <<
": GIM_SwitchType(MIs[" << InsnID
278 <<
"]->getOperand(" <<
OpIdx <<
"), [" << LowerBound <<
", "
279 << UpperBound <<
"), Default=" <<
Default
280 <<
", JumpTable...) // Got=";
282 dbgs() <<
"Not a VReg\n";
291 const auto TyI = ExecInfo.
TypeIDMap.find(Ty);
296 const int64_t
TypeID = TyI->second;
301 const auto NumEntry = (
TypeID - LowerBound);
304 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (NumEntry * 4));
319 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands"
320 << (IsLE ?
"LE" :
"GE") <<
"(MIs[" << InsnID
321 <<
"], Expected=" <<
Expected <<
")\n");
322 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
323 const unsigned NumOps = State.
MIs[InsnID]->getNumOperands();
325 if (handleReject() == RejectAndGiveUp)
334 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
335 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
336 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
337 if (State.
MIs[InsnID]->getNumOperands() !=
Expected) {
338 if (handleReject() == RejectAndGiveUp)
350 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
351 << InsnID <<
"]->getOperand(" <<
OpIdx
352 <<
"), Predicate=" <<
Predicate <<
")\n");
353 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
355 State.
MIs[InsnID]->getOperand(
OpIdx).isCImm()) &&
356 "Expected immediate operand");
359 if (State.
MIs[InsnID]->getOperand(
OpIdx).isCImm())
360 Value = State.
MIs[InsnID]->getOperand(
OpIdx).getCImm()->getSExtValue();
361 else if (State.
MIs[InsnID]->getOperand(
OpIdx).isImm())
367 if (handleReject() == RejectAndGiveUp)
376 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
377 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
378 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
379 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
380 "Expected G_CONSTANT");
382 if (!State.
MIs[InsnID]->getOperand(1).isCImm())
386 State.
MIs[InsnID]->getOperand(1).getCImm()->getValue();
388 if (handleReject() == RejectAndGiveUp)
397 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
398 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
399 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
400 assert(State.
MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
401 "Expected G_FCONSTANT");
402 assert(State.
MIs[InsnID]->getOperand(1).isFPImm() &&
403 "Expected FPImm operand");
406 State.
MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
409 if (handleReject() == RejectAndGiveUp)
419 <<
": GIM_CheckLeafOperandPredicate(MIs[" << InsnID
420 <<
"]->getOperand(" <<
OpIdx
421 <<
"), Predicate=" <<
Predicate <<
")\n");
422 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
424 "Expected register operand");
429 if (handleReject() == RejectAndGiveUp)
439 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
440 << InsnID <<
"])\n");
441 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
444 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
445 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
446 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
450 if (handleReject() == RejectAndGiveUp)
455 if (handleReject() == RejectAndGiveUp)
469 <<
": GIM_CheckSimplePredicate(Predicate="
473 if (handleReject() == RejectAndGiveUp)
483 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
484 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
485 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
489 if (handleReject() == RejectAndGiveUp)
497 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
501 assert(
MI &&
"Used insn before defined");
502 assert(
MI->getNumDefs() > 0 &&
"No defs");
503 const Register Res =
MI->getOperand(0).getReg();
505 if (!
MRI.use_nodbg_empty(Res)) {
506 if (handleReject() == RejectAndGiveUp)
515 dbgs() << CurrentIdx <<
": GIM_CheckHasOneUse(MIs["
519 assert(
MI &&
"Used insn before defined");
520 assert(
MI->getNumDefs() > 0 &&
"No defs");
521 const Register Res =
MI->getOperand(0).getReg();
523 if (!
MRI.hasOneNonDBGUse(Res)) {
524 if (handleReject() == RejectAndGiveUp)
533 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
534 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
535 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
536 if (!State.
MIs[InsnID]->hasOneMemOperand())
537 if (handleReject() == RejectAndGiveUp)
540 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
541 if (MMO->getMergedOrdering() != Ordering)
542 if (handleReject() == RejectAndGiveUp)
551 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
552 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
553 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
554 if (!State.
MIs[InsnID]->hasOneMemOperand())
555 if (handleReject() == RejectAndGiveUp)
558 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
560 if (handleReject() == RejectAndGiveUp)
569 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
570 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
571 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
572 if (!State.
MIs[InsnID]->hasOneMemOperand())
573 if (handleReject() == RejectAndGiveUp)
576 for (
const auto &MMO : State.
MIs[InsnID]->memoperands())
578 if (handleReject() == RejectAndGiveUp)
586 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
588 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
589 if (handleReject() == RejectAndGiveUp)
596 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
599 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
603 for (
unsigned I = 0;
I != NumAddrSpace; ++
I) {
606 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
607 << AddrSpace <<
'\n');
609 if (AddrSpace == MMOAddrSpace) {
615 CurrentIdx = LastIdx;
616 if (!
Success && handleReject() == RejectAndGiveUp)
625 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
627 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
628 if (handleReject() == RejectAndGiveUp)
634 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
636 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
637 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
638 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
651 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
652 << InsnID <<
"]->memoperands() + " << MMOIdx
653 <<
", Size=" <<
Size <<
")\n");
654 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
656 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
657 if (handleReject() == RejectAndGiveUp)
663 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
666 <<
" bytes vs " <<
Size
669 if (handleReject() == RejectAndGiveUp)
682 TgtExecutor::getName(),
683 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
688 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
689 <<
", OpIdx=" <<
OpIdx <<
")\n");
690 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
695 dbgs() << CurrentIdx <<
": Not a register\n");
696 if (handleReject() == RejectAndGiveUp)
701 if (State.
MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
702 if (handleReject() == RejectAndGiveUp)
708 *(State.
MIs[InsnID]->memoperands_begin() + MMOIdx);
713 if (handleReject() == RejectAndGiveUp)
717 if (handleReject() == RejectAndGiveUp)
721 if (handleReject() == RejectAndGiveUp)
732 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
733 <<
"]->getOperand(" <<
OpIdx
734 <<
"), TypeID=" <<
TypeID <<
")\n");
735 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
738 if (handleReject() == RejectAndGiveUp)
749 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
750 << InsnID <<
"]->getOperand(" <<
OpIdx
751 <<
"), SizeInBits=" << SizeInBits <<
")\n");
752 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
757 if (SizeInBits == 0) {
763 assert(SizeInBits != 0 &&
"Pointer size must be known");
767 if (handleReject() == RejectAndGiveUp)
769 }
else if (handleReject() == RejectAndGiveUp)
780 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
781 << InsnID <<
"]->getOperand(" <<
OpIdx
782 <<
"), StoreIdx=" << StoreIdx <<
")\n");
783 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
791 int TypeIdx = readS8();
794 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
795 << InsnID <<
"]->getOperand(" <<
OpIdx
796 <<
"), TypeIdx=" << TypeIdx <<
")\n");
797 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
798 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
800 TypeIdx = 1 - TypeIdx;
801 const auto &
Op = State.
MIs[InsnID]->getOperand(
OpIdx);
815 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
816 << InsnID <<
"]->getOperand(" <<
OpIdx
817 <<
"), RCEnum=" << RCEnum <<
")\n");
818 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
824 if (handleReject() == RejectAndGiveUp)
834 uint16_t ComplexPredicateID = readU16();
836 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
837 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
838 <<
"]->getOperand(" <<
OpIdx
839 <<
"), ComplexPredicateID=" << ComplexPredicateID
841 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
845 State.
MIs[InsnID]->getOperand(
OpIdx));
848 else if (handleReject() == RejectAndGiveUp)
861 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
862 << InsnID <<
"]->getOperand(" <<
OpIdx
863 <<
"), Value=" <<
Value <<
")\n");
864 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
872 if (handleReject() == RejectAndGiveUp)
879 if (handleReject() == RejectAndGiveUp)
882 }
else if (handleReject() == RejectAndGiveUp)
891 int64_t
Value = readU64();
893 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
894 << InsnID <<
"]->getOperand(" <<
OpIdx
895 <<
"), Value=" <<
Value <<
")\n");
896 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
904 if (handleReject() == RejectAndGiveUp)
915 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
916 << InsnID <<
"]->getOperand(" <<
OpIdx
917 <<
"), Value=" <<
Value <<
")\n");
918 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
921 if (handleReject() == RejectAndGiveUp)
930 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
931 << InsnID <<
"]->getOperand(" <<
OpIdx
932 <<
"), Value=" <<
Value <<
")\n");
933 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
936 if (handleReject() == RejectAndGiveUp)
944 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
945 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
946 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
947 if (!State.
MIs[InsnID]->getOperand(
OpIdx).isMBB()) {
948 if (handleReject() == RejectAndGiveUp)
957 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
958 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
959 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
960 if (!State.
MIs[InsnID]->getOperand(
OpIdx).isImm()) {
961 if (handleReject() == RejectAndGiveUp)
967 uint64_t NumInsn = MatchTable[CurrentIdx++];
969 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
970 << NumInsn <<
")\n");
972 for (
unsigned K = 1,
E = NumInsn + 1; K <
E; ++K) {
974 if (handleReject() == RejectAndGiveUp)
987 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
988 << InsnID <<
"][" <<
OpIdx <<
"], MIs["
989 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
990 assert(State.
MIs[InsnID] !=
nullptr &&
"Used insn before defined");
991 assert(State.
MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
997 if (
Op.isReg() && OtherOp.
isReg()) {
1004 if (!
Op.isIdenticalTo(OtherOp)) {
1005 if (handleReject() == RejectAndGiveUp)
1017 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1018 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1019 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1021 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1022 Register New = State.
MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1024 if (handleReject() == RejectAndGiveUp)
1034 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1035 <<
"], " << Flags <<
")\n");
1036 if ((State.
MIs[InsnID]->getFlags() & Flags) != Flags) {
1037 if (handleReject() == RejectAndGiveUp)
1047 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1048 <<
"], " << Flags <<
")\n");
1049 if ((State.
MIs[InsnID]->getFlags() & Flags)) {
1050 if (handleReject() == RejectAndGiveUp)
1057 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1058 if (handleReject() == RejectAndGiveUp)
1065 if (NewInsnID >= OutMIs.
size())
1066 OutMIs.
resize(NewInsnID + 1);
1072 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1076 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1077 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1078 << NewOpcode <<
")\n");
1086 if (NewInsnID >= OutMIs.
size())
1087 OutMIs.
resize(NewInsnID + 1);
1089 OutMIs[NewInsnID] = Builder.
buildInstr(Opcode);
1091 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1092 << NewInsnID <<
"], " << Opcode <<
")\n");
1101 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1102 << TempRegID <<
"], Imm=" << Imm <<
")\n");
1113 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1114 OutMIs[NewInsnID].add(State.
MIs[OldInsnID]->getOperand(
OpIdx));
1117 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1118 <<
"], MIs[" << OldInsnID <<
"], " <<
OpIdx <<
")\n");
1126 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1132 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1133 << NewInsnID <<
"], MIs[" << OldInsnID
1134 <<
"], /*start=*/" <<
OpIdx <<
")\n");
1143 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1146 OutMIs[NewInsnID].addReg(ZeroReg);
1148 OutMIs[NewInsnID].add(MO);
1150 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1151 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1152 <<
OpIdx <<
", " << ZeroReg <<
")\n");
1161 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1162 OutMIs[NewInsnID].addReg(State.
MIs[OldInsnID]->getOperand(
OpIdx).getReg(),
1165 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1166 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1167 <<
OpIdx <<
", " << SubRegIdx <<
")\n");
1175 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1177 OutMIs[InsnID].addDef(RegNum, Flags);
1179 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1180 << InsnID <<
"], " << RegNum <<
")\n");
1187 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1190 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1191 << InsnID <<
"], " << RegNum <<
")\n");
1199 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1200 OutMIs[InsnID].addReg(RegNum, RegFlags);
1203 << CurrentIdx <<
": GIR_AddRegister(OutMIs[" << InsnID
1204 <<
"], " << RegNum <<
", " << RegFlags <<
")\n");
1210 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1213 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1214 << InsnID <<
"], " <<
Value <<
")\n");
1221 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1222 << InsnID <<
"], OpIdx=" <<
OpIdx <<
")\n");
1224 assert(
MI &&
"Modifying undefined instruction");
1225 MI->getOperand(
MI->getNumExplicitOperands() +
OpIdx).setIsDead();
1233 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1234 << InsnID <<
"], " << Flags <<
")\n");
1236 MI->setFlags(
MI->getFlags() | Flags);
1244 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1245 << InsnID <<
"], " << Flags <<
")\n");
1247 MI->setFlags(
MI->getFlags() & ~Flags);
1255 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1256 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1258 MI->setFlags(
MI->getFlags() | State.
MIs[OldInsnID]->getFlags());
1268 TempRegFlags = readU16();
1273 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1275 OutMIs[InsnID].addReg(State.
TempRegisters[TempRegID], TempRegFlags,
1278 TgtExecutor::getName(),
1279 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1280 <<
"], TempRegisters[" << TempRegID <<
"]";
1282 dbgs() <<
", " << TempRegFlags <<
")\n");
1288 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1290 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1291 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1292 OutMIs[InsnID].addImm(Imm);
1294 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1295 <<
"], " << Imm <<
")\n");
1303 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1307 OutMIs[InsnID].addCImm(
1310 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1311 <<
"], TypeID=" <<
TypeID <<
", Imm=" << Imm
1319 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1320 for (
const auto &RenderOpFn : State.
Renderers[RendererID])
1321 RenderOpFn(OutMIs[InsnID]);
1323 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1324 << InsnID <<
"], " << RendererID <<
")\n");
1331 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1332 State.
Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1334 dbgs() << CurrentIdx
1335 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1336 << InsnID <<
"], " << RendererID <<
", "
1337 << RenderOpID <<
")\n");
1346 assert(
MI &&
"Attempted to add to undefined instruction");
1348 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1350 dbgs() << CurrentIdx
1351 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1352 << InsnID <<
"], " << RendererID <<
", "
1353 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1360 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1361 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1362 "Expected G_CONSTANT");
1363 if (State.
MIs[OldInsnID]->getOperand(1).isCImm()) {
1364 OutMIs[NewInsnID].addImm(
1365 State.
MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1366 }
else if (State.
MIs[OldInsnID]->getOperand(1).isImm())
1367 OutMIs[NewInsnID].add(State.
MIs[OldInsnID]->getOperand(1));
1371 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1372 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1380 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1381 assert(State.
MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1382 "Expected G_FCONSTANT");
1383 if (State.
MIs[OldInsnID]->getOperand(1).isFPImm())
1384 OutMIs[NewInsnID].addFPImm(
1385 State.
MIs[OldInsnID]->getOperand(1).getFPImm());
1390 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1391 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1399 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1401 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1402 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1403 << RendererFnID <<
")\n");
1405 OutMIs[InsnID], *State.
MIs[OldInsnID],
1412 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1420 if (handleReject() == RejectAndGiveUp)
1429 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1432 dbgs() << CurrentIdx
1433 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1434 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1435 <<
OpIdx <<
"), " << RendererFnID <<
")\n");
1437 OutMIs[InsnID], *State.
MIs[OldInsnID],
OpIdx);
1444 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1452 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1453 << InsnID <<
"], " <<
OpIdx <<
", " << RCEnum
1463 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1467 dbgs() << CurrentIdx
1468 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1469 << InsnID <<
"])\n");
1474 uint64_t NumInsn = MatchTable[CurrentIdx++];
1475 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1478 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1480 for (
unsigned K = 0; K < NumInsn; ++K) {
1483 dbgs() <<
", MIs[" << NextID <<
"]");
1484 for (
const auto &MMO : State.
MIs[NextID]->memoperands())
1485 OutMIs[InsnID].addMemOperand(MMO);
1493 assert(
MI &&
"Attempted to erase an undefined instruction");
1495 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1496 << InsnID <<
"])\n");
1503 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1504 eraseImpl(State.
MIs[0]);
1513 MRI.createGenericVirtualRegister(getTypeFromIdx(
TypeID));
1515 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1516 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1526 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1527 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1528 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1530 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1531 Register New = State.
MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1534 MRI.replaceRegWith(Old, New);
1545 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1546 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1547 << TempRegID <<
"])\n");
1549 Register Old = State.
MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1553 MRI.replaceRegWith(Old, New);
1564 <<
": GIR_Coverage("
1571 dbgs() << CurrentIdx <<
": GIR_Done\n");
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
This file defines the SmallVector class.
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Class for arbitrary precision integers.
void setCovered(uint64_t RuleID)
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
The size in bits of the pointer representation in a given address space.
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
bool executeMatchTable(TgtExecutor &Exec, MatcherState &State, const ExecInfoTy< PredicateBitset, ComplexMatcherMemFn, CustomRendererFn > &ExecInfo, MachineIRBuilder &Builder, const uint8_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.
virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const
virtual bool testMOPredicate_MO(unsigned, const MachineOperand &, const MatcherState &State) 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
static LLVM_ATTRIBUTE_ALWAYS_INLINE uint64_t fastDecodeULEB128(const uint8_t *LLVM_ATTRIBUTE_RESTRICT MatchTable, uint64_t &CurrentIdx)
LLVM_ABI bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, const MachineRegisterInfo &MRI, bool Splat=false) const
LLVM_ABI bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const
Return true if MI can obviously be folded into IntoMI.
virtual bool runCustomAction(unsigned, const MatcherState &State, NewMIVector &OutMIs) const
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.
LLVM_ABI 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.
LLVM_ABI void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg)
All the instructions using the given register are being changed.
static LLVM_ABI 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.
TypeSize getValue() const
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.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
LLVM_ABI 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.
LocationSize getSize() const
Return the size in bytes of the memory reference.
unsigned getAddrSpace() const
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
LocationSize getSizeInBits() const
Return the size in bits of the 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.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI 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...
LLVM_ABI 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...
@ GICXXCustomAction_Invalid
LLVM_ABI 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...
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
LLVM_ABI bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
LLVM_ABI 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...
@ Success
The lock was released successfully.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ GIR_AddIntrinsicID
Adds an intrinsic ID to the specified instruction.
@ 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.
@ GIM_RootCheckType
GIM_CheckType but InsnID is omitted and defaults to zero.
@ GIM_RootCheckRegBankForClass
GIM_CheckRegBankForClass but InsnID is omitted and defaults to zero.
@ 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.
@ GIR_RootConstrainSelectedInstOperands
GIR_ConstrainSelectedInstOperands but InsnID is omitted and defaults to zero.
@ 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.
@ 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
Checks if the matched instructions numbered [1, 1+N) can be folded into the root (inst 0).
@ 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_AddSimpleTempRegister
Add a temporary register to the specified instruction without setting any flags.
@ 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.
@ GIR_CopyRemaining
Copies all operand starting from OpIdx in OldInsnID into the new instruction NewInsnID.
@ 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.
@ GIR_AddImm8
Add signed 8 bit immediate to the specified instruction.
@ GIM_CheckIsSameOperandIgnoreCopies
@ GIM_CheckIsMBB
Check the specified operand is an MBB.
@ GIM_CheckNumOperandsLE
Check the instruction has a number of operands <= or >= than given number.
@ 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.
@ GIM_CheckLeafOperandPredicate
Check a leaf predicate on the specified instruction.
@ GIM_CheckHasOneUse
Check if there's one use of the first result.
@ GIR_EraseRootFromParent_Done
Combines both a GIR_EraseFromParent 0 + GIR_Done.
@ GIR_CopyMIFlags
Copy the MIFlags of a matched instruction into an output instruction.
@ GIR_DoneWithCustomAction
Calls a C++ function that concludes the current match.
@ GIR_BuildMI
Build a new instruction.
@ GIM_RecordInsn
Record the specified instruction.
@ GIM_CheckIsImm
Check the specified operand is an Imm.
@ GIR_BuildRootMI
GIR_BuildMI but InsnID is omitted and defaults to zero.
@ GIM_CheckFeatures
Check the feature bits Feature(2) - Expected features.
@ 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_CheckConstantInt8
Check the operand is a specific 8-bit signed integer.
@ 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_RootToRootCopy
GIR_Copy but with both New/OldInsnIDs omitted and defaulting to zero.
@ 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 int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
LLVM_ABI 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, Register > TempRegisters
std::vector< ComplexRendererFns::value_type > Renderers