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 RootFlags = State.MIs[0]->getFlags();
65 bool BuilderInitialized =
false;
66 const auto initializeBuilder = [&]() {
67 if (BuilderInitialized)
71 Builder.setInstrAndDebugLoc(*State.MIs[0]);
72 BuilderInitialized =
true;
74 const auto initializeOutMIFlagState = [&](
unsigned NumOutMIs) {
75 if (NumOutMIs > OutMIFlagsToDrop.
size())
76 OutMIFlagsToDrop.
resize(NumOutMIs, RootFlagsToDrop);
79 enum RejectAction { RejectAndGiveUp, RejectAndResume };
80 auto handleReject = [&]() -> RejectAction {
82 dbgs() << CurrentIdx <<
": Rejected\n");
83 if (OnFailResumeAt.
empty())
84 return RejectAndGiveUp;
87 dbgs() << CurrentIdx <<
": Resume at " << CurrentIdx <<
" ("
88 << OnFailResumeAt.
size() <<
" try-blocks remain)\n");
89 return RejectAndResume;
92 const auto propagateFlags = [&]() {
93 initializeOutMIFlagState(OutMIs.
size());
94 for (
unsigned I = 0,
E = OutMIs.
size();
I !=
E; ++
I) {
112 const auto getTypeFromIdx = [&](int64_t Idx) ->
LLT {
115 return State.RecordedTypes[1 - Idx];
118 const auto readULEB = [&]() {
127 const auto readS8 = [&]() {
return (int8_t)MatchTable[CurrentIdx++]; };
129 const auto readU16 = [&]() {
135 const auto readU32 = [&]() {
141 const auto readU64 = [&]() {
151 if (Builder.getInsertPt() ==
MI)
152 Builder.setInsertPt(*
MI->getParent(), ++
MI->getIterator());
155 MI->eraseFromParent();
159 assert(CurrentIdx != ~0u &&
"Invalid MatchTable index");
160 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
161 switch (MatcherOpcode) {
164 dbgs() << CurrentIdx <<
": Begin try-block\n");
171 unsigned OnFail = readU32();
172 uint16_t ExpectedBitsetID = readU16();
175 <<
": GIM_Try_CheckFeatures(ExpectedBitsetID="
176 << ExpectedBitsetID <<
")\n");
177 if ((AvailableFeatures & ExecInfo.
FeatureBitsets[ExpectedBitsetID]) !=
181 <<
": Features do not match, rejected\n");
196 assert(NewInsnID != 0 &&
"Refusing to modify MIs[0]");
201 dbgs() << CurrentIdx <<
": Not a register\n");
202 if (handleReject() == RejectAndGiveUp)
208 dbgs() << CurrentIdx <<
": Is a physical register\n");
209 if (handleReject() == RejectAndGiveUp)
220 if ((
size_t)NewInsnID < State.MIs.size())
221 State.MIs[NewInsnID] = NewMI;
223 assert((
size_t)NewInsnID == State.MIs.size() &&
224 "Expected to store MIs in order");
225 State.MIs.push_back(NewMI);
228 dbgs() << CurrentIdx <<
": MIs[" << NewInsnID
229 <<
"] = GIM_RecordInsn(" << InsnID <<
", " << OpIdx
239 Expected1 = readU16();
241 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
242 unsigned Opcode = State.MIs[InsnID]->getOpcode();
245 dbgs() << CurrentIdx <<
": GIM_CheckOpcode(MIs[" << InsnID
246 <<
"], ExpectedOpcode=" << Expected0;
248 dbgs() <<
" || " << Expected1;
249 dbgs() <<
") // Got=" << Opcode <<
"\n";
252 if (Opcode != Expected0 && Opcode != Expected1) {
253 if (handleReject() == RejectAndGiveUp)
264 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
265 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
268 dbgs() << CurrentIdx <<
": GIM_SwitchOpcode(MIs[" << InsnID <<
"], ["
269 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
270 <<
", JumpTable...) // Got=" << Opcode <<
"\n";
272 if (Opcode < LowerBound || UpperBound <= Opcode) {
276 const auto EntryIdx = (Opcode - LowerBound);
297 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
301 dbgs() << CurrentIdx <<
": GIM_SwitchType" << (IsShape ?
"Shape" :
"")
302 <<
"(MIs[" << InsnID <<
"]->getOperand(" << OpIdx <<
"), ["
303 << LowerBound <<
", " << UpperBound <<
"), Default=" <<
Default
304 <<
", JumpTable...) // Got=";
306 dbgs() <<
"Not a VReg\n";
319 const auto TyI = ExecInfo.
TypeIDMap.
find(Ty.getUniqueRAWLLTData());
324 const int64_t
TypeID = TyI->second;
329 const auto NumEntry = (
TypeID - LowerBound);
347 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands"
348 << (IsLE ?
"LE" :
"GE") <<
"(MIs[" << InsnID
349 <<
"], Expected=" <<
Expected <<
")\n");
350 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
351 const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
353 if (handleReject() == RejectAndGiveUp)
362 dbgs() << CurrentIdx <<
": GIM_CheckNumOperands(MIs["
363 << InsnID <<
"], Expected=" <<
Expected <<
")\n");
364 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
365 if (State.MIs[InsnID]->getNumOperands() !=
Expected) {
366 if (handleReject() == RejectAndGiveUp)
378 dbgs() << CurrentIdx <<
": GIM_CheckImmPredicate(MIs["
379 << InsnID <<
"]->getOperand(" << OpIdx
380 <<
"), Predicate=" <<
Predicate <<
")\n");
381 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
382 assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
383 State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
384 "Expected immediate operand");
387 if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
388 Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
389 else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
390 Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
395 if (handleReject() == RejectAndGiveUp)
404 << CurrentIdx <<
": GIM_CheckAPIntImmPredicate(MIs["
405 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
406 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
407 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
408 "Expected G_CONSTANT");
410 if (!State.MIs[InsnID]->getOperand(1).isCImm())
414 State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
416 if (handleReject() == RejectAndGiveUp)
425 << CurrentIdx <<
": GIM_CheckAPFloatImmPredicate(MIs["
426 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
427 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
428 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
429 "Expected G_FCONSTANT");
430 assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
431 "Expected FPImm operand");
434 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
437 if (handleReject() == RejectAndGiveUp)
447 <<
": GIM_CheckLeafOperandPredicate(MIs[" << InsnID
448 <<
"]->getOperand(" << OpIdx
449 <<
"), Predicate=" <<
Predicate <<
")\n");
450 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
451 assert(State.MIs[InsnID]->getOperand(OpIdx).isReg() &&
452 "Expected register operand");
457 if (handleReject() == RejectAndGiveUp)
467 <<
": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
468 << InsnID <<
"])\n");
469 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
472 assert((
MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
473 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
474 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
478 if (handleReject() == RejectAndGiveUp)
483 if (handleReject() == RejectAndGiveUp)
497 <<
": GIM_CheckSimplePredicate(Predicate="
501 if (handleReject() == RejectAndGiveUp)
511 << CurrentIdx <<
": GIM_CheckCxxPredicate(MIs["
512 << InsnID <<
"], Predicate=" <<
Predicate <<
")\n");
513 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
517 if (handleReject() == RejectAndGiveUp)
525 dbgs() << CurrentIdx <<
": GIM_CheckHasNoUse(MIs["
529 assert(
MI &&
"Used insn before defined");
530 assert(
MI->getNumDefs() > 0 &&
"No defs");
531 const Register Res =
MI->getOperand(0).getReg();
534 if (handleReject() == RejectAndGiveUp)
543 dbgs() << CurrentIdx <<
": GIM_CheckHasOneUse(MIs["
547 assert(
MI &&
"Used insn before defined");
548 assert(
MI->getNumDefs() > 0 &&
"No defs");
549 const Register Res =
MI->getOperand(0).getReg();
552 if (handleReject() == RejectAndGiveUp)
561 dbgs() << CurrentIdx <<
": GIM_CheckAtomicOrdering(MIs["
562 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
563 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
564 if (!State.MIs[InsnID]->hasOneMemOperand())
565 if (handleReject() == RejectAndGiveUp)
568 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
569 if (MMO->getMergedOrdering() != Ordering)
570 if (handleReject() == RejectAndGiveUp)
579 <<
": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
580 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
581 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
582 if (!State.MIs[InsnID]->hasOneMemOperand())
583 if (handleReject() == RejectAndGiveUp)
586 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
588 if (handleReject() == RejectAndGiveUp)
597 <<
": GIM_CheckAtomicOrderingWeakerThan(MIs["
598 << InsnID <<
"], " << (
uint64_t)Ordering <<
")\n");
599 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
600 if (!State.MIs[InsnID]->hasOneMemOperand())
601 if (handleReject() == RejectAndGiveUp)
604 for (
const auto &MMO : State.MIs[InsnID]->memoperands())
606 if (handleReject() == RejectAndGiveUp)
614 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
616 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
617 if (handleReject() == RejectAndGiveUp)
624 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
627 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
631 for (
unsigned I = 0;
I != NumAddrSpace; ++
I) {
634 dbgs() <<
"addrspace(" << MMOAddrSpace <<
") vs "
635 << AddrSpace <<
'\n');
637 if (AddrSpace == MMOAddrSpace) {
643 CurrentIdx = LastIdx;
644 if (!
Success && handleReject() == RejectAndGiveUp)
653 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
655 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
656 if (handleReject() == RejectAndGiveUp)
662 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
664 dbgs() << CurrentIdx <<
": GIM_CheckMemoryAlignment"
665 <<
"(MIs[" << InsnID <<
"]->memoperands() + "
666 << MMOIdx <<
")->getAlignment() >= " <<
MinAlign
679 dbgs() << CurrentIdx <<
": GIM_CheckMemorySizeEqual(MIs["
680 << InsnID <<
"]->memoperands() + " << MMOIdx
681 <<
", Size=" <<
Size <<
")\n");
682 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
684 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
685 if (handleReject() == RejectAndGiveUp)
691 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
694 <<
" bytes vs " <<
Size
697 if (handleReject() == RejectAndGiveUp)
710 TgtExecutor::getName(),
711 dbgs() << CurrentIdx <<
": GIM_CheckMemorySize"
716 <<
"LLT(MIs[" << InsnID <<
"]->memoperands() + " << MMOIdx
717 <<
", OpIdx=" << OpIdx <<
")\n");
718 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
723 dbgs() << CurrentIdx <<
": Not a register\n");
724 if (handleReject() == RejectAndGiveUp)
729 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
730 if (handleReject() == RejectAndGiveUp)
736 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
741 if (handleReject() == RejectAndGiveUp)
745 if (handleReject() == RejectAndGiveUp)
749 if (handleReject() == RejectAndGiveUp)
760 dbgs() << CurrentIdx <<
": GIM_CheckType(MIs[" << InsnID
761 <<
"]->getOperand(" << OpIdx
762 <<
"), TypeID=" <<
TypeID <<
")\n");
763 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
766 if (handleReject() == RejectAndGiveUp)
777 dbgs() << CurrentIdx <<
": GIM_CheckPointerToAny(MIs["
778 << InsnID <<
"]->getOperand(" << OpIdx
779 <<
"), SizeInBits=" << SizeInBits <<
")\n");
780 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
785 if (SizeInBits == 0) {
787 const unsigned AddrSpace = Ty.getAddressSpace();
788 SizeInBits =
MF->getDataLayout().getPointerSizeInBits(AddrSpace);
791 assert(SizeInBits != 0 &&
"Pointer size must be known");
794 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
795 if (handleReject() == RejectAndGiveUp)
797 }
else if (handleReject() == RejectAndGiveUp)
808 dbgs() << CurrentIdx <<
": GIM_RecordNamedOperand(MIs["
809 << InsnID <<
"]->getOperand(" << OpIdx
810 <<
"), StoreIdx=" << StoreIdx <<
")\n");
811 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
812 assert(StoreIdx < State.RecordedOperands.size() &&
"Index out of range");
813 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
819 int TypeIdx = readS8();
822 dbgs() << CurrentIdx <<
": GIM_RecordRegType(MIs["
823 << InsnID <<
"]->getOperand(" << OpIdx
824 <<
"), TypeIdx=" << TypeIdx <<
")\n");
825 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
826 assert(TypeIdx < 0 &&
"Temp types always have negative indexes!");
828 TypeIdx = 1 - TypeIdx;
829 const auto &
Op = State.MIs[InsnID]->getOperand(OpIdx);
830 if (State.RecordedTypes.size() <= (
uint64_t)TypeIdx)
831 State.RecordedTypes.resize(TypeIdx + 1,
LLT());
832 State.RecordedTypes[TypeIdx] = MRI.
getType(
Op.getReg());
843 dbgs() << CurrentIdx <<
": GIM_CheckRegBankForClass(MIs["
844 << InsnID <<
"]->getOperand(" << OpIdx
845 <<
"), RCEnum=" << RCEnum <<
")\n");
846 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
852 if (handleReject() == RejectAndGiveUp)
862 uint16_t ComplexPredicateID = readU16();
864 dbgs() << CurrentIdx <<
": State.Renderers[" << RendererID
865 <<
"] = GIM_CheckComplexPattern(MIs[" << InsnID
866 <<
"]->getOperand(" << OpIdx
867 <<
"), ComplexPredicateID=" << ComplexPredicateID
869 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
873 State.MIs[InsnID]->getOperand(OpIdx));
875 State.Renderers[RendererID] = std::move(*Renderer);
876 else if (handleReject() == RejectAndGiveUp)
889 dbgs() << CurrentIdx <<
": GIM_CheckConstantInt(MIs["
890 << InsnID <<
"]->getOperand(" << OpIdx
891 <<
"), Value=" <<
Value <<
")\n");
892 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
899 if (Ty.getScalarSizeInBits() > 64) {
900 if (handleReject() == RejectAndGiveUp)
907 if (handleReject() == RejectAndGiveUp)
910 }
else if (handleReject() == RejectAndGiveUp)
919 int64_t
Value = readU64();
921 dbgs() << CurrentIdx <<
": GIM_CheckLiteralInt(MIs["
922 << InsnID <<
"]->getOperand(" << OpIdx
923 <<
"), Value=" <<
Value <<
")\n");
924 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
932 if (handleReject() == RejectAndGiveUp)
943 dbgs() << CurrentIdx <<
": GIM_CheckIntrinsicID(MIs["
944 << InsnID <<
"]->getOperand(" << OpIdx
945 <<
"), Value=" <<
Value <<
")\n");
946 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
949 if (handleReject() == RejectAndGiveUp)
958 dbgs() << CurrentIdx <<
": GIM_CheckCmpPredicate(MIs["
959 << InsnID <<
"]->getOperand(" << OpIdx
960 <<
"), Value=" <<
Value <<
")\n");
961 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
964 if (handleReject() == RejectAndGiveUp)
972 dbgs() << CurrentIdx <<
": GIM_CheckIsMBB(MIs[" << InsnID
973 <<
"]->getOperand(" << OpIdx <<
"))\n");
974 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
975 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
976 if (handleReject() == RejectAndGiveUp)
985 dbgs() << CurrentIdx <<
": GIM_CheckIsImm(MIs[" << InsnID
986 <<
"]->getOperand(" << OpIdx <<
"))\n");
987 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
988 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
989 if (handleReject() == RejectAndGiveUp)
995 uint64_t NumInsn = MatchTable[CurrentIdx++];
997 dbgs() << CurrentIdx <<
": GIM_CheckIsSafeToFold(N = "
998 << NumInsn <<
")\n");
1000 for (
unsigned K = 1,
E = NumInsn + 1;
K <
E; ++
K) {
1002 if (handleReject() == RejectAndGiveUp)
1015 dbgs() << CurrentIdx <<
": GIM_CheckIsSameOperand(MIs["
1016 << InsnID <<
"][" << OpIdx <<
"], MIs["
1017 << OtherInsnID <<
"][" << OtherOpIdx <<
"])\n");
1018 assert(State.MIs[InsnID] !=
nullptr &&
"Used insn before defined");
1019 assert(State.MIs[OtherInsnID] !=
nullptr &&
"Used insn before defined");
1022 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
1025 if (
Op.isReg() && OtherOp.
isReg()) {
1032 if (!
Op.isIdenticalTo(OtherOp)) {
1033 if (handleReject() == RejectAndGiveUp)
1045 dbgs() << CurrentIdx <<
": GIM_CheckCanReplaceReg(MIs["
1046 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1047 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1049 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1050 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1052 if (handleReject() == RejectAndGiveUp)
1062 dbgs() << CurrentIdx <<
": GIM_MIFlags(MIs[" << InsnID
1063 <<
"], " << Flags <<
")\n");
1064 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1065 if (handleReject() == RejectAndGiveUp)
1075 dbgs() << CurrentIdx <<
": GIM_MIFlagsNot(MIs[" << InsnID
1076 <<
"], " << Flags <<
")\n");
1077 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1078 if (handleReject() == RejectAndGiveUp)
1085 dbgs() << CurrentIdx <<
": GIM_Reject\n");
1086 if (handleReject() == RejectAndGiveUp)
1093 if (NewInsnID >= OutMIs.
size())
1094 OutMIs.
resize(NewInsnID + 1);
1095 initializeOutMIFlagState(NewInsnID + 1);
1101 OutMIs[NewInsnID]->setDesc(
TII.get(NewOpcode));
1105 dbgs() << CurrentIdx <<
": GIR_MutateOpcode(OutMIs["
1106 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1107 << NewOpcode <<
")\n");
1115 if (NewInsnID >= OutMIs.
size())
1116 OutMIs.
resize(NewInsnID + 1);
1117 initializeOutMIFlagState(NewInsnID + 1);
1119 initializeBuilder();
1120 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1122 dbgs() << CurrentIdx <<
": GIR_BuildMI(OutMIs["
1123 << NewInsnID <<
"], " << Opcode <<
")\n");
1130 initializeBuilder();
1131 Builder.buildConstant(State.TempRegisters[TempRegID],
Imm);
1133 dbgs() << CurrentIdx <<
": GIR_BuildConstant(TempReg["
1134 << TempRegID <<
"], Imm=" <<
Imm <<
")\n");
1145 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1146 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
1149 << CurrentIdx <<
": GIR_Copy(OutMIs[" << NewInsnID
1150 <<
"], MIs[" << OldInsnID <<
"], " << OpIdx <<
")\n");
1158 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1164 dbgs() << CurrentIdx <<
": GIR_CopyRemaining(OutMIs["
1165 << NewInsnID <<
"], MIs[" << OldInsnID
1166 <<
"], /*start=*/" << OpIdx <<
")\n");
1175 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1178 OutMIs[NewInsnID].addReg(ZeroReg);
1180 OutMIs[NewInsnID].add(MO);
1182 dbgs() << CurrentIdx <<
": GIR_CopyOrAddZeroReg(OutMIs["
1183 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1184 << OpIdx <<
", " << ZeroReg <<
")\n");
1193 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1194 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1197 dbgs() << CurrentIdx <<
": GIR_CopySubReg(OutMIs["
1198 << NewInsnID <<
"], MIs[" << OldInsnID <<
"], "
1199 << OpIdx <<
", " << SubRegIdx <<
")\n");
1207 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1209 OutMIs[InsnID].addDef(RegNum, Flags);
1211 dbgs() << CurrentIdx <<
": GIR_AddImplicitDef(OutMIs["
1212 << InsnID <<
"], " << RegNum <<
", "
1213 <<
static_cast<uint16_t>(Flags) <<
")\n");
1220 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1223 dbgs() << CurrentIdx <<
": GIR_AddImplicitUse(OutMIs["
1224 << InsnID <<
"], " << RegNum <<
")\n");
1232 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1233 OutMIs[InsnID].addReg(RegNum, RegFlags);
1235 dbgs() << CurrentIdx <<
": GIR_AddRegister(OutMIs["
1236 << InsnID <<
"], " << RegNum <<
", "
1237 <<
static_cast<uint16_t>(RegFlags) <<
")\n");
1243 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1246 dbgs() << CurrentIdx <<
": GIR_AddIntrinsicID(OutMIs["
1247 << InsnID <<
"], " <<
Value <<
")\n");
1254 dbgs() << CurrentIdx <<
": GIR_SetImplicitDefDead(OutMIs["
1255 << InsnID <<
"], OpIdx=" << OpIdx <<
")\n");
1257 assert(
MI &&
"Modifying undefined instruction");
1258 MI->getOperand(
MI->getNumExplicitOperands() + OpIdx).setIsDead();
1266 dbgs() << CurrentIdx <<
": GIR_SetMIFlags(OutMIs["
1267 << InsnID <<
"], " << Flags <<
")\n");
1269 assert(
MI &&
"Modifying undefined instruction");
1270 MI->setFlags(
MI->getFlags() | Flags);
1271 initializeOutMIFlagState(OutMIs.
size());
1272 OutMIFlagsToDrop[InsnID] &= ~Flags;
1280 dbgs() << CurrentIdx <<
": GIR_UnsetMIFlags(OutMIs["
1281 << InsnID <<
"], " << Flags <<
")\n");
1283 assert(
MI &&
"Modifying undefined instruction");
1284 MI->setFlags(
MI->getFlags() & ~Flags);
1285 initializeOutMIFlagState(OutMIs.
size());
1286 OutMIFlagsToDrop[InsnID] |= Flags;
1294 dbgs() << CurrentIdx <<
": GIR_CopyMIFlags(OutMIs["
1295 << InsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1297 assert(
MI &&
"Modifying undefined instruction");
1298 uint32_t Flags = State.MIs[OldInsnID]->getFlags();
1299 MI->setFlags(
MI->getFlags() | Flags);
1300 initializeOutMIFlagState(OutMIs.
size());
1301 OutMIFlagsToDrop[InsnID] &= ~Flags;
1311 TempRegFlags =
static_cast<RegState>(readU16());
1316 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1318 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1321 TgtExecutor::getName(),
1322 dbgs() << CurrentIdx <<
": GIR_AddTempRegister(OutMIs[" << InsnID
1323 <<
"], TempRegisters[" << TempRegID <<
"]";
1324 if (SubReg)
dbgs() <<
'.' <<
TRI.getSubRegIndexName(SubReg);
1325 dbgs() <<
", " <<
static_cast<uint16_t>(TempRegFlags) <<
")\n");
1331 const bool IsAdd8 = (MatcherOpcode ==
GIR_AddImm8);
1333 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1334 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1335 OutMIs[InsnID].addImm(
Imm);
1337 dbgs() << CurrentIdx <<
": GIR_AddImm(OutMIs[" << InsnID
1338 <<
"], " <<
Imm <<
")\n");
1346 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1348 unsigned Width = getTypeFromIdx(
TypeID).getScalarSizeInBits();
1350 OutMIs[InsnID].addCImm(
1353 dbgs() << CurrentIdx <<
": GIR_AddCImm(OutMIs[" << InsnID
1354 <<
"], TypeID=" <<
TypeID <<
", Imm=" <<
Imm
1362 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1363 for (
const auto &RenderOpFn : State.Renderers[RendererID])
1364 RenderOpFn(OutMIs[InsnID]);
1366 dbgs() << CurrentIdx <<
": GIR_ComplexRenderer(OutMIs["
1367 << InsnID <<
"], " << RendererID <<
")\n");
1374 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1375 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1377 dbgs() << CurrentIdx
1378 <<
": GIR_ComplexSubOperandRenderer(OutMIs["
1379 << InsnID <<
"], " << RendererID <<
", "
1380 << RenderOpID <<
")\n");
1389 assert(
MI &&
"Attempted to add to undefined instruction");
1390 State.Renderers[RendererID][RenderOpID](
MI);
1391 MI->getOperand(
MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1393 dbgs() << CurrentIdx
1394 <<
": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1395 << InsnID <<
"], " << RendererID <<
", "
1396 << RenderOpID <<
", " << SubRegIdx <<
")\n");
1403 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1404 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1405 "Expected G_CONSTANT");
1406 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1407 OutMIs[NewInsnID].addImm(
1408 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1409 }
else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1410 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1414 dbgs() << CurrentIdx <<
": GIR_CopyConstantAsSImm(OutMIs["
1415 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1423 assert(OutMIs[NewInsnID] &&
"Attempted to add to undefined instruction");
1424 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1425 "Expected G_FCONSTANT");
1426 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1427 OutMIs[NewInsnID].addFPImm(
1428 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1433 << CurrentIdx <<
": GIR_CopyFPConstantAsFPImm(OutMIs["
1434 << NewInsnID <<
"], MIs[" << OldInsnID <<
"])\n");
1442 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1444 dbgs() << CurrentIdx <<
": GIR_CustomRenderer(OutMIs["
1445 << InsnID <<
"], MIs[" << OldInsnID <<
"], "
1446 << RendererFnID <<
")\n");
1448 OutMIs[InsnID], *State.MIs[OldInsnID],
1455 dbgs() << CurrentIdx <<
": GIR_DoneWithCustomAction(FnID="
1459 initializeOutMIFlagState(OutMIs.
size());
1460 for (
unsigned I = 0,
E = OutMIs.
size();
I !=
E; ++
I)
1461 OutMIFlagsToDrop[
I] &= ~OutMIs[
I]->getFlags();
1466 if (handleReject() == RejectAndGiveUp)
1475 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1478 dbgs() << CurrentIdx
1479 <<
": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1480 <<
"], MIs[" << OldInsnID <<
"]->getOperand("
1481 << OpIdx <<
"), " << RendererFnID <<
")\n");
1483 OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx);
1490 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1498 dbgs() << CurrentIdx <<
": GIR_ConstrainOperandRC(OutMIs["
1499 << InsnID <<
"], " << OpIdx <<
", " << RCEnum
1509 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1513 dbgs() << CurrentIdx
1514 <<
": GIR_ConstrainSelectedInstOperands(OutMIs["
1515 << InsnID <<
"])\n");
1520 uint64_t NumInsn = MatchTable[CurrentIdx++];
1521 assert(OutMIs[InsnID] &&
"Attempted to add to undefined instruction");
1524 dbgs() << CurrentIdx <<
": GIR_MergeMemOperands(OutMIs["
1526 for (
unsigned K = 0;
K < NumInsn; ++
K) {
1529 dbgs() <<
", MIs[" << NextID <<
"]");
1530 for (
const auto &MMO : State.MIs[NextID]->memoperands())
1531 OutMIs[InsnID].addMemOperand(MMO);
1539 assert(
MI &&
"Attempted to erase an undefined instruction");
1541 dbgs() << CurrentIdx <<
": GIR_EraseFromParent(MIs["
1542 << InsnID <<
"])\n");
1549 << CurrentIdx <<
": GIR_EraseRootFromParent_Done\n");
1550 eraseImpl(State.MIs[0]);
1558 State.TempRegisters[TempRegID] =
1561 dbgs() << CurrentIdx <<
": TempRegs[" << TempRegID
1562 <<
"] = GIR_MakeTempReg(" <<
TypeID <<
")\n");
1572 dbgs() << CurrentIdx <<
": GIR_ReplaceReg(MIs["
1573 << OldInsnID <<
"][" << OldOpIdx <<
"] = MIs["
1574 << NewInsnID <<
"][" << NewOpIdx <<
"])\n");
1576 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1577 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1591 dbgs() << CurrentIdx <<
": GIR_ReplaceRegWithTempReg(MIs["
1592 << OldInsnID <<
"][" << OldOpIdx <<
"] = TempRegs["
1593 << TempRegID <<
"])\n");
1595 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1596 Register New = State.TempRegisters[TempRegID];
1610 <<
": GIR_Coverage("
1617 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
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 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,...
MCRegisterClass TargetRegisterClass
SmallDenseMap< uint64_t, unsigned, 64 > TypeIDMap
const CustomRendererFn * CustomRenderers
const ComplexMatcherMemFn * ComplexPredicates
const PredicateBitset * FeatureBitsets