15#ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
16#define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
41template <
class TgtExecutor,
class PredicateBitset,
class ComplexMatcherMemFn,
42 class CustomRendererFn>
50 const PredicateBitset &AvailableFeatures,
59 bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
61 const uint32_t Flags = State.MIs[0]->getFlags();
63 enum RejectAction { RejectAndGiveUp, RejectAndResume };
64 auto handleReject = [&]() -> RejectAction {
66 dbgs() << CurrentIdx <<
": Rejected\n");
67 if (OnFailResumeAt.
empty())
68 return RejectAndGiveUp;
71 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
72 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
73 return RejectAndResume;
76 const auto propagateFlags = [&]() {
77 for (
auto MIB : OutMIs) {
80 uint32_t MIBFlags = Flags | MIB.getInstr()->getFlags();
81 if (NoFPException && MIB->mayRaiseFPException())
85 MIB.setMIFlags(MIBFlags);
93 const auto getTypeFromIdx = [&](int64_t Idx) ->
LLT {
96 return State.RecordedTypes[1 - Idx];
99 const auto readULEB = [&]() {
108 const auto readS8 = [&]() {
return (int8_t)MatchTable[CurrentIdx++]; };
110 const auto readU16 = [&]() {
116 const auto readU32 = [&]() {
122 const auto readU64 = [&]() {
131 if (Builder.getInsertPt() ==
MI)
132 Builder.setInsertPt(*
MI->getParent(), ++
MI->getIterator());
135 MI->eraseFromParent();
139 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
140 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
141 switch (MatcherOpcode) {
144 dbgs() << CurrentIdx <<
": Begin try-block\n");
157 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
162 dbgs() << CurrentIdx <<
": Not a register\n");
163 if (handleReject() == RejectAndGiveUp)
169 dbgs() << CurrentIdx <<
": Is a physical register\n");
170 if (handleReject() == RejectAndGiveUp)
181 if ((
size_t)NewInsnID < State.MIs.size())
182 State.MIs[NewInsnID] = NewMI;
184 assert((
size_t)NewInsnID == State.MIs.size() &&
185 "Expected to store MIs in order");
186 State.MIs.push_back(NewMI);
189 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
190 <<
"] = GIM_RecordInsn(" << InsnID <<
", " <<
OpIdx
196 uint16_t ExpectedBitsetID = readU16();
199 <<
": GIM_CheckFeatures(ExpectedBitsetID="
200 << ExpectedBitsetID <<
")\n");
201 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
203 if (handleReject() == RejectAndGiveUp)
214 Expected1 = readU16();
216 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
217 unsigned Opcode = State.MIs[InsnID]->getOpcode();
220 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
221 <<
"], ExpectedOpcode=" << Expected0;
223 dbgs() <<
" || " << Expected1;
224 dbgs() <<
") // Got=" << Opcode <<
"\n";
227 if (Opcode != Expected0 && Opcode != Expected1) {
228 if (handleReject() == RejectAndGiveUp)
239 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
240 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
243 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
244 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
245 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
247 if (Opcode < LowerBound || UpperBound <= Opcode) {
251 const auto EntryIdx = (Opcode - LowerBound);
270 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
274 dbgs() << CurrentIdx <<
": GIM_SwitchType(MIs[" << InsnID
275 <<
"]->getOperand(" <<
OpIdx <<
"), [" << LowerBound <<
", "
276 << UpperBound <<
"), Default=" <<
Default
277 <<
", JumpTable...) // Got=";
279 dbgs() <<
"Not a VReg\n";
288 const auto TyI = ExecInfo.
TypeIDMap.find(Ty);
293 const int64_t
TypeID = TyI->second;
298 const auto NumEntry = (
TypeID - LowerBound);
316 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands"
317 << (IsLE ?
"LE" :
"GE") <<
"(MIs[" << InsnID
318 <<
"], Expected=" <<
Expected <<
")\n");
319 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
320 const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
322 if (handleReject() == RejectAndGiveUp)
331 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
332 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
333 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
334 if (State.MIs[InsnID]->getNumOperands() !=
Expected) {
335 if (handleReject() == RejectAndGiveUp)
347 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
348 << InsnID <<
"]->getOperand(" <<
OpIdx
349 <<
"), Predicate=" <<
Predicate <<
")\n");
350 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
351 assert((State.MIs[InsnID]->getOperand(
OpIdx).isImm() ||
352 State.MIs[InsnID]->getOperand(
OpIdx).isCImm()) &&
353 "Expected immediate operand");
356 if (State.MIs[InsnID]->getOperand(
OpIdx).isCImm())
357 Value = State.MIs[InsnID]->getOperand(
OpIdx).getCImm()->getSExtValue();
358 else if (State.MIs[InsnID]->getOperand(
OpIdx).isImm())
359 Value = State.MIs[InsnID]->getOperand(
OpIdx).getImm();
364 if (handleReject() == RejectAndGiveUp)
373 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
374 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
375 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
376 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
377 "Expected G_CONSTANT");
379 if (!State.MIs[InsnID]->getOperand(1).isCImm())
383 State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
385 if (handleReject() == RejectAndGiveUp)
394 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
395 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
396 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
397 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
398 "Expected G_FCONSTANT");
399 assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
400 "Expected FPImm operand");
403 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
406 if (handleReject() == RejectAndGiveUp)
416 <<
": GIM_CheckLeafOperandPredicate(MIs[" << InsnID
417 <<
"]->getOperand(" <<
OpIdx
418 <<
"), Predicate=" <<
Predicate <<
")\n");
419 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
420 assert(State.MIs[InsnID]->getOperand(
OpIdx).isReg() &&
421 "Expected register operand");
426 if (handleReject() == RejectAndGiveUp)
436 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
437 << InsnID <<
"])\n");
438 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
441 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
442 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
443 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
447 if (handleReject() == RejectAndGiveUp)
452 if (handleReject() == RejectAndGiveUp)
466 <<
": GIM_CheckSimplePredicate(Predicate="
470 if (handleReject() == RejectAndGiveUp)
480 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
481 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
482 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
486 if (handleReject() == RejectAndGiveUp)
494 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
498 assert(
MI &&
"Used insn before defined");
499 assert(
MI->getNumDefs() > 0 &&
"No defs");
500 const Register Res =
MI->getOperand(0).getReg();
502 if (!
MRI.use_nodbg_empty(Res)) {
503 if (handleReject() == RejectAndGiveUp)
512 dbgs() << CurrentIdx <<
": GIM_CheckHasOneUse(MIs["
516 assert(
MI &&
"Used insn before defined");
517 assert(
MI->getNumDefs() > 0 &&
"No defs");
518 const Register Res =
MI->getOperand(0).getReg();
520 if (!
MRI.hasOneNonDBGUse(Res)) {
521 if (handleReject() == RejectAndGiveUp)
530 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
531 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
532 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
533 if (!State.MIs[InsnID]->hasOneMemOperand())
534 if (handleReject() == RejectAndGiveUp)
537 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
538 if (MMO->getMergedOrdering() != Ordering)
539 if (handleReject() == RejectAndGiveUp)
548 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
549 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
550 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
551 if (!State.MIs[InsnID]->hasOneMemOperand())
552 if (handleReject() == RejectAndGiveUp)
555 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
557 if (handleReject() == RejectAndGiveUp)
566 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
567 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
568 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
569 if (!State.MIs[InsnID]->hasOneMemOperand())
570 if (handleReject() == RejectAndGiveUp)
573 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
575 if (handleReject() == RejectAndGiveUp)
583 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
585 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
586 if (handleReject() == RejectAndGiveUp)
593 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
596 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
600 for (
unsigned I = 0;
I != NumAddrSpace; ++
I) {
603 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
604 << AddrSpace <<
'\n');
606 if (AddrSpace == MMOAddrSpace) {
612 CurrentIdx = LastIdx;
613 if (!
Success && handleReject() == RejectAndGiveUp)
622 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
624 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
625 if (handleReject() == RejectAndGiveUp)
631 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
633 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
634 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
635 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
648 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
649 << InsnID <<
"]->memoperands() + " << MMOIdx
650 <<
", Size=" <<
Size <<
")\n");
651 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
653 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
654 if (handleReject() == RejectAndGiveUp)
660 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
663 <<
" bytes vs " <<
Size
666 if (handleReject() == RejectAndGiveUp)
679 TgtExecutor::getName(),
680 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
685 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
686 <<
", OpIdx=" <<
OpIdx <<
")\n");
687 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
692 dbgs() << CurrentIdx <<
": Not a register\n");
693 if (handleReject() == RejectAndGiveUp)
698 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
699 if (handleReject() == RejectAndGiveUp)
705 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
710 if (handleReject() == RejectAndGiveUp)
714 if (handleReject() == RejectAndGiveUp)
718 if (handleReject() == RejectAndGiveUp)
729 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
730 <<
"]->getOperand(" <<
OpIdx
731 <<
"), TypeID=" <<
TypeID <<
")\n");
732 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
735 if (handleReject() == RejectAndGiveUp)
746 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
747 << InsnID <<
"]->getOperand(" <<
OpIdx
748 <<
"), SizeInBits=" << SizeInBits <<
")\n");
749 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
754 if (SizeInBits == 0) {
756 const unsigned AddrSpace = Ty.getAddressSpace();
757 SizeInBits =
MF->getDataLayout().getPointerSizeInBits(AddrSpace);
760 assert(SizeInBits != 0 &&
"Pointer size must be known");
763 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
764 if (handleReject() == RejectAndGiveUp)
766 }
else if (handleReject() == RejectAndGiveUp)
777 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
778 << InsnID <<
"]->getOperand(" <<
OpIdx
779 <<
"), StoreIdx=" << StoreIdx <<
")\n");
780 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
781 assert(StoreIdx < State.RecordedOperands.size() &&
"Index out of range");
782 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(
OpIdx);
788 int TypeIdx = readS8();
791 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
792 << InsnID <<
"]->getOperand(" <<
OpIdx
793 <<
"), TypeIdx=" << TypeIdx <<
")\n");
794 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
795 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
797 TypeIdx = 1 - TypeIdx;
798 const auto &
Op = State.MIs[InsnID]->getOperand(
OpIdx);
799 if (State.RecordedTypes.size() <= (
uint64_t)TypeIdx)
800 State.RecordedTypes.resize(TypeIdx + 1,
LLT());
801 State.RecordedTypes[TypeIdx] =
MRI.getType(
Op.getReg());
812 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
813 << InsnID <<
"]->getOperand(" <<
OpIdx
814 <<
"), RCEnum=" << RCEnum <<
")\n");
815 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
821 if (handleReject() == RejectAndGiveUp)
831 uint16_t ComplexPredicateID = readU16();
833 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
834 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
835 <<
"]->getOperand(" <<
OpIdx
836 <<
"), ComplexPredicateID=" << ComplexPredicateID
838 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
842 State.MIs[InsnID]->getOperand(
OpIdx));
844 State.Renderers[RendererID] = *Renderer;
845 else if (handleReject() == RejectAndGiveUp)
858 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
859 << InsnID <<
"]->getOperand(" <<
OpIdx
860 <<
"), Value=" <<
Value <<
")\n");
861 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
868 if (Ty.getScalarSizeInBits() > 64) {
869 if (handleReject() == RejectAndGiveUp)
876 if (handleReject() == RejectAndGiveUp)
879 }
else if (handleReject() == RejectAndGiveUp)
888 int64_t
Value = readU64();
890 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
891 << InsnID <<
"]->getOperand(" <<
OpIdx
892 <<
"), Value=" <<
Value <<
")\n");
893 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
901 if (handleReject() == RejectAndGiveUp)
912 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
913 << InsnID <<
"]->getOperand(" <<
OpIdx
914 <<
"), Value=" <<
Value <<
")\n");
915 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
918 if (handleReject() == RejectAndGiveUp)
927 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
928 << InsnID <<
"]->getOperand(" <<
OpIdx
929 <<
"), Value=" <<
Value <<
")\n");
930 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
933 if (handleReject() == RejectAndGiveUp)
941 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
942 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
943 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
944 if (!State.MIs[InsnID]->getOperand(
OpIdx).isMBB()) {
945 if (handleReject() == RejectAndGiveUp)
954 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
955 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
956 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
957 if (!State.MIs[InsnID]->getOperand(
OpIdx).isImm()) {
958 if (handleReject() == RejectAndGiveUp)
964 uint64_t NumInsn = MatchTable[CurrentIdx++];
966 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
967 << NumInsn <<
")\n");
969 for (
unsigned K = 1,
E = NumInsn + 1; K <
E; ++K) {
971 if (handleReject() == RejectAndGiveUp)
984 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
985 << InsnID <<
"][" <<
OpIdx <<
"], MIs["
986 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
987 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
988 assert(State.MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
991 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
994 if (
Op.isReg() && OtherOp.
isReg()) {
1001 if (!
Op.isIdenticalTo(OtherOp)) {
1002 if (handleReject() == RejectAndGiveUp)
1014 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1015 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1016 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1018 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1019 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1021 if (handleReject() == RejectAndGiveUp)
1031 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1032 <<
"], " << Flags <<
")\n");
1033 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1034 if (handleReject() == RejectAndGiveUp)
1044 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1045 <<
"], " << Flags <<
")\n");
1046 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1047 if (handleReject() == RejectAndGiveUp)
1054 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1055 if (handleReject() == RejectAndGiveUp)
1062 if (NewInsnID >= OutMIs.
size())
1063 OutMIs.
resize(NewInsnID + 1);
1069 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1073 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1074 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1075 << NewOpcode <<
")\n");
1083 if (NewInsnID >= OutMIs.
size())
1084 OutMIs.
resize(NewInsnID + 1);
1086 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1088 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1089 << NewInsnID <<
"], " << Opcode <<
")\n");
1096 Builder.buildConstant(State.TempRegisters[TempRegID], Imm);
1098 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1099 << TempRegID <<
"], Imm=" << Imm <<
")\n");
1110 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1111 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(
OpIdx));
1114 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1115 <<
"], MIs[" << OldInsnID <<
"], " <<
OpIdx <<
")\n");
1123 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1129 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1130 << NewInsnID <<
"], MIs[" << OldInsnID
1131 <<
"], /*start=*/" <<
OpIdx <<
")\n");
1140 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1143 OutMIs[NewInsnID].addReg(ZeroReg);
1145 OutMIs[NewInsnID].add(MO);
1147 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1148 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1149 <<
OpIdx <<
", " << ZeroReg <<
")\n");
1158 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1159 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(
OpIdx).getReg(),
1162 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1163 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1164 <<
OpIdx <<
", " << SubRegIdx <<
")\n");
1172 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1174 OutMIs[InsnID].addDef(RegNum, Flags);
1176 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1177 << InsnID <<
"], " << RegNum <<
")\n");
1184 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1187 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1188 << InsnID <<
"], " << RegNum <<
")\n");
1196 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1197 OutMIs[InsnID].addReg(RegNum, RegFlags);
1200 << CurrentIdx <<
": GIR_AddRegister(OutMIs[" << InsnID
1201 <<
"], " << RegNum <<
", " << RegFlags <<
")\n");
1207 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1210 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1211 << InsnID <<
"], " <<
Value <<
")\n");
1218 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1219 << InsnID <<
"], OpIdx=" <<
OpIdx <<
")\n");
1221 assert(
MI &&
"Modifying undefined instruction");
1222 MI->getOperand(
MI->getNumExplicitOperands() +
OpIdx).setIsDead();
1230 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1231 << InsnID <<
"], " << Flags <<
")\n");
1233 MI->setFlags(
MI->getFlags() | Flags);
1241 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1242 << InsnID <<
"], " << Flags <<
")\n");
1244 MI->setFlags(
MI->getFlags() & ~Flags);
1252 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1253 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1255 MI->setFlags(
MI->getFlags() | State.MIs[OldInsnID]->getFlags());
1265 TempRegFlags = readU16();
1270 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1272 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1275 TgtExecutor::getName(),
1276 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1277 <<
"], TempRegisters[" << TempRegID <<
"]";
1279 dbgs() <<
", " << TempRegFlags <<
")\n");
1285 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1287 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1288 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1289 OutMIs[InsnID].addImm(Imm);
1291 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1292 <<
"], " << Imm <<
")\n");
1300 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1304 OutMIs[InsnID].addCImm(
1307 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1308 <<
"], TypeID=" <<
TypeID <<
", Imm=" << Imm
1316 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1317 for (
const auto &RenderOpFn : State.Renderers[RendererID])
1318 RenderOpFn(OutMIs[InsnID]);
1320 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1321 << InsnID <<
"], " << RendererID <<
")\n");
1328 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1329 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1331 dbgs() << CurrentIdx
1332 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1333 << InsnID <<
"], " << RendererID <<
", "
1334 << RenderOpID <<
")\n");
1343 assert(
MI &&
"Attempted to add to undefined instruction");
1344 State.Renderers[RendererID][RenderOpID](
MI);
1345 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1347 dbgs() << CurrentIdx
1348 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1349 << InsnID <<
"], " << RendererID <<
", "
1350 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1357 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1358 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1359 "Expected G_CONSTANT");
1360 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1361 OutMIs[NewInsnID].addImm(
1362 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1363 }
else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1364 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1368 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1369 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1377 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1378 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1379 "Expected G_FCONSTANT");
1380 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1381 OutMIs[NewInsnID].addFPImm(
1382 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1387 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1388 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1396 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1398 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1399 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1400 << RendererFnID <<
")\n");
1402 OutMIs[InsnID], *State.MIs[OldInsnID],
1409 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1417 if (handleReject() == RejectAndGiveUp)
1426 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1429 dbgs() << CurrentIdx
1430 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1431 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1432 <<
OpIdx <<
"), " << RendererFnID <<
")\n");
1434 OutMIs[InsnID], *State.MIs[OldInsnID],
OpIdx);
1441 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1449 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1450 << InsnID <<
"], " <<
OpIdx <<
", " << RCEnum
1460 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1464 dbgs() << CurrentIdx
1465 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1466 << InsnID <<
"])\n");
1471 uint64_t NumInsn = MatchTable[CurrentIdx++];
1472 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1475 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1477 for (
unsigned K = 0; K < NumInsn; ++K) {
1480 dbgs() <<
", MIs[" << NextID <<
"]");
1481 for (
const auto &MMO : State.MIs[NextID]->memoperands())
1482 OutMIs[InsnID].addMemOperand(MMO);
1490 assert(
MI &&
"Attempted to erase an undefined instruction");
1492 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1493 << InsnID <<
"])\n");
1500 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1501 eraseImpl(State.MIs[0]);
1509 State.TempRegisters[TempRegID] =
1510 MRI.createGenericVirtualRegister(getTypeFromIdx(
TypeID));
1512 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1513 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1523 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1524 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1525 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1527 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1528 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1531 MRI.replaceRegWith(Old, New);
1542 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1543 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1544 << TempRegID <<
"])\n");
1546 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1547 Register New = State.TempRegisters[TempRegID];
1550 MRI.replaceRegWith(Old, New);
1561 <<
": GIR_Coverage("
1568 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...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
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.
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...
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 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 unsigned getScalarSizeInBits() const
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
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...
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.
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.
@ Default
The result values are uniform if and only if all operands are uniform.
@ 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_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.
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