15#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
16#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
42template <
class TgtExecutor,
class PredicateBitset,
class ComplexMatcherMemFn,
43 class CustomRendererFn>
51 const PredicateBitset &AvailableFeatures,
60 bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
62 const uint32_t RootFlags = State.MIs[0]->getFlags();
66 bool BuilderInitialized =
false;
67 const auto initializeBuilder = [&]() {
68 if (BuilderInitialized)
72 Builder.setInstrAndDebugLoc(*State.MIs[0]);
73 BuilderInitialized =
true;
75 const auto initializeOutMIFlagState = [&](
unsigned NumOutMIs) {
76 if (NumOutMIs > OutMIFlagsToDrop.
size())
77 OutMIFlagsToDrop.
resize(NumOutMIs, RootFlagsToDrop);
80 enum RejectAction { RejectAndGiveUp, RejectAndResume };
81 auto handleReject = [&]() -> RejectAction {
83 dbgs() << CurrentIdx <<
": Rejected\n");
84 if (OnFailResumeAt.
empty())
85 return RejectAndGiveUp;
88 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
89 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
90 return RejectAndResume;
93 const auto propagateFlags = [&]() {
94 initializeOutMIFlagState(OutMIs.
size());
95 for (
unsigned I = 0,
E = OutMIs.
size();
I !=
E; ++
I) {
113 const auto getTypeFromIdx = [&](int64_t Idx) ->
LLT {
116 return State.RecordedTypes[1 - Idx];
119 const auto readULEB = [&]() {
128 const auto readS8 = [&]() {
return (int8_t)MatchTable[CurrentIdx++]; };
130 const auto readU16 = [&]() {
136 const auto readU32 = [&]() {
142 const auto readU64 = [&]() {
152 if (Builder.getInsertPt() ==
MI)
153 Builder.setInsertPt(*
MI->getParent(), ++
MI->getIterator());
156 MI->eraseFromParent();
160 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
161 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
162 switch (MatcherOpcode) {
165 dbgs() << CurrentIdx <<
": Begin try-block\n");
172 unsigned OnFail = readU32();
173 uint16_t ExpectedBitsetID = readU16();
176 <<
": GIM_Try_CheckFeatures(ExpectedBitsetID="
177 << ExpectedBitsetID <<
")\n");
178 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
182 <<
": Features do not match, rejected\n");
197 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
202 dbgs() << CurrentIdx <<
": Not a register\n");
203 if (handleReject() == RejectAndGiveUp)
209 dbgs() << CurrentIdx <<
": Is a physical register\n");
210 if (handleReject() == RejectAndGiveUp)
221 if ((
size_t)NewInsnID < State.MIs.size())
222 State.MIs[NewInsnID] = NewMI;
224 assert((
size_t)NewInsnID == State.MIs.size() &&
225 "Expected to store MIs in order");
226 State.MIs.push_back(NewMI);
229 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
230 <<
"] = GIM_RecordInsn(" << InsnID <<
", " << OpIdx
240 Expected1 = readU16();
242 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
243 unsigned Opcode = State.MIs[InsnID]->getOpcode();
246 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
247 <<
"], ExpectedOpcode=" << Expected0;
249 dbgs() <<
" || " << Expected1;
250 dbgs() <<
") // Got=" << Opcode <<
"\n";
253 if (Opcode != Expected0 && Opcode != Expected1) {
254 if (handleReject() == RejectAndGiveUp)
265 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
266 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
269 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
270 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
271 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
273 if (Opcode < LowerBound || UpperBound <= Opcode) {
277 const auto EntryIdx = (Opcode - LowerBound);
298 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
302 dbgs() << CurrentIdx <<
": GIM_SwitchType" << (IsShape ?
"Shape" :
"")
303 <<
"(MIs[" << InsnID <<
"]->getOperand(" << OpIdx <<
"), ["
304 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
305 <<
", JumpTable...) // Got=";
307 dbgs() <<
"Not a VReg\n";
318 Ty = Ty.changeElementType(
LLT::scalar(Ty.getScalarSizeInBits()));
320 const auto TyI = ExecInfo.
TypeIDMap.
find(Ty.getUniqueRAWLLTData());
325 const int64_t
TypeID = TyI->second;
330 const auto NumEntry = (
TypeID - LowerBound);
348 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands"
349 << (IsLE ?
"LE" :
"GE") <<
"(MIs[" << InsnID
350 <<
"], Expected=" <<
Expected <<
")\n");
351 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
352 const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
354 if (handleReject() == RejectAndGiveUp)
363 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
364 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
365 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
366 if (State.MIs[InsnID]->getNumOperands() !=
Expected) {
367 if (handleReject() == RejectAndGiveUp)
379 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
380 << InsnID <<
"]->getOperand(" << OpIdx
381 <<
"), Predicate=" <<
Predicate <<
")\n");
382 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
383 assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
384 State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
385 "Expected immediate operand");
388 if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
389 Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
390 else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
391 Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
396 if (handleReject() == RejectAndGiveUp)
405 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
406 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
407 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
408 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
409 "Expected G_CONSTANT");
411 if (!State.MIs[InsnID]->getOperand(1).isCImm())
415 State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
417 if (handleReject() == RejectAndGiveUp)
426 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
427 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
428 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
429 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
430 "Expected G_FCONSTANT");
431 assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
432 "Expected FPImm operand");
435 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
438 if (handleReject() == RejectAndGiveUp)
448 <<
": GIM_CheckLeafOperandPredicate(MIs[" << InsnID
449 <<
"]->getOperand(" << OpIdx
450 <<
"), Predicate=" <<
Predicate <<
")\n");
451 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
452 assert(State.MIs[InsnID]->getOperand(OpIdx).isReg() &&
453 "Expected register operand");
458 if (handleReject() == RejectAndGiveUp)
468 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
469 << InsnID <<
"])\n");
470 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
473 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
474 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
475 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
479 if (handleReject() == RejectAndGiveUp)
484 if (handleReject() == RejectAndGiveUp)
498 <<
": GIM_CheckSimplePredicate(Predicate="
502 if (handleReject() == RejectAndGiveUp)
512 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
513 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
514 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
518 if (handleReject() == RejectAndGiveUp)
526 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
530 assert(
MI &&
"Used insn before defined");
531 assert(
MI->getNumDefs() > 0 &&
"No defs");
532 const Register Res =
MI->getOperand(0).getReg();
534 if (!
MRI.use_nodbg_empty(Res)) {
535 if (handleReject() == RejectAndGiveUp)
544 dbgs() << CurrentIdx <<
": GIM_CheckHasOneUse(MIs["
548 assert(
MI &&
"Used insn before defined");
549 assert(
MI->getNumDefs() > 0 &&
"No defs");
550 const Register Res =
MI->getOperand(0).getReg();
552 if (!
MRI.hasOneNonDBGUse(Res)) {
553 if (handleReject() == RejectAndGiveUp)
562 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
563 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
564 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
565 if (!State.MIs[InsnID]->hasOneMemOperand())
566 if (handleReject() == RejectAndGiveUp)
569 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
570 if (MMO->getMergedOrdering() != Ordering)
571 if (handleReject() == RejectAndGiveUp)
580 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
581 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
582 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
583 if (!State.MIs[InsnID]->hasOneMemOperand())
584 if (handleReject() == RejectAndGiveUp)
587 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
589 if (handleReject() == RejectAndGiveUp)
598 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
599 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
600 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
601 if (!State.MIs[InsnID]->hasOneMemOperand())
602 if (handleReject() == RejectAndGiveUp)
605 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
607 if (handleReject() == RejectAndGiveUp)
615 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
617 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
618 if (handleReject() == RejectAndGiveUp)
625 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
628 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
632 for (
unsigned I = 0;
I != NumAddrSpace; ++
I) {
635 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
636 << AddrSpace <<
'\n');
638 if (AddrSpace == MMOAddrSpace) {
644 CurrentIdx = LastIdx;
645 if (!
Success && handleReject() == RejectAndGiveUp)
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);
665 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
666 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
667 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
680 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
681 << InsnID <<
"]->memoperands() + " << MMOIdx
682 <<
", Size=" <<
Size <<
")\n");
683 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
685 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
686 if (handleReject() == RejectAndGiveUp)
692 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
695 <<
" bytes vs " <<
Size
698 if (handleReject() == RejectAndGiveUp)
711 TgtExecutor::getName(),
712 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
717 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
718 <<
", OpIdx=" << OpIdx <<
")\n");
719 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
724 dbgs() << CurrentIdx <<
": Not a register\n");
725 if (handleReject() == RejectAndGiveUp)
730 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
731 if (handleReject() == RejectAndGiveUp)
737 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
742 if (handleReject() == RejectAndGiveUp)
746 if (handleReject() == RejectAndGiveUp)
750 if (handleReject() == RejectAndGiveUp)
761 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
762 <<
"]->getOperand(" << OpIdx
763 <<
"), TypeID=" <<
TypeID <<
")\n");
764 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
767 if (handleReject() == RejectAndGiveUp)
777 unsigned HwModeIdx = MatchTable[CurrentIdx++];
779 dbgs() << CurrentIdx <<
": GIM_CheckTypeByHwMode(MIs["
780 << InsnID <<
"]->getOperand(" << OpIdx
781 <<
"), Idx=" << HwModeIdx <<
")\n");
782 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
786 if (handleReject() == RejectAndGiveUp)
801 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny"
802 << (IsByHwMode ?
"ByHwMode" :
"") <<
"(MIs["
803 << InsnID <<
"]->getOperand(" << OpIdx
804 <<
"), SizeInBits=" << SizeInBits <<
")\n");
805 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
810 if (SizeInBits == 0) {
812 const unsigned AddrSpace = Ty.getAddressSpace();
813 SizeInBits =
MF->getDataLayout().getPointerSizeInBits(AddrSpace);
816 assert(SizeInBits != 0 &&
"Pointer size must be known");
819 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
820 if (handleReject() == RejectAndGiveUp)
822 }
else if (handleReject() == RejectAndGiveUp)
833 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
834 << InsnID <<
"]->getOperand(" << OpIdx
835 <<
"), StoreIdx=" << StoreIdx <<
")\n");
836 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
837 assert(StoreIdx < State.RecordedOperands.size() &&
"Index out of range");
838 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
844 int TypeIdx = readS8();
847 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
848 << InsnID <<
"]->getOperand(" << OpIdx
849 <<
"), TypeIdx=" << TypeIdx <<
")\n");
850 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
851 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
853 TypeIdx = 1 - TypeIdx;
854 const auto &
Op = State.MIs[InsnID]->getOperand(OpIdx);
855 if (State.RecordedTypes.size() <= (
uint64_t)TypeIdx)
856 State.RecordedTypes.resize(TypeIdx + 1,
LLT());
857 State.RecordedTypes[TypeIdx] =
MRI.getType(
Op.getReg());
868 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
869 << InsnID <<
"]->getOperand(" << OpIdx
870 <<
"), RCEnum=" << RCEnum <<
")\n");
871 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
877 if (handleReject() == RejectAndGiveUp)
887 uint16_t ComplexPredicateID = readU16();
889 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
890 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
891 <<
"]->getOperand(" << OpIdx
892 <<
"), ComplexPredicateID=" << ComplexPredicateID
894 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
898 State.MIs[InsnID]->getOperand(OpIdx));
900 State.Renderers[RendererID] = std::move(*Renderer);
901 else if (handleReject() == RejectAndGiveUp)
914 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
915 << InsnID <<
"]->getOperand(" << OpIdx
916 <<
"), Value=" <<
Value <<
")\n");
917 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
924 if (Ty.getScalarSizeInBits() > 64) {
925 if (handleReject() == RejectAndGiveUp)
932 if (handleReject() == RejectAndGiveUp)
935 }
else if (handleReject() == RejectAndGiveUp)
944 int64_t
Value = readU64();
946 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
947 << InsnID <<
"]->getOperand(" << OpIdx
948 <<
"), Value=" <<
Value <<
")\n");
949 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
957 if (handleReject() == RejectAndGiveUp)
968 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
969 << InsnID <<
"]->getOperand(" << OpIdx
970 <<
"), Value=" <<
Value <<
")\n");
971 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
974 if (handleReject() == RejectAndGiveUp)
983 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
984 << InsnID <<
"]->getOperand(" << OpIdx
985 <<
"), Value=" <<
Value <<
")\n");
986 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
989 if (handleReject() == RejectAndGiveUp)
997 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
998 <<
"]->getOperand(" << OpIdx <<
"))\n");
999 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1000 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
1001 if (handleReject() == RejectAndGiveUp)
1010 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
1011 <<
"]->getOperand(" << OpIdx <<
"))\n");
1012 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1013 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
1014 if (handleReject() == RejectAndGiveUp)
1020 uint64_t NumInsn = MatchTable[CurrentIdx++];
1022 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
1023 << NumInsn <<
")\n");
1025 for (
unsigned K = 1,
E = NumInsn + 1;
K <
E; ++
K) {
1027 if (handleReject() == RejectAndGiveUp)
1040 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
1041 << InsnID <<
"][" << OpIdx <<
"], MIs["
1042 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
1043 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1044 assert(State.MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
1047 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
1050 if (
Op.isReg() && OtherOp.
isReg()) {
1057 if (!
Op.isIdenticalTo(OtherOp)) {
1058 if (handleReject() == RejectAndGiveUp)
1070 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1071 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1072 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1074 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1075 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1077 if (handleReject() == RejectAndGiveUp)
1087 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1088 <<
"], " << Flags <<
")\n");
1089 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1090 if (handleReject() == RejectAndGiveUp)
1100 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1101 <<
"], " << Flags <<
")\n");
1102 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1103 if (handleReject() == RejectAndGiveUp)
1110 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1111 if (handleReject() == RejectAndGiveUp)
1118 if (NewInsnID >= OutMIs.
size())
1119 OutMIs.
resize(NewInsnID + 1);
1120 initializeOutMIFlagState(NewInsnID + 1);
1126 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1130 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1131 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1132 << NewOpcode <<
")\n");
1140 if (NewInsnID >= OutMIs.
size())
1141 OutMIs.
resize(NewInsnID + 1);
1142 initializeOutMIFlagState(NewInsnID + 1);
1144 initializeBuilder();
1145 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1147 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1148 << NewInsnID <<
"], " << Opcode <<
")\n");
1155 initializeBuilder();
1156 Builder.buildConstant(State.TempRegisters[TempRegID],
Imm);
1158 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1159 << TempRegID <<
"], Imm=" <<
Imm <<
")\n");
1170 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1171 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
1174 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1175 <<
"], MIs[" << OldInsnID <<
"], " << OpIdx <<
")\n");
1183 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1189 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1190 << NewInsnID <<
"], MIs[" << OldInsnID
1191 <<
"], /*start=*/" << OpIdx <<
")\n");
1200 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1203 OutMIs[NewInsnID].addReg(ZeroReg);
1205 OutMIs[NewInsnID].add(MO);
1207 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1208 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1209 << OpIdx <<
", " << ZeroReg <<
")\n");
1218 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1219 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1222 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1223 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1224 << OpIdx <<
", " << SubRegIdx <<
")\n");
1232 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1234 OutMIs[InsnID].addDef(RegNum, Flags);
1236 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1237 << InsnID <<
"], " << RegNum <<
", "
1238 <<
static_cast<uint16_t>(Flags) <<
")\n");
1245 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1248 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1249 << InsnID <<
"], " << RegNum <<
")\n");
1257 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1258 OutMIs[InsnID].addReg(RegNum, RegFlags);
1260 dbgs() << CurrentIdx <<
": GIR_AddRegister(OutMIs["
1261 << InsnID <<
"], " << RegNum <<
", "
1262 <<
static_cast<uint16_t>(RegFlags) <<
")\n");
1268 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1271 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1272 << InsnID <<
"], " <<
Value <<
")\n");
1279 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1280 << InsnID <<
"], OpIdx=" << OpIdx <<
")\n");
1282 assert(
MI &&
"Modifying undefined instruction");
1283 MI->getOperand(
MI->getNumExplicitOperands() + OpIdx).setIsDead();
1291 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1292 << InsnID <<
"], " << Flags <<
")\n");
1294 assert(
MI &&
"Modifying undefined instruction");
1295 MI->setFlags(
MI->getFlags() | Flags);
1296 initializeOutMIFlagState(OutMIs.
size());
1297 OutMIFlagsToDrop[InsnID] &= ~Flags;
1305 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1306 << InsnID <<
"], " << Flags <<
")\n");
1308 assert(
MI &&
"Modifying undefined instruction");
1309 MI->setFlags(
MI->getFlags() & ~Flags);
1310 initializeOutMIFlagState(OutMIs.
size());
1311 OutMIFlagsToDrop[InsnID] |= Flags;
1319 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1320 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1322 assert(
MI &&
"Modifying undefined instruction");
1323 uint32_t Flags = State.MIs[OldInsnID]->getFlags();
1324 MI->setFlags(
MI->getFlags() | Flags);
1325 initializeOutMIFlagState(OutMIs.
size());
1326 OutMIFlagsToDrop[InsnID] &= ~Flags;
1336 TempRegFlags =
static_cast<RegState>(readU16());
1341 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1343 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1346 TgtExecutor::getName(),
1347 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1348 <<
"], TempRegisters[" << TempRegID <<
"]";
1349 if (SubReg)
dbgs() <<
'.' <<
TRI.getSubRegIndexName(SubReg);
1350 dbgs() <<
", " <<
static_cast<uint16_t>(TempRegFlags) <<
")\n");
1356 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1358 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1359 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1360 OutMIs[InsnID].addImm(
Imm);
1362 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1363 <<
"], " <<
Imm <<
")\n");
1371 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1373 unsigned Width = getTypeFromIdx(
TypeID).getScalarSizeInBits();
1375 OutMIs[InsnID].addCImm(
1378 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1379 <<
"], TypeID=" <<
TypeID <<
", Imm=" <<
Imm
1388 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1391 unsigned Width = Ty.getScalarSizeInBits();
1394 OutMIs[InsnID].addFPImm(ConstantFP::get(Ctx, APF));
1396 dbgs() << CurrentIdx <<
": GIR_AddCFPImm(OutMIs["
1397 << InsnID <<
"], TypeID=" <<
TypeID
1398 <<
", Imm=" <<
Imm <<
")\n");
1405 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1406 for (
const auto &RenderOpFn : State.Renderers[RendererID])
1407 RenderOpFn(OutMIs[InsnID]);
1409 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1410 << InsnID <<
"], " << RendererID <<
")\n");
1417 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1418 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1420 dbgs() << CurrentIdx
1421 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1422 << InsnID <<
"], " << RendererID <<
", "
1423 << RenderOpID <<
")\n");
1432 assert(
MI &&
"Attempted to add to undefined instruction");
1433 State.Renderers[RendererID][RenderOpID](
MI);
1434 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1436 dbgs() << CurrentIdx
1437 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1438 << InsnID <<
"], " << RendererID <<
", "
1439 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1446 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1447 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1448 "Expected G_CONSTANT");
1449 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1450 OutMIs[NewInsnID].addImm(
1451 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1452 }
else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1453 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1457 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1458 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1466 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1467 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1468 "Expected G_FCONSTANT");
1469 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1470 OutMIs[NewInsnID].addFPImm(
1471 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1476 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1477 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1485 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1487 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1488 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1489 << RendererFnID <<
")\n");
1491 OutMIs[InsnID], *State.MIs[OldInsnID],
1498 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1502 initializeOutMIFlagState(OutMIs.
size());
1503 for (
unsigned I = 0,
E = OutMIs.
size();
I !=
E; ++
I)
1504 OutMIFlagsToDrop[
I] &= ~OutMIs[
I]->getFlags();
1509 if (handleReject() == RejectAndGiveUp)
1518 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1521 dbgs() << CurrentIdx
1522 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1523 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1524 << OpIdx <<
"), " << RendererFnID <<
")\n");
1526 OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx);
1533 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1541 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1542 << InsnID <<
"], " << OpIdx <<
", " << RCEnum
1552 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1556 dbgs() << CurrentIdx
1557 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1558 << InsnID <<
"])\n");
1563 uint64_t NumInsn = MatchTable[CurrentIdx++];
1564 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1567 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1569 for (
unsigned K = 0;
K < NumInsn; ++
K) {
1572 dbgs() <<
", MIs[" << NextID <<
"]");
1573 for (
const auto &MMO : State.MIs[NextID]->memoperands())
1574 OutMIs[InsnID].addMemOperand(MMO);
1582 assert(
MI &&
"Attempted to erase an undefined instruction");
1584 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1585 << InsnID <<
"])\n");
1592 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1593 eraseImpl(State.MIs[0]);
1601 State.TempRegisters[TempRegID] =
1602 MRI.createGenericVirtualRegister(getTypeFromIdx(
TypeID));
1604 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1605 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1610 unsigned HwModeIdx = MatchTable[CurrentIdx++];
1612 State.TempRegisters[TempRegID] =
1615 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1616 <<
"] = GIR_MakeTempRegByHwMode(" << HwModeIdx
1627 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1628 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1629 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1631 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1632 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1635 MRI.replaceRegWith(Old, New);
1646 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1647 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1648 << TempRegID <<
"])\n");
1650 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1651 Register New = State.TempRegisters[TempRegID];
1654 MRI.replaceRegWith(Old, New);
1665 <<
": GIR_Coverage("
1672 dbgs() << CurrentIdx <<
": GIR_Done\n");
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...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
MachineRegisterInfo & MRI
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.
static uint32_t getFlags(const Symbol *Sym)
Class for arbitrary precision integers.
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...
iterator find(const_arg_type_t< KeyT > Val)
Tagged union holding either a T or a Error.
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 uint32_t getRootFlagsToDrop() 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
SmallVector< MachineInstrBuilder, 4 > NewMIVector
static Ty readBytesAs(const uint8_t *MatchTable)
virtual LLT getLLTForHwMode(unsigned Index) 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.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
This is an important class for using LLVM in a threaded context.
TypeSize getValue() const
Helper class to build MachineInstr.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
bool mayRaiseFPException() const
Return true if this instruction could possibly raise a floating-point exception.
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.
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...
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
LLVM_ABI const llvm::fltSemantics & getFltSemanticForLLT(LLT Ty)
Get the appropriate floating point arithmetic semantic based on the bit size of the given scalar LLT.
LLVM_ABI void 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.
DWARFExpression::Operation Op
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.
@ GICXXCustomAction_Invalid
@ 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_CheckTypeByHwMode
Check the type for the specified operand where the type depends on the HwMode.
@ GIM_CheckMemorySizeEqualTo
Check the size of the memory access for the given machine memory operand.
@ GIR_MakeTempRegByHwMode
Create a new temporary register that's not constrained where the type depends on the HwMode.
@ 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_AddCFPImm
Add a floating-point immediate 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_RootCheckTypeByHwMode
GIM_CheckTypeByHwMode but InsnID is omitted and defaults to zero.
@ 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_CheckPointerToAnyByHwMode
Check the type of a pointer to any address space where the size of the pointer depends on the HwMode.
@ 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_Try_CheckFeatures
GIM_Try only if the feature bits match.
@ 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_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.
@ GIM_SwitchTypeShape
Switch over the shape of an LLT on the specified instruction operand.
@ 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.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
MCRegisterClass TargetRegisterClass
SmallDenseMap< uint64_t, unsigned, 64 > TypeIDMap
const CustomRendererFn * CustomRenderers
const ComplexMatcherMemFn * ComplexPredicates
const PredicateBitset * FeatureBitsets