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();
62 bool BuilderInitialized =
false;
63 const auto initializeBuilder = [&]() {
64 if (BuilderInitialized)
68 Builder.setInstrAndDebugLoc(*State.MIs[0]);
69 BuilderInitialized =
true;
72 enum RejectAction { RejectAndGiveUp, RejectAndResume };
73 auto handleReject = [&]() -> RejectAction {
75 dbgs() << CurrentIdx <<
": Rejected\n");
76 if (OnFailResumeAt.
empty())
77 return RejectAndGiveUp;
80 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
81 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
82 return RejectAndResume;
85 const auto propagateFlags = [&]() {
86 for (
auto MIB : OutMIs) {
89 uint32_t MIBFlags = Flags | MIB.getInstr()->getFlags();
90 if (NoFPException && MIB->mayRaiseFPException())
94 MIB.setMIFlags(MIBFlags);
102 const auto getTypeFromIdx = [&](int64_t Idx) ->
LLT {
105 return State.RecordedTypes[1 - Idx];
108 const auto readULEB = [&]() {
117 const auto readS8 = [&]() {
return (int8_t)MatchTable[CurrentIdx++]; };
119 const auto readU16 = [&]() {
125 const auto readU32 = [&]() {
131 const auto readU64 = [&]() {
141 if (Builder.getInsertPt() ==
MI)
142 Builder.setInsertPt(*
MI->getParent(), ++
MI->getIterator());
145 MI->eraseFromParent();
149 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
150 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
151 switch (MatcherOpcode) {
154 dbgs() << CurrentIdx <<
": Begin try-block\n");
161 unsigned OnFail = readU32();
162 uint16_t ExpectedBitsetID = readU16();
165 <<
": GIM_Try_CheckFeatures(ExpectedBitsetID="
166 << ExpectedBitsetID <<
")\n");
167 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
171 <<
": Features do not match, rejected\n");
186 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
191 dbgs() << CurrentIdx <<
": Not a register\n");
192 if (handleReject() == RejectAndGiveUp)
198 dbgs() << CurrentIdx <<
": Is a physical register\n");
199 if (handleReject() == RejectAndGiveUp)
210 if ((
size_t)NewInsnID < State.MIs.size())
211 State.MIs[NewInsnID] = NewMI;
213 assert((
size_t)NewInsnID == State.MIs.size() &&
214 "Expected to store MIs in order");
215 State.MIs.push_back(NewMI);
218 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
219 <<
"] = GIM_RecordInsn(" << InsnID <<
", " <<
OpIdx
229 Expected1 = readU16();
231 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
232 unsigned Opcode = State.MIs[InsnID]->getOpcode();
235 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
236 <<
"], ExpectedOpcode=" << Expected0;
238 dbgs() <<
" || " << Expected1;
239 dbgs() <<
") // Got=" << Opcode <<
"\n";
242 if (Opcode != Expected0 && Opcode != Expected1) {
243 if (handleReject() == RejectAndGiveUp)
254 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
255 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
258 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
259 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
260 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
262 if (Opcode < LowerBound || UpperBound <= Opcode) {
266 const auto EntryIdx = (Opcode - LowerBound);
287 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
291 dbgs() << CurrentIdx <<
": GIM_SwitchType" << (IsShape ?
"Shape" :
"")
292 <<
"(MIs[" << InsnID <<
"]->getOperand(" <<
OpIdx <<
"), ["
293 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
294 <<
", JumpTable...) // Got=";
296 dbgs() <<
"Not a VReg\n";
309 const auto TyI = ExecInfo.
TypeIDMap.
find(Ty.getUniqueRAWLLTData());
314 const int64_t
TypeID = TyI->second;
319 const auto NumEntry = (
TypeID - LowerBound);
337 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands"
338 << (IsLE ?
"LE" :
"GE") <<
"(MIs[" << InsnID
339 <<
"], Expected=" <<
Expected <<
")\n");
340 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
341 const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
343 if (handleReject() == RejectAndGiveUp)
352 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
353 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
354 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
355 if (State.MIs[InsnID]->getNumOperands() !=
Expected) {
356 if (handleReject() == RejectAndGiveUp)
368 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
369 << InsnID <<
"]->getOperand(" <<
OpIdx
370 <<
"), Predicate=" <<
Predicate <<
")\n");
371 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
372 assert((State.MIs[InsnID]->getOperand(
OpIdx).isImm() ||
373 State.MIs[InsnID]->getOperand(
OpIdx).isCImm()) &&
374 "Expected immediate operand");
377 if (State.MIs[InsnID]->getOperand(
OpIdx).isCImm())
378 Value = State.MIs[InsnID]->getOperand(
OpIdx).getCImm()->getSExtValue();
379 else if (State.MIs[InsnID]->getOperand(
OpIdx).isImm())
380 Value = State.MIs[InsnID]->getOperand(
OpIdx).getImm();
385 if (handleReject() == RejectAndGiveUp)
394 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
395 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
396 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
397 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
398 "Expected G_CONSTANT");
400 if (!State.MIs[InsnID]->getOperand(1).isCImm())
404 State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
406 if (handleReject() == RejectAndGiveUp)
415 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
416 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
417 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
418 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
419 "Expected G_FCONSTANT");
420 assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
421 "Expected FPImm operand");
424 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
427 if (handleReject() == RejectAndGiveUp)
437 <<
": GIM_CheckLeafOperandPredicate(MIs[" << InsnID
438 <<
"]->getOperand(" <<
OpIdx
439 <<
"), Predicate=" <<
Predicate <<
")\n");
440 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
441 assert(State.MIs[InsnID]->getOperand(
OpIdx).isReg() &&
442 "Expected register operand");
447 if (handleReject() == RejectAndGiveUp)
457 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
458 << InsnID <<
"])\n");
459 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
462 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
463 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
464 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
468 if (handleReject() == RejectAndGiveUp)
473 if (handleReject() == RejectAndGiveUp)
487 <<
": GIM_CheckSimplePredicate(Predicate="
491 if (handleReject() == RejectAndGiveUp)
501 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
502 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
503 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
507 if (handleReject() == RejectAndGiveUp)
515 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
519 assert(
MI &&
"Used insn before defined");
520 assert(
MI->getNumDefs() > 0 &&
"No defs");
521 const Register Res =
MI->getOperand(0).getReg();
524 if (handleReject() == RejectAndGiveUp)
533 dbgs() << CurrentIdx <<
": GIM_CheckHasOneUse(MIs["
537 assert(
MI &&
"Used insn before defined");
538 assert(
MI->getNumDefs() > 0 &&
"No defs");
539 const Register Res =
MI->getOperand(0).getReg();
542 if (handleReject() == RejectAndGiveUp)
551 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
552 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
553 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
554 if (!State.MIs[InsnID]->hasOneMemOperand())
555 if (handleReject() == RejectAndGiveUp)
558 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
559 if (MMO->getMergedOrdering() != Ordering)
560 if (handleReject() == RejectAndGiveUp)
569 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
570 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
571 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
572 if (!State.MIs[InsnID]->hasOneMemOperand())
573 if (handleReject() == RejectAndGiveUp)
576 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
578 if (handleReject() == RejectAndGiveUp)
587 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
588 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
589 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
590 if (!State.MIs[InsnID]->hasOneMemOperand())
591 if (handleReject() == RejectAndGiveUp)
594 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
596 if (handleReject() == RejectAndGiveUp)
604 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
606 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
607 if (handleReject() == RejectAndGiveUp)
614 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
617 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
621 for (
unsigned I = 0;
I != NumAddrSpace; ++
I) {
624 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
625 << AddrSpace <<
'\n');
627 if (AddrSpace == MMOAddrSpace) {
633 CurrentIdx = LastIdx;
634 if (!
Success && handleReject() == RejectAndGiveUp)
643 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
645 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
646 if (handleReject() == RejectAndGiveUp)
652 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
654 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
655 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
656 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
669 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
670 << InsnID <<
"]->memoperands() + " << MMOIdx
671 <<
", Size=" <<
Size <<
")\n");
672 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
674 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
675 if (handleReject() == RejectAndGiveUp)
681 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
684 <<
" bytes vs " <<
Size
687 if (handleReject() == RejectAndGiveUp)
700 TgtExecutor::getName(),
701 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
706 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
707 <<
", OpIdx=" <<
OpIdx <<
")\n");
708 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
713 dbgs() << CurrentIdx <<
": Not a register\n");
714 if (handleReject() == RejectAndGiveUp)
719 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
720 if (handleReject() == RejectAndGiveUp)
726 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
731 if (handleReject() == RejectAndGiveUp)
735 if (handleReject() == RejectAndGiveUp)
739 if (handleReject() == RejectAndGiveUp)
750 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
751 <<
"]->getOperand(" <<
OpIdx
752 <<
"), TypeID=" <<
TypeID <<
")\n");
753 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
756 if (handleReject() == RejectAndGiveUp)
767 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
768 << InsnID <<
"]->getOperand(" <<
OpIdx
769 <<
"), SizeInBits=" << SizeInBits <<
")\n");
770 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
775 if (SizeInBits == 0) {
777 const unsigned AddrSpace = Ty.getAddressSpace();
778 SizeInBits =
MF->getDataLayout().getPointerSizeInBits(AddrSpace);
781 assert(SizeInBits != 0 &&
"Pointer size must be known");
784 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
785 if (handleReject() == RejectAndGiveUp)
787 }
else if (handleReject() == RejectAndGiveUp)
798 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
799 << InsnID <<
"]->getOperand(" <<
OpIdx
800 <<
"), StoreIdx=" << StoreIdx <<
")\n");
801 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
802 assert(StoreIdx < State.RecordedOperands.size() &&
"Index out of range");
803 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(
OpIdx);
809 int TypeIdx = readS8();
812 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
813 << InsnID <<
"]->getOperand(" <<
OpIdx
814 <<
"), TypeIdx=" << TypeIdx <<
")\n");
815 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
816 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
818 TypeIdx = 1 - TypeIdx;
819 const auto &
Op = State.MIs[InsnID]->getOperand(
OpIdx);
820 if (State.RecordedTypes.size() <= (
uint64_t)TypeIdx)
821 State.RecordedTypes.resize(TypeIdx + 1,
LLT());
822 State.RecordedTypes[TypeIdx] = MRI.
getType(
Op.getReg());
833 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
834 << InsnID <<
"]->getOperand(" <<
OpIdx
835 <<
"), RCEnum=" << RCEnum <<
")\n");
836 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
842 if (handleReject() == RejectAndGiveUp)
852 uint16_t ComplexPredicateID = readU16();
854 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
855 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
856 <<
"]->getOperand(" <<
OpIdx
857 <<
"), ComplexPredicateID=" << ComplexPredicateID
859 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
863 State.MIs[InsnID]->getOperand(
OpIdx));
865 State.Renderers[RendererID] = *Renderer;
866 else if (handleReject() == RejectAndGiveUp)
879 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
880 << InsnID <<
"]->getOperand(" <<
OpIdx
881 <<
"), Value=" <<
Value <<
")\n");
882 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
889 if (Ty.getScalarSizeInBits() > 64) {
890 if (handleReject() == RejectAndGiveUp)
897 if (handleReject() == RejectAndGiveUp)
900 }
else if (handleReject() == RejectAndGiveUp)
909 int64_t
Value = readU64();
911 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
912 << InsnID <<
"]->getOperand(" <<
OpIdx
913 <<
"), Value=" <<
Value <<
")\n");
914 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
922 if (handleReject() == RejectAndGiveUp)
933 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
934 << InsnID <<
"]->getOperand(" <<
OpIdx
935 <<
"), Value=" <<
Value <<
")\n");
936 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
939 if (handleReject() == RejectAndGiveUp)
948 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
949 << InsnID <<
"]->getOperand(" <<
OpIdx
950 <<
"), Value=" <<
Value <<
")\n");
951 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
954 if (handleReject() == RejectAndGiveUp)
962 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
963 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
964 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
965 if (!State.MIs[InsnID]->getOperand(
OpIdx).isMBB()) {
966 if (handleReject() == RejectAndGiveUp)
975 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
976 <<
"]->getOperand(" <<
OpIdx <<
"))\n");
977 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
978 if (!State.MIs[InsnID]->getOperand(
OpIdx).isImm()) {
979 if (handleReject() == RejectAndGiveUp)
985 uint64_t NumInsn = MatchTable[CurrentIdx++];
987 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
988 << NumInsn <<
")\n");
990 for (
unsigned K = 1,
E = NumInsn + 1; K <
E; ++K) {
992 if (handleReject() == RejectAndGiveUp)
1005 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
1006 << InsnID <<
"][" <<
OpIdx <<
"], MIs["
1007 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
1008 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1009 assert(State.MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
1012 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
1015 if (
Op.isReg() && OtherOp.
isReg()) {
1022 if (!
Op.isIdenticalTo(OtherOp)) {
1023 if (handleReject() == RejectAndGiveUp)
1035 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1036 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1037 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1039 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1040 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1042 if (handleReject() == RejectAndGiveUp)
1052 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1053 <<
"], " << Flags <<
")\n");
1054 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1055 if (handleReject() == RejectAndGiveUp)
1065 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1066 <<
"], " << Flags <<
")\n");
1067 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1068 if (handleReject() == RejectAndGiveUp)
1075 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1076 if (handleReject() == RejectAndGiveUp)
1083 if (NewInsnID >= OutMIs.
size())
1084 OutMIs.
resize(NewInsnID + 1);
1090 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1094 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1095 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1096 << NewOpcode <<
")\n");
1104 if (NewInsnID >= OutMIs.
size())
1105 OutMIs.
resize(NewInsnID + 1);
1107 initializeBuilder();
1108 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1110 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1111 << NewInsnID <<
"], " << Opcode <<
")\n");
1118 initializeBuilder();
1119 Builder.buildConstant(State.TempRegisters[TempRegID], Imm);
1121 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1122 << TempRegID <<
"], Imm=" << Imm <<
")\n");
1133 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1134 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(
OpIdx));
1137 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1138 <<
"], MIs[" << OldInsnID <<
"], " <<
OpIdx <<
")\n");
1146 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1152 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1153 << NewInsnID <<
"], MIs[" << OldInsnID
1154 <<
"], /*start=*/" <<
OpIdx <<
")\n");
1163 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1166 OutMIs[NewInsnID].addReg(ZeroReg);
1168 OutMIs[NewInsnID].add(MO);
1170 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1171 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1172 <<
OpIdx <<
", " << ZeroReg <<
")\n");
1181 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1182 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(
OpIdx).getReg(),
1185 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1186 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1187 <<
OpIdx <<
", " << SubRegIdx <<
")\n");
1195 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1197 OutMIs[InsnID].addDef(RegNum, Flags);
1199 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1200 << InsnID <<
"], " << RegNum <<
", "
1201 <<
static_cast<uint16_t>(Flags) <<
")\n");
1208 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1211 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1212 << InsnID <<
"], " << RegNum <<
")\n");
1220 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1221 OutMIs[InsnID].addReg(RegNum, RegFlags);
1223 dbgs() << CurrentIdx <<
": GIR_AddRegister(OutMIs["
1224 << InsnID <<
"], " << RegNum <<
", "
1225 <<
static_cast<uint16_t>(RegFlags) <<
")\n");
1231 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1234 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1235 << InsnID <<
"], " <<
Value <<
")\n");
1242 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1243 << InsnID <<
"], OpIdx=" <<
OpIdx <<
")\n");
1245 assert(
MI &&
"Modifying undefined instruction");
1246 MI->getOperand(
MI->getNumExplicitOperands() +
OpIdx).setIsDead();
1254 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1255 << InsnID <<
"], " << Flags <<
")\n");
1257 MI->setFlags(
MI->getFlags() | Flags);
1265 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1266 << InsnID <<
"], " << Flags <<
")\n");
1268 MI->setFlags(
MI->getFlags() & ~Flags);
1276 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1277 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1279 MI->setFlags(
MI->getFlags() | State.MIs[OldInsnID]->getFlags());
1289 TempRegFlags =
static_cast<RegState>(readU16());
1294 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1296 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1299 TgtExecutor::getName(),
1300 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1301 <<
"], TempRegisters[" << TempRegID <<
"]";
1302 if (SubReg)
dbgs() <<
'.' <<
TRI.getSubRegIndexName(SubReg);
1303 dbgs() <<
", " <<
static_cast<uint16_t>(TempRegFlags) <<
")\n");
1309 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1311 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1312 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1313 OutMIs[InsnID].addImm(Imm);
1315 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1316 <<
"], " << Imm <<
")\n");
1324 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1328 OutMIs[InsnID].addCImm(
1331 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1332 <<
"], TypeID=" <<
TypeID <<
", Imm=" << Imm
1340 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1341 for (
const auto &RenderOpFn : State.Renderers[RendererID])
1342 RenderOpFn(OutMIs[InsnID]);
1344 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1345 << InsnID <<
"], " << RendererID <<
")\n");
1352 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1353 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1355 dbgs() << CurrentIdx
1356 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1357 << InsnID <<
"], " << RendererID <<
", "
1358 << RenderOpID <<
")\n");
1367 assert(
MI &&
"Attempted to add to undefined instruction");
1368 State.Renderers[RendererID][RenderOpID](
MI);
1369 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1371 dbgs() << CurrentIdx
1372 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1373 << InsnID <<
"], " << RendererID <<
", "
1374 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1381 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1382 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1383 "Expected G_CONSTANT");
1384 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1385 OutMIs[NewInsnID].addImm(
1386 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1387 }
else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1388 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1392 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1393 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1401 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1402 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1403 "Expected G_FCONSTANT");
1404 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1405 OutMIs[NewInsnID].addFPImm(
1406 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1411 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1412 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1420 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1422 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1423 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1424 << RendererFnID <<
")\n");
1426 OutMIs[InsnID], *State.MIs[OldInsnID],
1433 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1441 if (handleReject() == RejectAndGiveUp)
1450 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1453 dbgs() << CurrentIdx
1454 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1455 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1456 <<
OpIdx <<
"), " << RendererFnID <<
")\n");
1458 OutMIs[InsnID], *State.MIs[OldInsnID],
OpIdx);
1465 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1473 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1474 << InsnID <<
"], " <<
OpIdx <<
", " << RCEnum
1484 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1488 dbgs() << CurrentIdx
1489 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1490 << InsnID <<
"])\n");
1495 uint64_t NumInsn = MatchTable[CurrentIdx++];
1496 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1499 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1501 for (
unsigned K = 0; K < NumInsn; ++K) {
1504 dbgs() <<
", MIs[" << NextID <<
"]");
1505 for (
const auto &MMO : State.MIs[NextID]->memoperands())
1506 OutMIs[InsnID].addMemOperand(MMO);
1514 assert(
MI &&
"Attempted to erase an undefined instruction");
1516 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1517 << InsnID <<
"])\n");
1524 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1525 eraseImpl(State.MIs[0]);
1533 State.TempRegisters[TempRegID] =
1536 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1537 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1547 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1548 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1549 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1551 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1552 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1566 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1567 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1568 << TempRegID <<
"])\n");
1570 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1571 Register New = State.TempRegisters[TempRegID];
1585 <<
": GIR_Coverage("
1592 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
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...
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 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
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
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI 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 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_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.
@ Default
The result value is uniform if and only if all operands are uniform.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
SmallDenseMap< uint64_t, unsigned, 64 > TypeIDMap
const CustomRendererFn * CustomRenderers
const ComplexMatcherMemFn * ComplexPredicates
const PredicateBitset * FeatureBitsets