File indexing completed on 2026-05-10 08:43:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
0016 #define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
0017
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
0020 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
0021 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
0022 #include "llvm/CodeGen/GlobalISel/Utils.h"
0023 #include "llvm/CodeGen/MachineInstrBuilder.h"
0024 #include "llvm/CodeGen/MachineOperand.h"
0025 #include "llvm/CodeGen/MachineRegisterInfo.h"
0026 #include "llvm/CodeGen/RegisterBankInfo.h"
0027 #include "llvm/CodeGen/TargetInstrInfo.h"
0028 #include "llvm/CodeGen/TargetOpcodes.h"
0029 #include "llvm/CodeGen/TargetRegisterInfo.h"
0030 #include "llvm/IR/Constants.h"
0031 #include "llvm/IR/DataLayout.h"
0032 #include "llvm/IR/Type.h"
0033 #include "llvm/Support/CodeGenCoverage.h"
0034 #include "llvm/Support/Debug.h"
0035 #include "llvm/Support/ErrorHandling.h"
0036 #include "llvm/Support/LEB128.h"
0037 #include "llvm/Support/raw_ostream.h"
0038 #include <cassert>
0039 #include <cstddef>
0040 #include <cstdint>
0041
0042 namespace llvm {
0043
0044 template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn,
0045 class CustomRendererFn>
0046 bool GIMatchTableExecutor::executeMatchTable(
0047 TgtExecutor &Exec, MatcherState &State,
0048 const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
0049 &ExecInfo,
0050 MachineIRBuilder &Builder, const uint8_t *MatchTable,
0051 const TargetInstrInfo &TII, MachineRegisterInfo &MRI,
0052 const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
0053 const PredicateBitset &AvailableFeatures,
0054 CodeGenCoverage *CoverageInfo) const {
0055
0056 uint64_t CurrentIdx = 0;
0057 SmallVector<uint64_t, 4> OnFailResumeAt;
0058 NewMIVector OutMIs;
0059
0060 GISelChangeObserver *Observer = Builder.getObserver();
0061
0062 bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
0063
0064 const uint16_t Flags = State.MIs[0]->getFlags();
0065
0066 enum RejectAction { RejectAndGiveUp, RejectAndResume };
0067 auto handleReject = [&]() -> RejectAction {
0068 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0069 dbgs() << CurrentIdx << ": Rejected\n");
0070 if (OnFailResumeAt.empty())
0071 return RejectAndGiveUp;
0072 CurrentIdx = OnFailResumeAt.pop_back_val();
0073 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0074 dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
0075 << OnFailResumeAt.size() << " try-blocks remain)\n");
0076 return RejectAndResume;
0077 };
0078
0079 const auto propagateFlags = [&]() {
0080 for (auto MIB : OutMIs) {
0081
0082
0083 uint16_t MIBFlags = Flags;
0084 if (NoFPException && MIB->mayRaiseFPException())
0085 MIBFlags |= MachineInstr::NoFPExcept;
0086 if (Observer)
0087 Observer->changingInstr(*MIB);
0088 MIB.setMIFlags(MIBFlags);
0089 if (Observer)
0090 Observer->changedInstr(*MIB);
0091 }
0092 };
0093
0094
0095
0096 const auto getTypeFromIdx = [&](int64_t Idx) -> LLT {
0097 if (Idx >= 0)
0098 return ExecInfo.TypeObjects[Idx];
0099 return State.RecordedTypes[1 - Idx];
0100 };
0101
0102 const auto readULEB = [&]() {
0103 return fastDecodeULEB128(MatchTable, CurrentIdx);
0104 };
0105
0106
0107
0108
0109
0110
0111 const auto readS8 = [&]() { return (int8_t)MatchTable[CurrentIdx++]; };
0112
0113 const auto readU16 = [&]() {
0114 auto V = readBytesAs<uint16_t>(MatchTable + CurrentIdx);
0115 CurrentIdx += 2;
0116 return V;
0117 };
0118
0119 const auto readU32 = [&]() {
0120 auto V = readBytesAs<uint32_t>(MatchTable + CurrentIdx);
0121 CurrentIdx += 4;
0122 return V;
0123 };
0124
0125 const auto readU64 = [&]() {
0126 auto V = readBytesAs<uint64_t>(MatchTable + CurrentIdx);
0127 CurrentIdx += 8;
0128 return V;
0129 };
0130
0131 const auto eraseImpl = [&](MachineInstr *MI) {
0132
0133
0134 if (Builder.getInsertPt() == MI)
0135 Builder.setInsertPt(*MI->getParent(), ++MI->getIterator());
0136 if (Observer)
0137 Observer->erasingInstr(*MI);
0138 MI->eraseFromParent();
0139 };
0140
0141 while (true) {
0142 assert(CurrentIdx != ~0u && "Invalid MatchTable index");
0143 uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
0144 switch (MatcherOpcode) {
0145 case GIM_Try: {
0146 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0147 dbgs() << CurrentIdx << ": Begin try-block\n");
0148 OnFailResumeAt.push_back(readU32());
0149 break;
0150 }
0151
0152 case GIM_RecordInsn:
0153 case GIM_RecordInsnIgnoreCopies: {
0154 uint64_t NewInsnID = readULEB();
0155 uint64_t InsnID = readULEB();
0156 uint64_t OpIdx = readULEB();
0157
0158
0159
0160 assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
0161
0162 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0163 if (!MO.isReg()) {
0164 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0165 dbgs() << CurrentIdx << ": Not a register\n");
0166 if (handleReject() == RejectAndGiveUp)
0167 return false;
0168 break;
0169 }
0170 if (MO.getReg().isPhysical()) {
0171 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0172 dbgs() << CurrentIdx << ": Is a physical register\n");
0173 if (handleReject() == RejectAndGiveUp)
0174 return false;
0175 break;
0176 }
0177
0178 MachineInstr *NewMI;
0179 if (MatcherOpcode == GIM_RecordInsnIgnoreCopies)
0180 NewMI = getDefIgnoringCopies(MO.getReg(), MRI);
0181 else
0182 NewMI = MRI.getVRegDef(MO.getReg());
0183
0184 if ((size_t)NewInsnID < State.MIs.size())
0185 State.MIs[NewInsnID] = NewMI;
0186 else {
0187 assert((size_t)NewInsnID == State.MIs.size() &&
0188 "Expected to store MIs in order");
0189 State.MIs.push_back(NewMI);
0190 }
0191 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0192 dbgs() << CurrentIdx << ": MIs[" << NewInsnID
0193 << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
0194 << ")\n");
0195 break;
0196 }
0197
0198 case GIM_CheckFeatures: {
0199 uint16_t ExpectedBitsetID = readU16();
0200 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0201 dbgs() << CurrentIdx
0202 << ": GIM_CheckFeatures(ExpectedBitsetID="
0203 << ExpectedBitsetID << ")\n");
0204 if ((AvailableFeatures & ExecInfo.FeatureBitsets[ExpectedBitsetID]) !=
0205 ExecInfo.FeatureBitsets[ExpectedBitsetID]) {
0206 if (handleReject() == RejectAndGiveUp)
0207 return false;
0208 }
0209 break;
0210 }
0211 case GIM_CheckOpcode:
0212 case GIM_CheckOpcodeIsEither: {
0213 uint64_t InsnID = readULEB();
0214 uint16_t Expected0 = readU16();
0215 uint16_t Expected1 = -1;
0216 if (MatcherOpcode == GIM_CheckOpcodeIsEither)
0217 Expected1 = readU16();
0218
0219 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0220 unsigned Opcode = State.MIs[InsnID]->getOpcode();
0221
0222 DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0223 dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
0224 << "], ExpectedOpcode=" << Expected0;
0225 if (MatcherOpcode == GIM_CheckOpcodeIsEither)
0226 dbgs() << " || " << Expected1;
0227 dbgs() << ") // Got=" << Opcode << "\n";
0228 });
0229
0230 if (Opcode != Expected0 && Opcode != Expected1) {
0231 if (handleReject() == RejectAndGiveUp)
0232 return false;
0233 }
0234 break;
0235 }
0236 case GIM_SwitchOpcode: {
0237 uint64_t InsnID = readULEB();
0238 uint16_t LowerBound = readU16();
0239 uint16_t UpperBound = readU16();
0240 uint32_t Default = readU32();
0241
0242 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0243 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
0244
0245 DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0246 dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
0247 << LowerBound << ", " << UpperBound << "), Default=" << Default
0248 << ", JumpTable...) // Got=" << Opcode << "\n";
0249 });
0250 if (Opcode < LowerBound || UpperBound <= Opcode) {
0251 CurrentIdx = Default;
0252 break;
0253 }
0254 const auto EntryIdx = (Opcode - LowerBound);
0255
0256 CurrentIdx =
0257 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (EntryIdx * 4));
0258 if (!CurrentIdx) {
0259 CurrentIdx = Default;
0260 break;
0261 }
0262 OnFailResumeAt.push_back(Default);
0263 break;
0264 }
0265
0266 case GIM_SwitchType: {
0267 uint64_t InsnID = readULEB();
0268 uint64_t OpIdx = readULEB();
0269 uint16_t LowerBound = readU16();
0270 uint16_t UpperBound = readU16();
0271 int64_t Default = readU32();
0272
0273 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0274 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0275
0276 DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0277 dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
0278 << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
0279 << UpperBound << "), Default=" << Default
0280 << ", JumpTable...) // Got=";
0281 if (!MO.isReg())
0282 dbgs() << "Not a VReg\n";
0283 else
0284 dbgs() << MRI.getType(MO.getReg()) << "\n";
0285 });
0286 if (!MO.isReg()) {
0287 CurrentIdx = Default;
0288 break;
0289 }
0290 const LLT Ty = MRI.getType(MO.getReg());
0291 const auto TyI = ExecInfo.TypeIDMap.find(Ty);
0292 if (TyI == ExecInfo.TypeIDMap.end()) {
0293 CurrentIdx = Default;
0294 break;
0295 }
0296 const int64_t TypeID = TyI->second;
0297 if (TypeID < LowerBound || UpperBound <= TypeID) {
0298 CurrentIdx = Default;
0299 break;
0300 }
0301 const auto NumEntry = (TypeID - LowerBound);
0302
0303 CurrentIdx =
0304 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (NumEntry * 4));
0305 if (!CurrentIdx) {
0306 CurrentIdx = Default;
0307 break;
0308 }
0309 OnFailResumeAt.push_back(Default);
0310 break;
0311 }
0312
0313 case GIM_CheckNumOperandsGE:
0314 case GIM_CheckNumOperandsLE: {
0315 uint64_t InsnID = readULEB();
0316 uint64_t Expected = readULEB();
0317 const bool IsLE = (MatcherOpcode == GIM_CheckNumOperandsLE);
0318 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0319 dbgs() << CurrentIdx << ": GIM_CheckNumOperands"
0320 << (IsLE ? "LE" : "GE") << "(MIs[" << InsnID
0321 << "], Expected=" << Expected << ")\n");
0322 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0323 const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
0324 if (IsLE ? (NumOps > Expected) : (NumOps < Expected)) {
0325 if (handleReject() == RejectAndGiveUp)
0326 return false;
0327 }
0328 break;
0329 }
0330 case GIM_CheckNumOperands: {
0331 uint64_t InsnID = readULEB();
0332 uint64_t Expected = readULEB();
0333 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0334 dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
0335 << InsnID << "], Expected=" << Expected << ")\n");
0336 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0337 if (State.MIs[InsnID]->getNumOperands() != Expected) {
0338 if (handleReject() == RejectAndGiveUp)
0339 return false;
0340 }
0341 break;
0342 }
0343 case GIM_CheckI64ImmPredicate:
0344 case GIM_CheckImmOperandPredicate: {
0345 uint64_t InsnID = readULEB();
0346 unsigned OpIdx =
0347 MatcherOpcode == GIM_CheckImmOperandPredicate ? readULEB() : 1;
0348 uint16_t Predicate = readU16();
0349 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0350 dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs["
0351 << InsnID << "]->getOperand(" << OpIdx
0352 << "), Predicate=" << Predicate << ")\n");
0353 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0354 assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
0355 State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
0356 "Expected immediate operand");
0357 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0358 int64_t Value = 0;
0359 if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
0360 Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
0361 else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
0362 Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
0363 else
0364 llvm_unreachable("Expected Imm or CImm operand");
0365
0366 if (!testImmPredicate_I64(Predicate, Value))
0367 if (handleReject() == RejectAndGiveUp)
0368 return false;
0369 break;
0370 }
0371 case GIM_CheckAPIntImmPredicate: {
0372 uint64_t InsnID = readULEB();
0373 uint16_t Predicate = readU16();
0374 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0375 dbgs()
0376 << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
0377 << InsnID << "], Predicate=" << Predicate << ")\n");
0378 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0379 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
0380 "Expected G_CONSTANT");
0381 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0382 if (!State.MIs[InsnID]->getOperand(1).isCImm())
0383 llvm_unreachable("Expected Imm or CImm operand");
0384
0385 const APInt &Value =
0386 State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
0387 if (!testImmPredicate_APInt(Predicate, Value))
0388 if (handleReject() == RejectAndGiveUp)
0389 return false;
0390 break;
0391 }
0392 case GIM_CheckAPFloatImmPredicate: {
0393 uint64_t InsnID = readULEB();
0394 uint16_t Predicate = readU16();
0395 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0396 dbgs()
0397 << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
0398 << InsnID << "], Predicate=" << Predicate << ")\n");
0399 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0400 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
0401 "Expected G_FCONSTANT");
0402 assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
0403 "Expected FPImm operand");
0404 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0405 const APFloat &Value =
0406 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
0407
0408 if (!testImmPredicate_APFloat(Predicate, Value))
0409 if (handleReject() == RejectAndGiveUp)
0410 return false;
0411 break;
0412 }
0413 case GIM_CheckIsBuildVectorAllOnes:
0414 case GIM_CheckIsBuildVectorAllZeros: {
0415 uint64_t InsnID = readULEB();
0416
0417 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0418 dbgs() << CurrentIdx
0419 << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
0420 << InsnID << "])\n");
0421 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0422
0423 const MachineInstr *MI = State.MIs[InsnID];
0424 assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
0425 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
0426 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
0427
0428 if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
0429 if (!isBuildVectorAllOnes(*MI, MRI)) {
0430 if (handleReject() == RejectAndGiveUp)
0431 return false;
0432 }
0433 } else {
0434 if (!isBuildVectorAllZeros(*MI, MRI)) {
0435 if (handleReject() == RejectAndGiveUp)
0436 return false;
0437 }
0438 }
0439
0440 break;
0441 }
0442 case GIM_CheckSimplePredicate: {
0443
0444
0445
0446 uint16_t Predicate = readU16();
0447 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0448 dbgs() << CurrentIdx
0449 << ": GIM_CheckSimplePredicate(Predicate="
0450 << Predicate << ")\n");
0451 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0452 if (!testSimplePredicate(Predicate)) {
0453 if (handleReject() == RejectAndGiveUp)
0454 return false;
0455 }
0456 break;
0457 }
0458 case GIM_CheckCxxInsnPredicate: {
0459 uint64_t InsnID = readULEB();
0460 uint16_t Predicate = readU16();
0461 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0462 dbgs()
0463 << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
0464 << InsnID << "], Predicate=" << Predicate << ")\n");
0465 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0466 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0467
0468 if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID], State))
0469 if (handleReject() == RejectAndGiveUp)
0470 return false;
0471 break;
0472 }
0473 case GIM_CheckHasNoUse: {
0474 uint64_t InsnID = readULEB();
0475
0476 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0477 dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs["
0478 << InsnID << "]\n");
0479
0480 const MachineInstr *MI = State.MIs[InsnID];
0481 assert(MI && "Used insn before defined");
0482 assert(MI->getNumDefs() > 0 && "No defs");
0483 const Register Res = MI->getOperand(0).getReg();
0484
0485 if (!MRI.use_nodbg_empty(Res)) {
0486 if (handleReject() == RejectAndGiveUp)
0487 return false;
0488 }
0489 break;
0490 }
0491 case GIM_CheckHasOneUse: {
0492 uint64_t InsnID = readULEB();
0493
0494 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0495 dbgs() << CurrentIdx << ": GIM_CheckHasOneUse(MIs["
0496 << InsnID << "]\n");
0497
0498 const MachineInstr *MI = State.MIs[InsnID];
0499 assert(MI && "Used insn before defined");
0500 assert(MI->getNumDefs() > 0 && "No defs");
0501 const Register Res = MI->getOperand(0).getReg();
0502
0503 if (!MRI.hasOneNonDBGUse(Res)) {
0504 if (handleReject() == RejectAndGiveUp)
0505 return false;
0506 }
0507 break;
0508 }
0509 case GIM_CheckAtomicOrdering: {
0510 uint64_t InsnID = readULEB();
0511 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0512 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0513 dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
0514 << InsnID << "], " << (uint64_t)Ordering << ")\n");
0515 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0516 if (!State.MIs[InsnID]->hasOneMemOperand())
0517 if (handleReject() == RejectAndGiveUp)
0518 return false;
0519
0520 for (const auto &MMO : State.MIs[InsnID]->memoperands())
0521 if (MMO->getMergedOrdering() != Ordering)
0522 if (handleReject() == RejectAndGiveUp)
0523 return false;
0524 break;
0525 }
0526 case GIM_CheckAtomicOrderingOrStrongerThan: {
0527 uint64_t InsnID = readULEB();
0528 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0529 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0530 dbgs() << CurrentIdx
0531 << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
0532 << InsnID << "], " << (uint64_t)Ordering << ")\n");
0533 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0534 if (!State.MIs[InsnID]->hasOneMemOperand())
0535 if (handleReject() == RejectAndGiveUp)
0536 return false;
0537
0538 for (const auto &MMO : State.MIs[InsnID]->memoperands())
0539 if (!isAtLeastOrStrongerThan(MMO->getMergedOrdering(), Ordering))
0540 if (handleReject() == RejectAndGiveUp)
0541 return false;
0542 break;
0543 }
0544 case GIM_CheckAtomicOrderingWeakerThan: {
0545 uint64_t InsnID = readULEB();
0546 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0547 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0548 dbgs() << CurrentIdx
0549 << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
0550 << InsnID << "], " << (uint64_t)Ordering << ")\n");
0551 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0552 if (!State.MIs[InsnID]->hasOneMemOperand())
0553 if (handleReject() == RejectAndGiveUp)
0554 return false;
0555
0556 for (const auto &MMO : State.MIs[InsnID]->memoperands())
0557 if (!isStrongerThan(Ordering, MMO->getMergedOrdering()))
0558 if (handleReject() == RejectAndGiveUp)
0559 return false;
0560 break;
0561 }
0562 case GIM_CheckMemoryAddressSpace: {
0563 uint64_t InsnID = readULEB();
0564 uint64_t MMOIdx = readULEB();
0565
0566 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
0567
0568 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0569 if (handleReject() == RejectAndGiveUp)
0570 return false;
0571 break;
0572 }
0573
0574
0575
0576 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
0577
0578 const MachineMemOperand *MMO =
0579 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0580 const unsigned MMOAddrSpace = MMO->getAddrSpace();
0581
0582 bool Success = false;
0583 for (unsigned I = 0; I != NumAddrSpace; ++I) {
0584 uint64_t AddrSpace = readULEB();
0585 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0586 dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
0587 << AddrSpace << '\n');
0588
0589 if (AddrSpace == MMOAddrSpace) {
0590 Success = true;
0591 break;
0592 }
0593 }
0594
0595 CurrentIdx = LastIdx;
0596 if (!Success && handleReject() == RejectAndGiveUp)
0597 return false;
0598 break;
0599 }
0600 case GIM_CheckMemoryAlignment: {
0601 uint64_t InsnID = readULEB();
0602 uint64_t MMOIdx = readULEB();
0603 uint64_t MinAlign = MatchTable[CurrentIdx++];
0604
0605 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0606
0607 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0608 if (handleReject() == RejectAndGiveUp)
0609 return false;
0610 break;
0611 }
0612
0613 MachineMemOperand *MMO =
0614 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0615 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0616 dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
0617 << "(MIs[" << InsnID << "]->memoperands() + "
0618 << MMOIdx << ")->getAlignment() >= " << MinAlign
0619 << ")\n");
0620 if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
0621 return false;
0622
0623 break;
0624 }
0625 case GIM_CheckMemorySizeEqualTo: {
0626 uint64_t InsnID = readULEB();
0627 uint64_t MMOIdx = readULEB();
0628 uint32_t Size = readU32();
0629
0630 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0631 dbgs() << CurrentIdx << ": GIM_CheckMemorySizeEqual(MIs["
0632 << InsnID << "]->memoperands() + " << MMOIdx
0633 << ", Size=" << Size << ")\n");
0634 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0635
0636 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0637 if (handleReject() == RejectAndGiveUp)
0638 return false;
0639 break;
0640 }
0641
0642 MachineMemOperand *MMO =
0643 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0644
0645 DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << MMO->getSize()
0646 << " bytes vs " << Size
0647 << " bytes\n");
0648 if (MMO->getSize() != Size)
0649 if (handleReject() == RejectAndGiveUp)
0650 return false;
0651
0652 break;
0653 }
0654 case GIM_CheckMemorySizeEqualToLLT:
0655 case GIM_CheckMemorySizeLessThanLLT:
0656 case GIM_CheckMemorySizeGreaterThanLLT: {
0657 uint64_t InsnID = readULEB();
0658 uint64_t MMOIdx = readULEB();
0659 uint64_t OpIdx = readULEB();
0660
0661 DEBUG_WITH_TYPE(
0662 TgtExecutor::getName(),
0663 dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
0664 << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT ? "EqualTo"
0665 : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
0666 ? "GreaterThan"
0667 : "LessThan")
0668 << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
0669 << ", OpIdx=" << OpIdx << ")\n");
0670 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0671
0672 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0673 if (!MO.isReg()) {
0674 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0675 dbgs() << CurrentIdx << ": Not a register\n");
0676 if (handleReject() == RejectAndGiveUp)
0677 return false;
0678 break;
0679 }
0680
0681 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0682 if (handleReject() == RejectAndGiveUp)
0683 return false;
0684 break;
0685 }
0686
0687 MachineMemOperand *MMO =
0688 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0689
0690 const TypeSize Size = MRI.getType(MO.getReg()).getSizeInBits();
0691 if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
0692 MMO->getSizeInBits() != Size) {
0693 if (handleReject() == RejectAndGiveUp)
0694 return false;
0695 } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
0696 TypeSize::isKnownGE(MMO->getSizeInBits().getValue(), Size)) {
0697 if (handleReject() == RejectAndGiveUp)
0698 return false;
0699 } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
0700 TypeSize::isKnownLE(MMO->getSizeInBits().getValue(), Size))
0701 if (handleReject() == RejectAndGiveUp)
0702 return false;
0703
0704 break;
0705 }
0706 case GIM_RootCheckType:
0707 case GIM_CheckType: {
0708 uint64_t InsnID = (MatcherOpcode == GIM_RootCheckType) ? 0 : readULEB();
0709 uint64_t OpIdx = readULEB();
0710 int TypeID = readS8();
0711 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0712 dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
0713 << "]->getOperand(" << OpIdx
0714 << "), TypeID=" << TypeID << ")\n");
0715 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0716 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0717 if (!MO.isReg() || MRI.getType(MO.getReg()) != getTypeFromIdx(TypeID)) {
0718 if (handleReject() == RejectAndGiveUp)
0719 return false;
0720 }
0721 break;
0722 }
0723 case GIM_CheckPointerToAny: {
0724 uint64_t InsnID = readULEB();
0725 uint64_t OpIdx = readULEB();
0726 uint64_t SizeInBits = readULEB();
0727
0728 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0729 dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
0730 << InsnID << "]->getOperand(" << OpIdx
0731 << "), SizeInBits=" << SizeInBits << ")\n");
0732 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0733 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0734 const LLT Ty = MRI.getType(MO.getReg());
0735
0736
0737 if (SizeInBits == 0) {
0738 MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
0739 const unsigned AddrSpace = Ty.getAddressSpace();
0740 SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
0741 }
0742
0743 assert(SizeInBits != 0 && "Pointer size must be known");
0744
0745 if (MO.isReg()) {
0746 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
0747 if (handleReject() == RejectAndGiveUp)
0748 return false;
0749 } else if (handleReject() == RejectAndGiveUp)
0750 return false;
0751
0752 break;
0753 }
0754 case GIM_RecordNamedOperand: {
0755 uint64_t InsnID = readULEB();
0756 uint64_t OpIdx = readULEB();
0757 uint64_t StoreIdx = readULEB();
0758
0759 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0760 dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
0761 << InsnID << "]->getOperand(" << OpIdx
0762 << "), StoreIdx=" << StoreIdx << ")\n");
0763 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0764 assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
0765 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
0766 break;
0767 }
0768 case GIM_RecordRegType: {
0769 uint64_t InsnID = readULEB();
0770 uint64_t OpIdx = readULEB();
0771 int TypeIdx = readS8();
0772
0773 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0774 dbgs() << CurrentIdx << ": GIM_RecordRegType(MIs["
0775 << InsnID << "]->getOperand(" << OpIdx
0776 << "), TypeIdx=" << TypeIdx << ")\n");
0777 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0778 assert(TypeIdx < 0 && "Temp types always have negative indexes!");
0779
0780 TypeIdx = 1 - TypeIdx;
0781 const auto &Op = State.MIs[InsnID]->getOperand(OpIdx);
0782 if (State.RecordedTypes.size() <= (uint64_t)TypeIdx)
0783 State.RecordedTypes.resize(TypeIdx + 1, LLT());
0784 State.RecordedTypes[TypeIdx] = MRI.getType(Op.getReg());
0785 break;
0786 }
0787
0788 case GIM_RootCheckRegBankForClass:
0789 case GIM_CheckRegBankForClass: {
0790 uint64_t InsnID =
0791 (MatcherOpcode == GIM_RootCheckRegBankForClass) ? 0 : readULEB();
0792 uint64_t OpIdx = readULEB();
0793 uint16_t RCEnum = readU16();
0794 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0795 dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
0796 << InsnID << "]->getOperand(" << OpIdx
0797 << "), RCEnum=" << RCEnum << ")\n");
0798 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0799 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0800 if (!MO.isReg() ||
0801 &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
0802 MRI.getType(MO.getReg())) !=
0803 RBI.getRegBank(MO.getReg(), MRI, TRI)) {
0804 if (handleReject() == RejectAndGiveUp)
0805 return false;
0806 }
0807 break;
0808 }
0809
0810 case GIM_CheckComplexPattern: {
0811 uint64_t InsnID = readULEB();
0812 uint64_t OpIdx = readULEB();
0813 uint16_t RendererID = readU16();
0814 uint16_t ComplexPredicateID = readU16();
0815 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0816 dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
0817 << "] = GIM_CheckComplexPattern(MIs[" << InsnID
0818 << "]->getOperand(" << OpIdx
0819 << "), ComplexPredicateID=" << ComplexPredicateID
0820 << ")\n");
0821 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0822
0823 ComplexRendererFns Renderer =
0824 (Exec.*ExecInfo.ComplexPredicates[ComplexPredicateID])(
0825 State.MIs[InsnID]->getOperand(OpIdx));
0826 if (Renderer)
0827 State.Renderers[RendererID] = *Renderer;
0828 else if (handleReject() == RejectAndGiveUp)
0829 return false;
0830 break;
0831 }
0832
0833 case GIM_CheckConstantInt:
0834 case GIM_CheckConstantInt8: {
0835 const bool IsInt8 = (MatcherOpcode == GIM_CheckConstantInt8);
0836
0837 uint64_t InsnID = readULEB();
0838 uint64_t OpIdx = readULEB();
0839 uint64_t Value = IsInt8 ? (int64_t)readS8() : readU64();
0840 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0841 dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
0842 << InsnID << "]->getOperand(" << OpIdx
0843 << "), Value=" << Value << ")\n");
0844 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0845 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0846 if (MO.isReg()) {
0847
0848 LLT Ty = MRI.getType(MO.getReg());
0849
0850
0851 if (Ty.getScalarSizeInBits() > 64) {
0852 if (handleReject() == RejectAndGiveUp)
0853 return false;
0854 break;
0855 }
0856
0857 Value = SignExtend64(Value, Ty.getScalarSizeInBits());
0858 if (!isOperandImmEqual(MO, Value, MRI, true)) {
0859 if (handleReject() == RejectAndGiveUp)
0860 return false;
0861 }
0862 } else if (handleReject() == RejectAndGiveUp)
0863 return false;
0864
0865 break;
0866 }
0867
0868 case GIM_CheckLiteralInt: {
0869 uint64_t InsnID = readULEB();
0870 uint64_t OpIdx = readULEB();
0871 int64_t Value = readU64();
0872 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0873 dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
0874 << InsnID << "]->getOperand(" << OpIdx
0875 << "), Value=" << Value << ")\n");
0876 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0877 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0878 if (MO.isImm() && MO.getImm() == Value)
0879 break;
0880
0881 if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
0882 break;
0883
0884 if (handleReject() == RejectAndGiveUp)
0885 return false;
0886
0887 break;
0888 }
0889
0890 case GIM_CheckIntrinsicID: {
0891 uint64_t InsnID = readULEB();
0892 uint64_t OpIdx = readULEB();
0893 uint16_t Value = readU16();
0894 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0895 dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
0896 << InsnID << "]->getOperand(" << OpIdx
0897 << "), Value=" << Value << ")\n");
0898 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0899 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0900 if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
0901 if (handleReject() == RejectAndGiveUp)
0902 return false;
0903 break;
0904 }
0905 case GIM_CheckCmpPredicate: {
0906 uint64_t InsnID = readULEB();
0907 uint64_t OpIdx = readULEB();
0908 uint16_t Value = readU16();
0909 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0910 dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
0911 << InsnID << "]->getOperand(" << OpIdx
0912 << "), Value=" << Value << ")\n");
0913 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0914 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0915 if (!MO.isPredicate() || MO.getPredicate() != Value)
0916 if (handleReject() == RejectAndGiveUp)
0917 return false;
0918 break;
0919 }
0920 case GIM_CheckIsMBB: {
0921 uint64_t InsnID = readULEB();
0922 uint64_t OpIdx = readULEB();
0923 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0924 dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
0925 << "]->getOperand(" << OpIdx << "))\n");
0926 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0927 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
0928 if (handleReject() == RejectAndGiveUp)
0929 return false;
0930 }
0931 break;
0932 }
0933 case GIM_CheckIsImm: {
0934 uint64_t InsnID = readULEB();
0935 uint64_t OpIdx = readULEB();
0936 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0937 dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
0938 << "]->getOperand(" << OpIdx << "))\n");
0939 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0940 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
0941 if (handleReject() == RejectAndGiveUp)
0942 return false;
0943 }
0944 break;
0945 }
0946 case GIM_CheckIsSafeToFold: {
0947 uint64_t NumInsn = MatchTable[CurrentIdx++];
0948 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0949 dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(N = "
0950 << NumInsn << ")\n");
0951 MachineInstr &Root = *State.MIs[0];
0952 for (unsigned K = 1, E = NumInsn + 1; K < E; ++K) {
0953 if (!isObviouslySafeToFold(*State.MIs[K], Root)) {
0954 if (handleReject() == RejectAndGiveUp)
0955 return false;
0956 }
0957 }
0958 break;
0959 }
0960 case GIM_CheckIsSameOperand:
0961 case GIM_CheckIsSameOperandIgnoreCopies: {
0962 uint64_t InsnID = readULEB();
0963 uint64_t OpIdx = readULEB();
0964 uint64_t OtherInsnID = readULEB();
0965 uint64_t OtherOpIdx = readULEB();
0966 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0967 dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
0968 << InsnID << "][" << OpIdx << "], MIs["
0969 << OtherInsnID << "][" << OtherOpIdx << "])\n");
0970 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0971 assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
0972
0973 MachineOperand &Op = State.MIs[InsnID]->getOperand(OpIdx);
0974 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
0975
0976 if (MatcherOpcode == GIM_CheckIsSameOperandIgnoreCopies) {
0977 if (Op.isReg() && OtherOp.isReg()) {
0978 if (getSrcRegIgnoringCopies(Op.getReg(), MRI) ==
0979 getSrcRegIgnoringCopies(OtherOp.getReg(), MRI))
0980 break;
0981 }
0982 }
0983
0984 if (!Op.isIdenticalTo(OtherOp)) {
0985 if (handleReject() == RejectAndGiveUp)
0986 return false;
0987 }
0988 break;
0989 }
0990 case GIM_CheckCanReplaceReg: {
0991 uint64_t OldInsnID = readULEB();
0992 uint64_t OldOpIdx = readULEB();
0993 uint64_t NewInsnID = readULEB();
0994 uint64_t NewOpIdx = readULEB();
0995
0996 DEBUG_WITH_TYPE(TgtExecutor::getName(),
0997 dbgs() << CurrentIdx << ": GIM_CheckCanReplaceReg(MIs["
0998 << OldInsnID << "][" << OldOpIdx << "] = MIs["
0999 << NewInsnID << "][" << NewOpIdx << "])\n");
1000
1001 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1002 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1003 if (!canReplaceReg(Old, New, MRI)) {
1004 if (handleReject() == RejectAndGiveUp)
1005 return false;
1006 }
1007 break;
1008 }
1009 case GIM_MIFlags: {
1010 uint64_t InsnID = readULEB();
1011 uint32_t Flags = readU32();
1012
1013 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1014 dbgs() << CurrentIdx << ": GIM_MIFlags(MIs[" << InsnID
1015 << "], " << Flags << ")\n");
1016 if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1017 if (handleReject() == RejectAndGiveUp)
1018 return false;
1019 }
1020 break;
1021 }
1022 case GIM_MIFlagsNot: {
1023 uint64_t InsnID = readULEB();
1024 uint32_t Flags = readU32();
1025
1026 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1027 dbgs() << CurrentIdx << ": GIM_MIFlagsNot(MIs[" << InsnID
1028 << "], " << Flags << ")\n");
1029 if ((State.MIs[InsnID]->getFlags() & Flags)) {
1030 if (handleReject() == RejectAndGiveUp)
1031 return false;
1032 }
1033 break;
1034 }
1035 case GIM_Reject:
1036 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1037 dbgs() << CurrentIdx << ": GIM_Reject\n");
1038 if (handleReject() == RejectAndGiveUp)
1039 return false;
1040 break;
1041 case GIR_MutateOpcode: {
1042 uint64_t OldInsnID = readULEB();
1043 uint64_t NewInsnID = readULEB();
1044 uint16_t NewOpcode = readU16();
1045 if (NewInsnID >= OutMIs.size())
1046 OutMIs.resize(NewInsnID + 1);
1047
1048 MachineInstr *OldMI = State.MIs[OldInsnID];
1049 if (Observer)
1050 Observer->changingInstr(*OldMI);
1051 OutMIs[NewInsnID] = MachineInstrBuilder(*OldMI->getMF(), OldMI);
1052 OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
1053 if (Observer)
1054 Observer->changedInstr(*OldMI);
1055 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1056 dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
1057 << NewInsnID << "], MIs[" << OldInsnID << "], "
1058 << NewOpcode << ")\n");
1059 break;
1060 }
1061
1062 case GIR_BuildRootMI:
1063 case GIR_BuildMI: {
1064 uint64_t NewInsnID = (MatcherOpcode == GIR_BuildRootMI) ? 0 : readULEB();
1065 uint16_t Opcode = readU16();
1066 if (NewInsnID >= OutMIs.size())
1067 OutMIs.resize(NewInsnID + 1);
1068
1069 OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1070 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1071 dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
1072 << NewInsnID << "], " << Opcode << ")\n");
1073 break;
1074 }
1075
1076 case GIR_BuildConstant: {
1077 uint64_t TempRegID = readULEB();
1078 uint64_t Imm = readU64();
1079 Builder.buildConstant(State.TempRegisters[TempRegID], Imm);
1080 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1081 dbgs() << CurrentIdx << ": GIR_BuildConstant(TempReg["
1082 << TempRegID << "], Imm=" << Imm << ")\n");
1083 break;
1084 }
1085
1086 case GIR_RootToRootCopy:
1087 case GIR_Copy: {
1088 uint64_t NewInsnID =
1089 (MatcherOpcode == GIR_RootToRootCopy) ? 0 : readULEB();
1090 uint64_t OldInsnID =
1091 (MatcherOpcode == GIR_RootToRootCopy) ? 0 : readULEB();
1092 uint64_t OpIdx = readULEB();
1093 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1094 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
1095 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1096 dbgs()
1097 << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
1098 << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
1099 break;
1100 }
1101
1102 case GIR_CopyRemaining: {
1103 uint64_t NewInsnID = readULEB();
1104 uint64_t OldInsnID = readULEB();
1105 uint64_t OpIdx = readULEB();
1106 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1107 MachineInstr &OldMI = *State.MIs[OldInsnID];
1108 MachineInstrBuilder &NewMI = OutMIs[NewInsnID];
1109 for (const auto &Op : drop_begin(OldMI.operands(), OpIdx))
1110 NewMI.add(Op);
1111 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1112 dbgs() << CurrentIdx << ": GIR_CopyRemaining(OutMIs["
1113 << NewInsnID << "], MIs[" << OldInsnID
1114 << "], /*start=*/" << OpIdx << ")\n");
1115 break;
1116 }
1117
1118 case GIR_CopyOrAddZeroReg: {
1119 uint64_t NewInsnID = readULEB();
1120 uint64_t OldInsnID = readULEB();
1121 uint64_t OpIdx = readULEB();
1122 uint16_t ZeroReg = readU16();
1123 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1124 MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
1125 if (isOperandImmEqual(MO, 0, MRI))
1126 OutMIs[NewInsnID].addReg(ZeroReg);
1127 else
1128 OutMIs[NewInsnID].add(MO);
1129 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1130 dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
1131 << NewInsnID << "], MIs[" << OldInsnID << "], "
1132 << OpIdx << ", " << ZeroReg << ")\n");
1133 break;
1134 }
1135
1136 case GIR_CopySubReg: {
1137 uint64_t NewInsnID = readULEB();
1138 uint64_t OldInsnID = readULEB();
1139 uint64_t OpIdx = readULEB();
1140 uint16_t SubRegIdx = readU16();
1141 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1142 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1143 0, SubRegIdx);
1144 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1145 dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
1146 << NewInsnID << "], MIs[" << OldInsnID << "], "
1147 << OpIdx << ", " << SubRegIdx << ")\n");
1148 break;
1149 }
1150
1151 case GIR_AddImplicitDef: {
1152 uint64_t InsnID = readULEB();
1153 uint16_t RegNum = readU16();
1154 uint16_t Flags = readU16();
1155 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1156 Flags |= RegState::Implicit;
1157 OutMIs[InsnID].addDef(RegNum, Flags);
1158 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1159 dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
1160 << InsnID << "], " << RegNum << ")\n");
1161 break;
1162 }
1163
1164 case GIR_AddImplicitUse: {
1165 uint64_t InsnID = readULEB();
1166 uint16_t RegNum = readU16();
1167 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1168 OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
1169 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1170 dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
1171 << InsnID << "], " << RegNum << ")\n");
1172 break;
1173 }
1174
1175 case GIR_AddRegister: {
1176 uint64_t InsnID = readULEB();
1177 uint16_t RegNum = readU16();
1178 uint16_t RegFlags = readU16();
1179 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1180 OutMIs[InsnID].addReg(RegNum, RegFlags);
1181 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1182 dbgs()
1183 << CurrentIdx << ": GIR_AddRegister(OutMIs[" << InsnID
1184 << "], " << RegNum << ", " << RegFlags << ")\n");
1185 break;
1186 }
1187 case GIR_AddIntrinsicID: {
1188 uint64_t InsnID = readULEB();
1189 uint16_t Value = readU16();
1190 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1191 OutMIs[InsnID].addIntrinsicID((Intrinsic::ID)Value);
1192 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1193 dbgs() << CurrentIdx << ": GIR_AddIntrinsicID(OutMIs["
1194 << InsnID << "], " << Value << ")\n");
1195 break;
1196 }
1197 case GIR_SetImplicitDefDead: {
1198 uint64_t InsnID = readULEB();
1199 uint64_t OpIdx = readULEB();
1200 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1201 dbgs() << CurrentIdx << ": GIR_SetImplicitDefDead(OutMIs["
1202 << InsnID << "], OpIdx=" << OpIdx << ")\n");
1203 MachineInstr *MI = OutMIs[InsnID];
1204 assert(MI && "Modifying undefined instruction");
1205 MI->getOperand(MI->getNumExplicitOperands() + OpIdx).setIsDead();
1206 break;
1207 }
1208 case GIR_SetMIFlags: {
1209 uint64_t InsnID = readULEB();
1210 uint32_t Flags = readU32();
1211
1212 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1213 dbgs() << CurrentIdx << ": GIR_SetMIFlags(OutMIs["
1214 << InsnID << "], " << Flags << ")\n");
1215 MachineInstr *MI = OutMIs[InsnID];
1216 MI->setFlags(MI->getFlags() | Flags);
1217 break;
1218 }
1219 case GIR_UnsetMIFlags: {
1220 uint64_t InsnID = readULEB();
1221 uint32_t Flags = readU32();
1222
1223 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1224 dbgs() << CurrentIdx << ": GIR_UnsetMIFlags(OutMIs["
1225 << InsnID << "], " << Flags << ")\n");
1226 MachineInstr *MI = OutMIs[InsnID];
1227 MI->setFlags(MI->getFlags() & ~Flags);
1228 break;
1229 }
1230 case GIR_CopyMIFlags: {
1231 uint64_t InsnID = readULEB();
1232 uint64_t OldInsnID = readULEB();
1233
1234 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1235 dbgs() << CurrentIdx << ": GIR_CopyMIFlags(OutMIs["
1236 << InsnID << "], MIs[" << OldInsnID << "])\n");
1237 MachineInstr *MI = OutMIs[InsnID];
1238 MI->setFlags(MI->getFlags() | State.MIs[OldInsnID]->getFlags());
1239 break;
1240 }
1241 case GIR_AddSimpleTempRegister:
1242 case GIR_AddTempRegister:
1243 case GIR_AddTempSubRegister: {
1244 uint64_t InsnID = readULEB();
1245 uint64_t TempRegID = readULEB();
1246 uint16_t TempRegFlags = 0;
1247 if (MatcherOpcode != GIR_AddSimpleTempRegister)
1248 TempRegFlags = readU16();
1249 uint16_t SubReg = 0;
1250 if (MatcherOpcode == GIR_AddTempSubRegister)
1251 SubReg = readU16();
1252
1253 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1254
1255 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1256 SubReg);
1257 DEBUG_WITH_TYPE(
1258 TgtExecutor::getName(),
1259 dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" << InsnID
1260 << "], TempRegisters[" << TempRegID << "]";
1261 if (SubReg) dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
1262 dbgs() << ", " << TempRegFlags << ")\n");
1263 break;
1264 }
1265
1266 case GIR_AddImm8:
1267 case GIR_AddImm: {
1268 const bool IsAdd8 = (MatcherOpcode == GIR_AddImm8);
1269 uint64_t InsnID = readULEB();
1270 uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1271 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1272 OutMIs[InsnID].addImm(Imm);
1273 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1274 dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
1275 << "], " << Imm << ")\n");
1276 break;
1277 }
1278
1279 case GIR_AddCImm: {
1280 uint64_t InsnID = readULEB();
1281 int TypeID = readS8();
1282 uint64_t Imm = readU64();
1283 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1284
1285 unsigned Width = ExecInfo.TypeObjects[TypeID].getScalarSizeInBits();
1286 LLVMContext &Ctx = MF->getFunction().getContext();
1287 OutMIs[InsnID].addCImm(
1288 ConstantInt::get(IntegerType::get(Ctx, Width), Imm, true));
1289 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1290 dbgs() << CurrentIdx << ": GIR_AddCImm(OutMIs[" << InsnID
1291 << "], TypeID=" << TypeID << ", Imm=" << Imm
1292 << ")\n");
1293 break;
1294 }
1295
1296 case GIR_ComplexRenderer: {
1297 uint64_t InsnID = readULEB();
1298 uint16_t RendererID = readU16();
1299 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1300 for (const auto &RenderOpFn : State.Renderers[RendererID])
1301 RenderOpFn(OutMIs[InsnID]);
1302 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1303 dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
1304 << InsnID << "], " << RendererID << ")\n");
1305 break;
1306 }
1307 case GIR_ComplexSubOperandRenderer: {
1308 uint64_t InsnID = readULEB();
1309 uint16_t RendererID = readU16();
1310 uint64_t RenderOpID = readULEB();
1311 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1312 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1313 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1314 dbgs() << CurrentIdx
1315 << ": GIR_ComplexSubOperandRenderer(OutMIs["
1316 << InsnID << "], " << RendererID << ", "
1317 << RenderOpID << ")\n");
1318 break;
1319 }
1320 case GIR_ComplexSubOperandSubRegRenderer: {
1321 uint64_t InsnID = readULEB();
1322 uint16_t RendererID = readU16();
1323 uint64_t RenderOpID = readULEB();
1324 uint16_t SubRegIdx = readU16();
1325 MachineInstrBuilder &MI = OutMIs[InsnID];
1326 assert(MI && "Attempted to add to undefined instruction");
1327 State.Renderers[RendererID][RenderOpID](MI);
1328 MI->getOperand(MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1329 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1330 dbgs() << CurrentIdx
1331 << ": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1332 << InsnID << "], " << RendererID << ", "
1333 << RenderOpID << ", " << SubRegIdx << ")\n");
1334 break;
1335 }
1336
1337 case GIR_CopyConstantAsSImm: {
1338 uint64_t NewInsnID = readULEB();
1339 uint64_t OldInsnID = readULEB();
1340 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1341 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1342 "Expected G_CONSTANT");
1343 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1344 OutMIs[NewInsnID].addImm(
1345 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1346 } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1347 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1348 else
1349 llvm_unreachable("Expected Imm or CImm operand");
1350 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1351 dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
1352 << NewInsnID << "], MIs[" << OldInsnID << "])\n");
1353 break;
1354 }
1355
1356
1357 case GIR_CopyFConstantAsFPImm: {
1358 uint64_t NewInsnID = readULEB();
1359 uint64_t OldInsnID = readULEB();
1360 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1361 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1362 "Expected G_FCONSTANT");
1363 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1364 OutMIs[NewInsnID].addFPImm(
1365 State.MIs[OldInsnID]->getOperand(1).getFPImm());
1366 else
1367 llvm_unreachable("Expected FPImm operand");
1368 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1369 dbgs()
1370 << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
1371 << NewInsnID << "], MIs[" << OldInsnID << "])\n");
1372 break;
1373 }
1374
1375 case GIR_CustomRenderer: {
1376 uint64_t InsnID = readULEB();
1377 uint64_t OldInsnID = readULEB();
1378 uint16_t RendererFnID = readU16();
1379 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1380 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1381 dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
1382 << InsnID << "], MIs[" << OldInsnID << "], "
1383 << RendererFnID << ")\n");
1384 (Exec.*ExecInfo.CustomRenderers[RendererFnID])(
1385 OutMIs[InsnID], *State.MIs[OldInsnID],
1386 -1);
1387 break;
1388 }
1389 case GIR_DoneWithCustomAction: {
1390 uint16_t FnID = readU16();
1391 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1392 dbgs() << CurrentIdx << ": GIR_DoneWithCustomAction(FnID="
1393 << FnID << ")\n");
1394 assert(FnID > GICXXCustomAction_Invalid && "Expected a valid FnID");
1395 if (runCustomAction(FnID, State, OutMIs)) {
1396 propagateFlags();
1397 return true;
1398 }
1399
1400 if (handleReject() == RejectAndGiveUp)
1401 return false;
1402 break;
1403 }
1404 case GIR_CustomOperandRenderer: {
1405 uint64_t InsnID = readULEB();
1406 uint64_t OldInsnID = readULEB();
1407 uint64_t OpIdx = readULEB();
1408 uint16_t RendererFnID = readU16();
1409 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1410
1411 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1412 dbgs() << CurrentIdx
1413 << ": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1414 << "], MIs[" << OldInsnID << "]->getOperand("
1415 << OpIdx << "), " << RendererFnID << ")\n");
1416 (Exec.*ExecInfo.CustomRenderers[RendererFnID])(
1417 OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx);
1418 break;
1419 }
1420 case GIR_ConstrainOperandRC: {
1421 uint64_t InsnID = readULEB();
1422 uint64_t OpIdx = readULEB();
1423 uint16_t RCEnum = readU16();
1424 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1425 MachineInstr &I = *OutMIs[InsnID].getInstr();
1426 MachineFunction &MF = *I.getParent()->getParent();
1427 MachineRegisterInfo &MRI = MF.getRegInfo();
1428 const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
1429 MachineOperand &MO = I.getOperand(OpIdx);
1430 constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
1431 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1432 dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
1433 << InsnID << "], " << OpIdx << ", " << RCEnum
1434 << ")\n");
1435 break;
1436 }
1437
1438 case GIR_RootConstrainSelectedInstOperands:
1439 case GIR_ConstrainSelectedInstOperands: {
1440 uint64_t InsnID = (MatcherOpcode == GIR_RootConstrainSelectedInstOperands)
1441 ? 0
1442 : readULEB();
1443 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1444 constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
1445 RBI);
1446 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1447 dbgs() << CurrentIdx
1448 << ": GIR_ConstrainSelectedInstOperands(OutMIs["
1449 << InsnID << "])\n");
1450 break;
1451 }
1452 case GIR_MergeMemOperands: {
1453 uint64_t InsnID = readULEB();
1454 uint64_t NumInsn = MatchTable[CurrentIdx++];
1455 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1456
1457 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1458 dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
1459 << InsnID << "]");
1460 for (unsigned K = 0; K < NumInsn; ++K) {
1461 uint64_t NextID = readULEB();
1462 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1463 dbgs() << ", MIs[" << NextID << "]");
1464 for (const auto &MMO : State.MIs[NextID]->memoperands())
1465 OutMIs[InsnID].addMemOperand(MMO);
1466 }
1467 DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << ")\n");
1468 break;
1469 }
1470 case GIR_EraseFromParent: {
1471 uint64_t InsnID = readULEB();
1472 MachineInstr *MI = State.MIs[InsnID];
1473 assert(MI && "Attempted to erase an undefined instruction");
1474 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1475 dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
1476 << InsnID << "])\n");
1477 eraseImpl(MI);
1478 break;
1479 }
1480 case GIR_EraseRootFromParent_Done: {
1481 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1482 dbgs()
1483 << CurrentIdx << ": GIR_EraseRootFromParent_Done\n");
1484 eraseImpl(State.MIs[0]);
1485 propagateFlags();
1486 return true;
1487 }
1488 case GIR_MakeTempReg: {
1489 uint64_t TempRegID = readULEB();
1490 int TypeID = readS8();
1491
1492 State.TempRegisters[TempRegID] =
1493 MRI.createGenericVirtualRegister(getTypeFromIdx(TypeID));
1494 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1495 dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
1496 << "] = GIR_MakeTempReg(" << TypeID << ")\n");
1497 break;
1498 }
1499 case GIR_ReplaceReg: {
1500 uint64_t OldInsnID = readULEB();
1501 uint64_t OldOpIdx = readULEB();
1502 uint64_t NewInsnID = readULEB();
1503 uint64_t NewOpIdx = readULEB();
1504
1505 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1506 dbgs() << CurrentIdx << ": GIR_ReplaceReg(MIs["
1507 << OldInsnID << "][" << OldOpIdx << "] = MIs["
1508 << NewInsnID << "][" << NewOpIdx << "])\n");
1509
1510 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1511 Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1512 if (Observer)
1513 Observer->changingAllUsesOfReg(MRI, Old);
1514 MRI.replaceRegWith(Old, New);
1515 if (Observer)
1516 Observer->finishedChangingAllUsesOfReg();
1517 break;
1518 }
1519 case GIR_ReplaceRegWithTempReg: {
1520 uint64_t OldInsnID = readULEB();
1521 uint64_t OldOpIdx = readULEB();
1522 uint64_t TempRegID = readULEB();
1523
1524 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1525 dbgs() << CurrentIdx << ": GIR_ReplaceRegWithTempReg(MIs["
1526 << OldInsnID << "][" << OldOpIdx << "] = TempRegs["
1527 << TempRegID << "])\n");
1528
1529 Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1530 Register New = State.TempRegisters[TempRegID];
1531 if (Observer)
1532 Observer->changingAllUsesOfReg(MRI, Old);
1533 MRI.replaceRegWith(Old, New);
1534 if (Observer)
1535 Observer->finishedChangingAllUsesOfReg();
1536 break;
1537 }
1538 case GIR_Coverage: {
1539 uint32_t RuleID = readU32();
1540 assert(CoverageInfo);
1541 CoverageInfo->setCovered(RuleID);
1542
1543 DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx
1544 << ": GIR_Coverage("
1545 << RuleID << ")");
1546 break;
1547 }
1548
1549 case GIR_Done:
1550 DEBUG_WITH_TYPE(TgtExecutor::getName(),
1551 dbgs() << CurrentIdx << ": GIR_Done\n");
1552 propagateFlags();
1553 return true;
1554 default:
1555 llvm_unreachable("Unexpected command");
1556 }
1557 }
1558 }
1559
1560 }
1561
1562 #endif