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";
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();
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();
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)
778 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
779 << InsnID <<
"]->getOperand(" << OpIdx
780 <<
"), SizeInBits=" << SizeInBits <<
")\n");
781 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
786 if (SizeInBits == 0) {
788 const unsigned AddrSpace = Ty.getAddressSpace();
789 SizeInBits =
MF->getDataLayout().getPointerSizeInBits(AddrSpace);
792 assert(SizeInBits != 0 &&
"Pointer size must be known");
795 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
796 if (handleReject() == RejectAndGiveUp)
798 }
else if (handleReject() == RejectAndGiveUp)
809 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
810 << InsnID <<
"]->getOperand(" << OpIdx
811 <<
"), StoreIdx=" << StoreIdx <<
")\n");
812 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
813 assert(StoreIdx < State.RecordedOperands.size() &&
"Index out of range");
814 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
820 int TypeIdx = readS8();
823 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
824 << InsnID <<
"]->getOperand(" << OpIdx
825 <<
"), TypeIdx=" << TypeIdx <<
")\n");
826 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
827 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
829 TypeIdx = 1 - TypeIdx;
830 const auto &
Op = State.MIs[InsnID]->getOperand(OpIdx);
831 if (State.RecordedTypes.size() <= (
uint64_t)TypeIdx)
832 State.RecordedTypes.resize(TypeIdx + 1,
LLT());
833 State.RecordedTypes[TypeIdx] = MRI.
getType(
Op.getReg());
844 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
845 << InsnID <<
"]->getOperand(" << OpIdx
846 <<
"), RCEnum=" << RCEnum <<
")\n");
847 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
853 if (handleReject() == RejectAndGiveUp)
863 uint16_t ComplexPredicateID = readU16();
865 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
866 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
867 <<
"]->getOperand(" << OpIdx
868 <<
"), ComplexPredicateID=" << ComplexPredicateID
870 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
874 State.MIs[InsnID]->getOperand(OpIdx));
876 State.Renderers[RendererID] = std::move(*Renderer);
877 else if (handleReject() == RejectAndGiveUp)
890 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
891 << InsnID <<
"]->getOperand(" << OpIdx
892 <<
"), Value=" <<
Value <<
")\n");
893 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
900 if (Ty.getScalarSizeInBits() > 64) {
901 if (handleReject() == RejectAndGiveUp)
908 if (handleReject() == RejectAndGiveUp)
911 }
else if (handleReject() == RejectAndGiveUp)
920 int64_t
Value = readU64();
922 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
923 << InsnID <<
"]->getOperand(" << OpIdx
924 <<
"), Value=" <<
Value <<
")\n");
925 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
933 if (handleReject() == RejectAndGiveUp)
944 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
945 << InsnID <<
"]->getOperand(" << OpIdx
946 <<
"), Value=" <<
Value <<
")\n");
947 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
950 if (handleReject() == RejectAndGiveUp)
959 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
960 << InsnID <<
"]->getOperand(" << OpIdx
961 <<
"), Value=" <<
Value <<
")\n");
962 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
965 if (handleReject() == RejectAndGiveUp)
973 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
974 <<
"]->getOperand(" << OpIdx <<
"))\n");
975 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
976 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
977 if (handleReject() == RejectAndGiveUp)
986 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
987 <<
"]->getOperand(" << OpIdx <<
"))\n");
988 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
989 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
990 if (handleReject() == RejectAndGiveUp)
996 uint64_t NumInsn = MatchTable[CurrentIdx++];
998 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
999 << NumInsn <<
")\n");
1001 for (
unsigned K = 1,
E = NumInsn + 1;
K <
E; ++
K) {
1003 if (handleReject() == RejectAndGiveUp)
1016 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
1017 << InsnID <<
"][" << OpIdx <<
"], MIs["
1018 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
1019 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1020 assert(State.MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
1023 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
1026 if (
Op.isReg() && OtherOp.
isReg()) {
1033 if (!
Op.isIdenticalTo(OtherOp)) {
1034 if (handleReject() == RejectAndGiveUp)
1046 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1047 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1048 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1050 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1051 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1053 if (handleReject() == RejectAndGiveUp)
1063 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1064 <<
"], " << Flags <<
")\n");
1065 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1066 if (handleReject() == RejectAndGiveUp)
1076 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1077 <<
"], " << Flags <<
")\n");
1078 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1079 if (handleReject() == RejectAndGiveUp)
1086 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1087 if (handleReject() == RejectAndGiveUp)
1094 if (NewInsnID >= OutMIs.
size())
1095 OutMIs.
resize(NewInsnID + 1);
1096 initializeOutMIFlagState(NewInsnID + 1);
1102 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1106 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1107 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1108 << NewOpcode <<
")\n");
1116 if (NewInsnID >= OutMIs.
size())
1117 OutMIs.
resize(NewInsnID + 1);
1118 initializeOutMIFlagState(NewInsnID + 1);
1120 initializeBuilder();
1121 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1123 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1124 << NewInsnID <<
"], " << Opcode <<
")\n");
1131 initializeBuilder();
1132 Builder.buildConstant(State.TempRegisters[TempRegID],
Imm);
1134 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1135 << TempRegID <<
"], Imm=" <<
Imm <<
")\n");
1146 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1147 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
1150 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1151 <<
"], MIs[" << OldInsnID <<
"], " << OpIdx <<
")\n");
1159 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1165 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1166 << NewInsnID <<
"], MIs[" << OldInsnID
1167 <<
"], /*start=*/" << OpIdx <<
")\n");
1176 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1179 OutMIs[NewInsnID].addReg(ZeroReg);
1181 OutMIs[NewInsnID].add(MO);
1183 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1184 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1185 << OpIdx <<
", " << ZeroReg <<
")\n");
1194 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1195 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1198 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1199 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1200 << OpIdx <<
", " << SubRegIdx <<
")\n");
1208 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1210 OutMIs[InsnID].addDef(RegNum, Flags);
1212 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1213 << InsnID <<
"], " << RegNum <<
", "
1214 <<
static_cast<uint16_t>(Flags) <<
")\n");
1221 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1224 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1225 << InsnID <<
"], " << RegNum <<
")\n");
1233 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1234 OutMIs[InsnID].addReg(RegNum, RegFlags);
1236 dbgs() << CurrentIdx <<
": GIR_AddRegister(OutMIs["
1237 << InsnID <<
"], " << RegNum <<
", "
1238 <<
static_cast<uint16_t>(RegFlags) <<
")\n");
1244 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1247 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1248 << InsnID <<
"], " <<
Value <<
")\n");
1255 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1256 << InsnID <<
"], OpIdx=" << OpIdx <<
")\n");
1258 assert(
MI &&
"Modifying undefined instruction");
1259 MI->getOperand(
MI->getNumExplicitOperands() + OpIdx).setIsDead();
1267 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1268 << InsnID <<
"], " << Flags <<
")\n");
1270 assert(
MI &&
"Modifying undefined instruction");
1271 MI->setFlags(
MI->getFlags() | Flags);
1272 initializeOutMIFlagState(OutMIs.
size());
1273 OutMIFlagsToDrop[InsnID] &= ~Flags;
1281 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1282 << InsnID <<
"], " << Flags <<
")\n");
1284 assert(
MI &&
"Modifying undefined instruction");
1285 MI->setFlags(
MI->getFlags() & ~Flags);
1286 initializeOutMIFlagState(OutMIs.
size());
1287 OutMIFlagsToDrop[InsnID] |= Flags;
1295 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1296 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1298 assert(
MI &&
"Modifying undefined instruction");
1299 uint32_t Flags = State.MIs[OldInsnID]->getFlags();
1300 MI->setFlags(
MI->getFlags() | Flags);
1301 initializeOutMIFlagState(OutMIs.
size());
1302 OutMIFlagsToDrop[InsnID] &= ~Flags;
1312 TempRegFlags =
static_cast<RegState>(readU16());
1317 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1319 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1322 TgtExecutor::getName(),
1323 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1324 <<
"], TempRegisters[" << TempRegID <<
"]";
1325 if (SubReg)
dbgs() <<
'.' <<
TRI.getSubRegIndexName(SubReg);
1326 dbgs() <<
", " <<
static_cast<uint16_t>(TempRegFlags) <<
")\n");
1332 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1334 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1335 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1336 OutMIs[InsnID].addImm(
Imm);
1338 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1339 <<
"], " <<
Imm <<
")\n");
1347 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1349 unsigned Width = getTypeFromIdx(
TypeID).getScalarSizeInBits();
1351 OutMIs[InsnID].addCImm(
1354 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1355 <<
"], TypeID=" <<
TypeID <<
", Imm=" <<
Imm
1364 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1367 unsigned Width = Ty.getScalarSizeInBits();
1370 OutMIs[InsnID].addFPImm(ConstantFP::get(Ctx, APF));
1372 dbgs() << CurrentIdx <<
": GIR_AddCFPImm(OutMIs["
1373 << InsnID <<
"], TypeID=" <<
TypeID
1374 <<
", Imm=" <<
Imm <<
")\n");
1381 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1382 for (
const auto &RenderOpFn : State.Renderers[RendererID])
1383 RenderOpFn(OutMIs[InsnID]);
1385 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1386 << InsnID <<
"], " << RendererID <<
")\n");
1393 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1394 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1396 dbgs() << CurrentIdx
1397 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1398 << InsnID <<
"], " << RendererID <<
", "
1399 << RenderOpID <<
")\n");
1408 assert(
MI &&
"Attempted to add to undefined instruction");
1409 State.Renderers[RendererID][RenderOpID](
MI);
1410 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1412 dbgs() << CurrentIdx
1413 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1414 << InsnID <<
"], " << RendererID <<
", "
1415 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1422 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1423 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1424 "Expected G_CONSTANT");
1425 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1426 OutMIs[NewInsnID].addImm(
1427 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1428 }
else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1429 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1433 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1434 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1442 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1443 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1444 "Expected G_FCONSTANT");
1445 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1446 OutMIs[NewInsnID].addFPImm(
1447 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1452 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1453 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1461 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1463 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1464 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1465 << RendererFnID <<
")\n");
1467 OutMIs[InsnID], *State.MIs[OldInsnID],
1474 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1478 initializeOutMIFlagState(OutMIs.
size());
1479 for (
unsigned I = 0,
E = OutMIs.
size();
I !=
E; ++
I)
1480 OutMIFlagsToDrop[
I] &= ~OutMIs[
I]->getFlags();
1485 if (handleReject() == RejectAndGiveUp)
1494 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1497 dbgs() << CurrentIdx
1498 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1499 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1500 << OpIdx <<
"), " << RendererFnID <<
")\n");
1502 OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx);
1509 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1517 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1518 << InsnID <<
"], " << OpIdx <<
", " << RCEnum
1528 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1532 dbgs() << CurrentIdx
1533 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1534 << InsnID <<
"])\n");
1539 uint64_t NumInsn = MatchTable[CurrentIdx++];
1540 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1543 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1545 for (
unsigned K = 0;
K < NumInsn; ++
K) {
1548 dbgs() <<
", MIs[" << NextID <<
"]");
1549 for (
const auto &MMO : State.MIs[NextID]->memoperands())
1550 OutMIs[InsnID].addMemOperand(MMO);
1558 assert(
MI &&
"Attempted to erase an undefined instruction");
1560 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1561 << InsnID <<
"])\n");
1568 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1569 eraseImpl(State.MIs[0]);
1577 State.TempRegisters[TempRegID] =
1580 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1581 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1591 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1592 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1593 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1595 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1596 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1610 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1611 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1612 << TempRegID <<
"])\n");
1614 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1615 Register New = State.TempRegisters[TempRegID];
1629 <<
": GIR_Coverage("
1636 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
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)
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 LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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_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_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_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_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