1 //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file This file implements GIMatchTableExecutor's `executeMatchTable` 10 /// function. This is implemented in a separate file because the function is 11 /// quite large. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H 16 #define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H 17 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" 20 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 21 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 22 #include "llvm/CodeGen/GlobalISel/Utils.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineOperand.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/RegisterBankInfo.h" 27 #include "llvm/CodeGen/TargetInstrInfo.h" 28 #include "llvm/CodeGen/TargetOpcodes.h" 29 #include "llvm/CodeGen/TargetRegisterInfo.h" 30 #include "llvm/IR/Constants.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/Type.h" 33 #include "llvm/Support/CodeGenCoverage.h" 34 #include "llvm/Support/Debug.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/LEB128.h" 37 #include "llvm/Support/raw_ostream.h" 38 #include <cassert> 39 #include <cstddef> 40 #include <cstdint> 41 42 namespace llvm { 43 44 template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn, 45 class CustomRendererFn> 46 bool GIMatchTableExecutor::executeMatchTable( 47 TgtExecutor &Exec, MatcherState &State, 48 const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> 49 &ExecInfo, 50 MachineIRBuilder &Builder, const uint8_t *MatchTable, 51 const TargetInstrInfo &TII, MachineRegisterInfo &MRI, 52 const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI, 53 const PredicateBitset &AvailableFeatures, 54 CodeGenCoverage *CoverageInfo) const { 55 56 uint64_t CurrentIdx = 0; 57 SmallVector<uint64_t, 4> OnFailResumeAt; 58 NewMIVector OutMIs; 59 60 GISelChangeObserver *Observer = Builder.getObserver(); 61 // Bypass the flag check on the instruction, and only look at the MCInstrDesc. 62 bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException(); 63 64 const uint16_t Flags = State.MIs[0]->getFlags(); 65 66 enum RejectAction { RejectAndGiveUp, RejectAndResume }; 67 auto handleReject = [&]() -> RejectAction { 68 DEBUG_WITH_TYPE(TgtExecutor::getName(), 69 dbgs() << CurrentIdx << ": Rejected\n"); 70 if (OnFailResumeAt.empty()) 71 return RejectAndGiveUp; 72 CurrentIdx = OnFailResumeAt.pop_back_val(); 73 DEBUG_WITH_TYPE(TgtExecutor::getName(), 74 dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " (" 75 << OnFailResumeAt.size() << " try-blocks remain)\n"); 76 return RejectAndResume; 77 }; 78 79 const auto propagateFlags = [&]() { 80 for (auto MIB : OutMIs) { 81 // Set the NoFPExcept flag when no original matched instruction could 82 // raise an FP exception, but the new instruction potentially might. 83 uint16_t MIBFlags = Flags; 84 if (NoFPException && MIB->mayRaiseFPException()) 85 MIBFlags |= MachineInstr::NoFPExcept; 86 if (Observer) 87 Observer->changingInstr(*MIB); 88 MIB.setMIFlags(MIBFlags); 89 if (Observer) 90 Observer->changedInstr(*MIB); 91 } 92 }; 93 94 // If the index is >= 0, it's an index in the type objects generated by 95 // TableGen. If the index is <0, it's an index in the recorded types object. 96 const auto getTypeFromIdx = [&](int64_t Idx) -> LLT { 97 if (Idx >= 0) 98 return ExecInfo.TypeObjects[Idx]; 99 return State.RecordedTypes[1 - Idx]; 100 }; 101 102 const auto readULEB = [&]() { 103 return fastDecodeULEB128(MatchTable, CurrentIdx); 104 }; 105 106 // Convenience function to return a signed value. This avoids 107 // us forgetting to first cast to int8_t before casting to a 108 // wider signed int type. 109 // if we casted uint8 directly to a wider type we'd lose 110 // negative values. 111 const auto readS8 = [&]() { return (int8_t)MatchTable[CurrentIdx++]; }; 112 113 const auto readU16 = [&]() { 114 auto V = readBytesAs<uint16_t>(MatchTable + CurrentIdx); 115 CurrentIdx += 2; 116 return V; 117 }; 118 119 const auto readU32 = [&]() { 120 auto V = readBytesAs<uint32_t>(MatchTable + CurrentIdx); 121 CurrentIdx += 4; 122 return V; 123 }; 124 125 const auto readU64 = [&]() { 126 auto V = readBytesAs<uint64_t>(MatchTable + CurrentIdx); 127 CurrentIdx += 8; 128 return V; 129 }; 130 131 const auto eraseImpl = [&](MachineInstr *MI) { 132 // If we're erasing the insertion point, ensure we don't leave a dangling 133 // pointer in the builder. 134 if (Builder.getInsertPt() == MI) 135 Builder.setInsertPt(*MI->getParent(), ++MI->getIterator()); 136 if (Observer) 137 Observer->erasingInstr(*MI); 138 MI->eraseFromParent(); 139 }; 140 141 while (true) { 142 assert(CurrentIdx != ~0u && "Invalid MatchTable index"); 143 uint8_t MatcherOpcode = MatchTable[CurrentIdx++]; 144 switch (MatcherOpcode) { 145 case GIM_Try: { 146 DEBUG_WITH_TYPE(TgtExecutor::getName(), 147 dbgs() << CurrentIdx << ": Begin try-block\n"); 148 OnFailResumeAt.push_back(readU32()); 149 break; 150 } 151 152 case GIM_RecordInsn: 153 case GIM_RecordInsnIgnoreCopies: { 154 uint64_t NewInsnID = readULEB(); 155 uint64_t InsnID = readULEB(); 156 uint64_t OpIdx = readULEB(); 157 158 // As an optimisation we require that MIs[0] is always the root. Refuse 159 // any attempt to modify it. 160 assert(NewInsnID != 0 && "Refusing to modify MIs[0]"); 161 162 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 163 if (!MO.isReg()) { 164 DEBUG_WITH_TYPE(TgtExecutor::getName(), 165 dbgs() << CurrentIdx << ": Not a register\n"); 166 if (handleReject() == RejectAndGiveUp) 167 return false; 168 break; 169 } 170 if (MO.getReg().isPhysical()) { 171 DEBUG_WITH_TYPE(TgtExecutor::getName(), 172 dbgs() << CurrentIdx << ": Is a physical register\n"); 173 if (handleReject() == RejectAndGiveUp) 174 return false; 175 break; 176 } 177 178 MachineInstr *NewMI; 179 if (MatcherOpcode == GIM_RecordInsnIgnoreCopies) 180 NewMI = getDefIgnoringCopies(MO.getReg(), MRI); 181 else 182 NewMI = MRI.getVRegDef(MO.getReg()); 183 184 if ((size_t)NewInsnID < State.MIs.size()) 185 State.MIs[NewInsnID] = NewMI; 186 else { 187 assert((size_t)NewInsnID == State.MIs.size() && 188 "Expected to store MIs in order"); 189 State.MIs.push_back(NewMI); 190 } 191 DEBUG_WITH_TYPE(TgtExecutor::getName(), 192 dbgs() << CurrentIdx << ": MIs[" << NewInsnID 193 << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx 194 << ")\n"); 195 break; 196 } 197 198 case GIM_CheckFeatures: { 199 uint16_t ExpectedBitsetID = readU16(); 200 DEBUG_WITH_TYPE(TgtExecutor::getName(), 201 dbgs() << CurrentIdx 202 << ": GIM_CheckFeatures(ExpectedBitsetID=" 203 << ExpectedBitsetID << ")\n"); 204 if ((AvailableFeatures & ExecInfo.FeatureBitsets[ExpectedBitsetID]) != 205 ExecInfo.FeatureBitsets[ExpectedBitsetID]) { 206 if (handleReject() == RejectAndGiveUp) 207 return false; 208 } 209 break; 210 } 211 case GIM_CheckOpcode: 212 case GIM_CheckOpcodeIsEither: { 213 uint64_t InsnID = readULEB(); 214 uint16_t Expected0 = readU16(); 215 uint16_t Expected1 = -1; 216 if (MatcherOpcode == GIM_CheckOpcodeIsEither) 217 Expected1 = readU16(); 218 219 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 220 unsigned Opcode = State.MIs[InsnID]->getOpcode(); 221 222 DEBUG_WITH_TYPE(TgtExecutor::getName(), { 223 dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID 224 << "], ExpectedOpcode=" << Expected0; 225 if (MatcherOpcode == GIM_CheckOpcodeIsEither) 226 dbgs() << " || " << Expected1; 227 dbgs() << ") // Got=" << Opcode << "\n"; 228 }); 229 230 if (Opcode != Expected0 && Opcode != Expected1) { 231 if (handleReject() == RejectAndGiveUp) 232 return false; 233 } 234 break; 235 } 236 case GIM_SwitchOpcode: { 237 uint64_t InsnID = readULEB(); 238 uint16_t LowerBound = readU16(); 239 uint16_t UpperBound = readU16(); 240 uint32_t Default = readU32(); 241 242 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 243 const int64_t Opcode = State.MIs[InsnID]->getOpcode(); 244 245 DEBUG_WITH_TYPE(TgtExecutor::getName(), { 246 dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], [" 247 << LowerBound << ", " << UpperBound << "), Default=" << Default 248 << ", JumpTable...) // Got=" << Opcode << "\n"; 249 }); 250 if (Opcode < LowerBound || UpperBound <= Opcode) { 251 CurrentIdx = Default; 252 break; 253 } 254 const auto EntryIdx = (Opcode - LowerBound); 255 // Each entry is 4 bytes 256 CurrentIdx = 257 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (EntryIdx * 4)); 258 if (!CurrentIdx) { 259 CurrentIdx = Default; 260 break; 261 } 262 OnFailResumeAt.push_back(Default); 263 break; 264 } 265 266 case GIM_SwitchType: { 267 uint64_t InsnID = readULEB(); 268 uint64_t OpIdx = readULEB(); 269 uint16_t LowerBound = readU16(); 270 uint16_t UpperBound = readU16(); 271 int64_t Default = readU32(); 272 273 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 274 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 275 276 DEBUG_WITH_TYPE(TgtExecutor::getName(), { 277 dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID 278 << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", " 279 << UpperBound << "), Default=" << Default 280 << ", JumpTable...) // Got="; 281 if (!MO.isReg()) 282 dbgs() << "Not a VReg\n"; 283 else 284 dbgs() << MRI.getType(MO.getReg()) << "\n"; 285 }); 286 if (!MO.isReg()) { 287 CurrentIdx = Default; 288 break; 289 } 290 const LLT Ty = MRI.getType(MO.getReg()); 291 const auto TyI = ExecInfo.TypeIDMap.find(Ty); 292 if (TyI == ExecInfo.TypeIDMap.end()) { 293 CurrentIdx = Default; 294 break; 295 } 296 const int64_t TypeID = TyI->second; 297 if (TypeID < LowerBound || UpperBound <= TypeID) { 298 CurrentIdx = Default; 299 break; 300 } 301 const auto NumEntry = (TypeID - LowerBound); 302 // Each entry is 4 bytes 303 CurrentIdx = 304 readBytesAs<uint32_t>(MatchTable + CurrentIdx + (NumEntry * 4)); 305 if (!CurrentIdx) { 306 CurrentIdx = Default; 307 break; 308 } 309 OnFailResumeAt.push_back(Default); 310 break; 311 } 312 313 case GIM_CheckNumOperandsGE: 314 case GIM_CheckNumOperandsLE: { 315 uint64_t InsnID = readULEB(); 316 uint64_t Expected = readULEB(); 317 const bool IsLE = (MatcherOpcode == GIM_CheckNumOperandsLE); 318 DEBUG_WITH_TYPE(TgtExecutor::getName(), 319 dbgs() << CurrentIdx << ": GIM_CheckNumOperands" 320 << (IsLE ? "LE" : "GE") << "(MIs[" << InsnID 321 << "], Expected=" << Expected << ")\n"); 322 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 323 const unsigned NumOps = State.MIs[InsnID]->getNumOperands(); 324 if (IsLE ? (NumOps > Expected) : (NumOps < Expected)) { 325 if (handleReject() == RejectAndGiveUp) 326 return false; 327 } 328 break; 329 } 330 case GIM_CheckNumOperands: { 331 uint64_t InsnID = readULEB(); 332 uint64_t Expected = readULEB(); 333 DEBUG_WITH_TYPE(TgtExecutor::getName(), 334 dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs[" 335 << InsnID << "], Expected=" << Expected << ")\n"); 336 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 337 if (State.MIs[InsnID]->getNumOperands() != Expected) { 338 if (handleReject() == RejectAndGiveUp) 339 return false; 340 } 341 break; 342 } 343 case GIM_CheckI64ImmPredicate: 344 case GIM_CheckImmOperandPredicate: { 345 uint64_t InsnID = readULEB(); 346 unsigned OpIdx = 347 MatcherOpcode == GIM_CheckImmOperandPredicate ? readULEB() : 1; 348 uint16_t Predicate = readU16(); 349 DEBUG_WITH_TYPE(TgtExecutor::getName(), 350 dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs[" 351 << InsnID << "]->getOperand(" << OpIdx 352 << "), Predicate=" << Predicate << ")\n"); 353 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 354 assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() || 355 State.MIs[InsnID]->getOperand(OpIdx).isCImm()) && 356 "Expected immediate operand"); 357 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate"); 358 int64_t Value = 0; 359 if (State.MIs[InsnID]->getOperand(OpIdx).isCImm()) 360 Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue(); 361 else if (State.MIs[InsnID]->getOperand(OpIdx).isImm()) 362 Value = State.MIs[InsnID]->getOperand(OpIdx).getImm(); 363 else 364 llvm_unreachable("Expected Imm or CImm operand"); 365 366 if (!testImmPredicate_I64(Predicate, Value)) 367 if (handleReject() == RejectAndGiveUp) 368 return false; 369 break; 370 } 371 case GIM_CheckAPIntImmPredicate: { 372 uint64_t InsnID = readULEB(); 373 uint16_t Predicate = readU16(); 374 DEBUG_WITH_TYPE(TgtExecutor::getName(), 375 dbgs() 376 << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs[" 377 << InsnID << "], Predicate=" << Predicate << ")\n"); 378 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 379 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && 380 "Expected G_CONSTANT"); 381 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate"); 382 if (!State.MIs[InsnID]->getOperand(1).isCImm()) 383 llvm_unreachable("Expected Imm or CImm operand"); 384 385 const APInt &Value = 386 State.MIs[InsnID]->getOperand(1).getCImm()->getValue(); 387 if (!testImmPredicate_APInt(Predicate, Value)) 388 if (handleReject() == RejectAndGiveUp) 389 return false; 390 break; 391 } 392 case GIM_CheckAPFloatImmPredicate: { 393 uint64_t InsnID = readULEB(); 394 uint16_t Predicate = readU16(); 395 DEBUG_WITH_TYPE(TgtExecutor::getName(), 396 dbgs() 397 << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs[" 398 << InsnID << "], Predicate=" << Predicate << ")\n"); 399 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 400 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && 401 "Expected G_FCONSTANT"); 402 assert(State.MIs[InsnID]->getOperand(1).isFPImm() && 403 "Expected FPImm operand"); 404 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate"); 405 const APFloat &Value = 406 State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); 407 408 if (!testImmPredicate_APFloat(Predicate, Value)) 409 if (handleReject() == RejectAndGiveUp) 410 return false; 411 break; 412 } 413 case GIM_CheckIsBuildVectorAllOnes: 414 case GIM_CheckIsBuildVectorAllZeros: { 415 uint64_t InsnID = readULEB(); 416 417 DEBUG_WITH_TYPE(TgtExecutor::getName(), 418 dbgs() << CurrentIdx 419 << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs[" 420 << InsnID << "])\n"); 421 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 422 423 const MachineInstr *MI = State.MIs[InsnID]; 424 assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR || 425 MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) && 426 "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC"); 427 428 if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) { 429 if (!isBuildVectorAllOnes(*MI, MRI)) { 430 if (handleReject() == RejectAndGiveUp) 431 return false; 432 } 433 } else { 434 if (!isBuildVectorAllZeros(*MI, MRI)) { 435 if (handleReject() == RejectAndGiveUp) 436 return false; 437 } 438 } 439 440 break; 441 } 442 case GIM_CheckSimplePredicate: { 443 // Note: we don't check for invalid here because this is purely a hook to 444 // allow some executors (such as the combiner) to check arbitrary, 445 // contextless predicates, such as whether a rule is enabled or not. 446 uint16_t Predicate = readU16(); 447 DEBUG_WITH_TYPE(TgtExecutor::getName(), 448 dbgs() << CurrentIdx 449 << ": GIM_CheckSimplePredicate(Predicate=" 450 << Predicate << ")\n"); 451 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate"); 452 if (!testSimplePredicate(Predicate)) { 453 if (handleReject() == RejectAndGiveUp) 454 return false; 455 } 456 break; 457 } 458 case GIM_CheckCxxInsnPredicate: { 459 uint64_t InsnID = readULEB(); 460 uint16_t Predicate = readU16(); 461 DEBUG_WITH_TYPE(TgtExecutor::getName(), 462 dbgs() 463 << CurrentIdx << ": GIM_CheckCxxPredicate(MIs[" 464 << InsnID << "], Predicate=" << Predicate << ")\n"); 465 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 466 assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate"); 467 468 if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID], State)) 469 if (handleReject() == RejectAndGiveUp) 470 return false; 471 break; 472 } 473 case GIM_CheckHasNoUse: { 474 uint64_t InsnID = readULEB(); 475 476 DEBUG_WITH_TYPE(TgtExecutor::getName(), 477 dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs[" 478 << InsnID << "]\n"); 479 480 const MachineInstr *MI = State.MIs[InsnID]; 481 assert(MI && "Used insn before defined"); 482 assert(MI->getNumDefs() > 0 && "No defs"); 483 const Register Res = MI->getOperand(0).getReg(); 484 485 if (!MRI.use_nodbg_empty(Res)) { 486 if (handleReject() == RejectAndGiveUp) 487 return false; 488 } 489 break; 490 } 491 case GIM_CheckHasOneUse: { 492 uint64_t InsnID = readULEB(); 493 494 DEBUG_WITH_TYPE(TgtExecutor::getName(), 495 dbgs() << CurrentIdx << ": GIM_CheckHasOneUse(MIs[" 496 << InsnID << "]\n"); 497 498 const MachineInstr *MI = State.MIs[InsnID]; 499 assert(MI && "Used insn before defined"); 500 assert(MI->getNumDefs() > 0 && "No defs"); 501 const Register Res = MI->getOperand(0).getReg(); 502 503 if (!MRI.hasOneNonDBGUse(Res)) { 504 if (handleReject() == RejectAndGiveUp) 505 return false; 506 } 507 break; 508 } 509 case GIM_CheckAtomicOrdering: { 510 uint64_t InsnID = readULEB(); 511 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 512 DEBUG_WITH_TYPE(TgtExecutor::getName(), 513 dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs[" 514 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 515 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 516 if (!State.MIs[InsnID]->hasOneMemOperand()) 517 if (handleReject() == RejectAndGiveUp) 518 return false; 519 520 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 521 if (MMO->getMergedOrdering() != Ordering) 522 if (handleReject() == RejectAndGiveUp) 523 return false; 524 break; 525 } 526 case GIM_CheckAtomicOrderingOrStrongerThan: { 527 uint64_t InsnID = readULEB(); 528 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 529 DEBUG_WITH_TYPE(TgtExecutor::getName(), 530 dbgs() << CurrentIdx 531 << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs[" 532 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 533 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 534 if (!State.MIs[InsnID]->hasOneMemOperand()) 535 if (handleReject() == RejectAndGiveUp) 536 return false; 537 538 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 539 if (!isAtLeastOrStrongerThan(MMO->getMergedOrdering(), Ordering)) 540 if (handleReject() == RejectAndGiveUp) 541 return false; 542 break; 543 } 544 case GIM_CheckAtomicOrderingWeakerThan: { 545 uint64_t InsnID = readULEB(); 546 auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 547 DEBUG_WITH_TYPE(TgtExecutor::getName(), 548 dbgs() << CurrentIdx 549 << ": GIM_CheckAtomicOrderingWeakerThan(MIs[" 550 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 551 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 552 if (!State.MIs[InsnID]->hasOneMemOperand()) 553 if (handleReject() == RejectAndGiveUp) 554 return false; 555 556 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 557 if (!isStrongerThan(Ordering, MMO->getMergedOrdering())) 558 if (handleReject() == RejectAndGiveUp) 559 return false; 560 break; 561 } 562 case GIM_CheckMemoryAddressSpace: { 563 uint64_t InsnID = readULEB(); 564 uint64_t MMOIdx = readULEB(); 565 // This accepts a list of possible address spaces. 566 const uint64_t NumAddrSpace = MatchTable[CurrentIdx++]; 567 568 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 569 if (handleReject() == RejectAndGiveUp) 570 return false; 571 break; 572 } 573 574 // Need to still jump to the end of the list of address spaces if we find 575 // a match earlier. 576 const uint64_t LastIdx = CurrentIdx + NumAddrSpace; 577 578 const MachineMemOperand *MMO = 579 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 580 const unsigned MMOAddrSpace = MMO->getAddrSpace(); 581 582 bool Success = false; 583 for (unsigned I = 0; I != NumAddrSpace; ++I) { 584 uint64_t AddrSpace = readULEB(); 585 DEBUG_WITH_TYPE(TgtExecutor::getName(), 586 dbgs() << "addrspace(" << MMOAddrSpace << ") vs " 587 << AddrSpace << '\n'); 588 589 if (AddrSpace == MMOAddrSpace) { 590 Success = true; 591 break; 592 } 593 } 594 595 CurrentIdx = LastIdx; 596 if (!Success && handleReject() == RejectAndGiveUp) 597 return false; 598 break; 599 } 600 case GIM_CheckMemoryAlignment: { 601 uint64_t InsnID = readULEB(); 602 uint64_t MMOIdx = readULEB(); 603 uint64_t MinAlign = MatchTable[CurrentIdx++]; 604 605 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 606 607 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 608 if (handleReject() == RejectAndGiveUp) 609 return false; 610 break; 611 } 612 613 MachineMemOperand *MMO = 614 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 615 DEBUG_WITH_TYPE(TgtExecutor::getName(), 616 dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment" 617 << "(MIs[" << InsnID << "]->memoperands() + " 618 << MMOIdx << ")->getAlignment() >= " << MinAlign 619 << ")\n"); 620 if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp) 621 return false; 622 623 break; 624 } 625 case GIM_CheckMemorySizeEqualTo: { 626 uint64_t InsnID = readULEB(); 627 uint64_t MMOIdx = readULEB(); 628 uint32_t Size = readU32(); 629 630 DEBUG_WITH_TYPE(TgtExecutor::getName(), 631 dbgs() << CurrentIdx << ": GIM_CheckMemorySizeEqual(MIs[" 632 << InsnID << "]->memoperands() + " << MMOIdx 633 << ", Size=" << Size << ")\n"); 634 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 635 636 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 637 if (handleReject() == RejectAndGiveUp) 638 return false; 639 break; 640 } 641 642 MachineMemOperand *MMO = 643 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 644 645 DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << MMO->getSize() 646 << " bytes vs " << Size 647 << " bytes\n"); 648 if (MMO->getSize() != Size) 649 if (handleReject() == RejectAndGiveUp) 650 return false; 651 652 break; 653 } 654 case GIM_CheckMemorySizeEqualToLLT: 655 case GIM_CheckMemorySizeLessThanLLT: 656 case GIM_CheckMemorySizeGreaterThanLLT: { 657 uint64_t InsnID = readULEB(); 658 uint64_t MMOIdx = readULEB(); 659 uint64_t OpIdx = readULEB(); 660 661 DEBUG_WITH_TYPE( 662 TgtExecutor::getName(), 663 dbgs() << CurrentIdx << ": GIM_CheckMemorySize" 664 << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT ? "EqualTo" 665 : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT 666 ? "GreaterThan" 667 : "LessThan") 668 << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx 669 << ", OpIdx=" << OpIdx << ")\n"); 670 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 671 672 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 673 if (!MO.isReg()) { 674 DEBUG_WITH_TYPE(TgtExecutor::getName(), 675 dbgs() << CurrentIdx << ": Not a register\n"); 676 if (handleReject() == RejectAndGiveUp) 677 return false; 678 break; 679 } 680 681 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 682 if (handleReject() == RejectAndGiveUp) 683 return false; 684 break; 685 } 686 687 MachineMemOperand *MMO = 688 *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 689 690 const TypeSize Size = MRI.getType(MO.getReg()).getSizeInBits(); 691 if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT && 692 MMO->getSizeInBits() != Size) { 693 if (handleReject() == RejectAndGiveUp) 694 return false; 695 } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT && 696 TypeSize::isKnownGE(MMO->getSizeInBits().getValue(), Size)) { 697 if (handleReject() == RejectAndGiveUp) 698 return false; 699 } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT && 700 TypeSize::isKnownLE(MMO->getSizeInBits().getValue(), Size)) 701 if (handleReject() == RejectAndGiveUp) 702 return false; 703 704 break; 705 } 706 case GIM_RootCheckType: 707 case GIM_CheckType: { 708 uint64_t InsnID = (MatcherOpcode == GIM_RootCheckType) ? 0 : readULEB(); 709 uint64_t OpIdx = readULEB(); 710 int TypeID = readS8(); 711 DEBUG_WITH_TYPE(TgtExecutor::getName(), 712 dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID 713 << "]->getOperand(" << OpIdx 714 << "), TypeID=" << TypeID << ")\n"); 715 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 716 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 717 if (!MO.isReg() || MRI.getType(MO.getReg()) != getTypeFromIdx(TypeID)) { 718 if (handleReject() == RejectAndGiveUp) 719 return false; 720 } 721 break; 722 } 723 case GIM_CheckPointerToAny: { 724 uint64_t InsnID = readULEB(); 725 uint64_t OpIdx = readULEB(); 726 uint64_t SizeInBits = readULEB(); 727 728 DEBUG_WITH_TYPE(TgtExecutor::getName(), 729 dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs[" 730 << InsnID << "]->getOperand(" << OpIdx 731 << "), SizeInBits=" << SizeInBits << ")\n"); 732 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 733 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 734 const LLT Ty = MRI.getType(MO.getReg()); 735 736 // iPTR must be looked up in the target. 737 if (SizeInBits == 0) { 738 MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent(); 739 const unsigned AddrSpace = Ty.getAddressSpace(); 740 SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace); 741 } 742 743 assert(SizeInBits != 0 && "Pointer size must be known"); 744 745 if (MO.isReg()) { 746 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) 747 if (handleReject() == RejectAndGiveUp) 748 return false; 749 } else if (handleReject() == RejectAndGiveUp) 750 return false; 751 752 break; 753 } 754 case GIM_RecordNamedOperand: { 755 uint64_t InsnID = readULEB(); 756 uint64_t OpIdx = readULEB(); 757 uint64_t StoreIdx = readULEB(); 758 759 DEBUG_WITH_TYPE(TgtExecutor::getName(), 760 dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs[" 761 << InsnID << "]->getOperand(" << OpIdx 762 << "), StoreIdx=" << StoreIdx << ")\n"); 763 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 764 assert(StoreIdx < State.RecordedOperands.size() && "Index out of range"); 765 State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx); 766 break; 767 } 768 case GIM_RecordRegType: { 769 uint64_t InsnID = readULEB(); 770 uint64_t OpIdx = readULEB(); 771 int TypeIdx = readS8(); 772 773 DEBUG_WITH_TYPE(TgtExecutor::getName(), 774 dbgs() << CurrentIdx << ": GIM_RecordRegType(MIs[" 775 << InsnID << "]->getOperand(" << OpIdx 776 << "), TypeIdx=" << TypeIdx << ")\n"); 777 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 778 assert(TypeIdx < 0 && "Temp types always have negative indexes!"); 779 // Indexes start at -1. 780 TypeIdx = 1 - TypeIdx; 781 const auto &Op = State.MIs[InsnID]->getOperand(OpIdx); 782 if (State.RecordedTypes.size() <= (uint64_t)TypeIdx) 783 State.RecordedTypes.resize(TypeIdx + 1, LLT()); 784 State.RecordedTypes[TypeIdx] = MRI.getType(Op.getReg()); 785 break; 786 } 787 788 case GIM_RootCheckRegBankForClass: 789 case GIM_CheckRegBankForClass: { 790 uint64_t InsnID = 791 (MatcherOpcode == GIM_RootCheckRegBankForClass) ? 0 : readULEB(); 792 uint64_t OpIdx = readULEB(); 793 uint16_t RCEnum = readU16(); 794 DEBUG_WITH_TYPE(TgtExecutor::getName(), 795 dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs[" 796 << InsnID << "]->getOperand(" << OpIdx 797 << "), RCEnum=" << RCEnum << ")\n"); 798 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 799 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 800 if (!MO.isReg() || 801 &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum), 802 MRI.getType(MO.getReg())) != 803 RBI.getRegBank(MO.getReg(), MRI, TRI)) { 804 if (handleReject() == RejectAndGiveUp) 805 return false; 806 } 807 break; 808 } 809 810 case GIM_CheckComplexPattern: { 811 uint64_t InsnID = readULEB(); 812 uint64_t OpIdx = readULEB(); 813 uint16_t RendererID = readU16(); 814 uint16_t ComplexPredicateID = readU16(); 815 DEBUG_WITH_TYPE(TgtExecutor::getName(), 816 dbgs() << CurrentIdx << ": State.Renderers[" << RendererID 817 << "] = GIM_CheckComplexPattern(MIs[" << InsnID 818 << "]->getOperand(" << OpIdx 819 << "), ComplexPredicateID=" << ComplexPredicateID 820 << ")\n"); 821 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 822 // FIXME: Use std::invoke() when it's available. 823 ComplexRendererFns Renderer = 824 (Exec.*ExecInfo.ComplexPredicates[ComplexPredicateID])( 825 State.MIs[InsnID]->getOperand(OpIdx)); 826 if (Renderer) 827 State.Renderers[RendererID] = *Renderer; 828 else if (handleReject() == RejectAndGiveUp) 829 return false; 830 break; 831 } 832 833 case GIM_CheckConstantInt: 834 case GIM_CheckConstantInt8: { 835 const bool IsInt8 = (MatcherOpcode == GIM_CheckConstantInt8); 836 837 uint64_t InsnID = readULEB(); 838 uint64_t OpIdx = readULEB(); 839 uint64_t Value = IsInt8 ? (int64_t)readS8() : readU64(); 840 DEBUG_WITH_TYPE(TgtExecutor::getName(), 841 dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs[" 842 << InsnID << "]->getOperand(" << OpIdx 843 << "), Value=" << Value << ")\n"); 844 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 845 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 846 if (MO.isReg()) { 847 // isOperandImmEqual() will sign-extend to 64-bits, so should we. 848 LLT Ty = MRI.getType(MO.getReg()); 849 // If the type is > 64 bits, it can't be a constant int, so we bail 850 // early because SignExtend64 will assert otherwise. 851 if (Ty.getScalarSizeInBits() > 64) { 852 if (handleReject() == RejectAndGiveUp) 853 return false; 854 break; 855 } 856 857 Value = SignExtend64(Value, Ty.getScalarSizeInBits()); 858 if (!isOperandImmEqual(MO, Value, MRI, /*Splat=*/true)) { 859 if (handleReject() == RejectAndGiveUp) 860 return false; 861 } 862 } else if (handleReject() == RejectAndGiveUp) 863 return false; 864 865 break; 866 } 867 868 case GIM_CheckLiteralInt: { 869 uint64_t InsnID = readULEB(); 870 uint64_t OpIdx = readULEB(); 871 int64_t Value = readU64(); 872 DEBUG_WITH_TYPE(TgtExecutor::getName(), 873 dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs[" 874 << InsnID << "]->getOperand(" << OpIdx 875 << "), Value=" << Value << ")\n"); 876 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 877 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 878 if (MO.isImm() && MO.getImm() == Value) 879 break; 880 881 if (MO.isCImm() && MO.getCImm()->equalsInt(Value)) 882 break; 883 884 if (handleReject() == RejectAndGiveUp) 885 return false; 886 887 break; 888 } 889 890 case GIM_CheckIntrinsicID: { 891 uint64_t InsnID = readULEB(); 892 uint64_t OpIdx = readULEB(); 893 uint16_t Value = readU16(); 894 DEBUG_WITH_TYPE(TgtExecutor::getName(), 895 dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs[" 896 << InsnID << "]->getOperand(" << OpIdx 897 << "), Value=" << Value << ")\n"); 898 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 899 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 900 if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value) 901 if (handleReject() == RejectAndGiveUp) 902 return false; 903 break; 904 } 905 case GIM_CheckCmpPredicate: { 906 uint64_t InsnID = readULEB(); 907 uint64_t OpIdx = readULEB(); 908 uint16_t Value = readU16(); 909 DEBUG_WITH_TYPE(TgtExecutor::getName(), 910 dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs[" 911 << InsnID << "]->getOperand(" << OpIdx 912 << "), Value=" << Value << ")\n"); 913 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 914 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 915 if (!MO.isPredicate() || MO.getPredicate() != Value) 916 if (handleReject() == RejectAndGiveUp) 917 return false; 918 break; 919 } 920 case GIM_CheckIsMBB: { 921 uint64_t InsnID = readULEB(); 922 uint64_t OpIdx = readULEB(); 923 DEBUG_WITH_TYPE(TgtExecutor::getName(), 924 dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID 925 << "]->getOperand(" << OpIdx << "))\n"); 926 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 927 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) { 928 if (handleReject() == RejectAndGiveUp) 929 return false; 930 } 931 break; 932 } 933 case GIM_CheckIsImm: { 934 uint64_t InsnID = readULEB(); 935 uint64_t OpIdx = readULEB(); 936 DEBUG_WITH_TYPE(TgtExecutor::getName(), 937 dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID 938 << "]->getOperand(" << OpIdx << "))\n"); 939 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 940 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) { 941 if (handleReject() == RejectAndGiveUp) 942 return false; 943 } 944 break; 945 } 946 case GIM_CheckIsSafeToFold: { 947 uint64_t NumInsn = MatchTable[CurrentIdx++]; 948 DEBUG_WITH_TYPE(TgtExecutor::getName(), 949 dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(N = " 950 << NumInsn << ")\n"); 951 MachineInstr &Root = *State.MIs[0]; 952 for (unsigned K = 1, E = NumInsn + 1; K < E; ++K) { 953 if (!isObviouslySafeToFold(*State.MIs[K], Root)) { 954 if (handleReject() == RejectAndGiveUp) 955 return false; 956 } 957 } 958 break; 959 } 960 case GIM_CheckIsSameOperand: 961 case GIM_CheckIsSameOperandIgnoreCopies: { 962 uint64_t InsnID = readULEB(); 963 uint64_t OpIdx = readULEB(); 964 uint64_t OtherInsnID = readULEB(); 965 uint64_t OtherOpIdx = readULEB(); 966 DEBUG_WITH_TYPE(TgtExecutor::getName(), 967 dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs[" 968 << InsnID << "][" << OpIdx << "], MIs[" 969 << OtherInsnID << "][" << OtherOpIdx << "])\n"); 970 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 971 assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined"); 972 973 MachineOperand &Op = State.MIs[InsnID]->getOperand(OpIdx); 974 MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx); 975 976 if (MatcherOpcode == GIM_CheckIsSameOperandIgnoreCopies) { 977 if (Op.isReg() && OtherOp.isReg()) { 978 if (getSrcRegIgnoringCopies(Op.getReg(), MRI) == 979 getSrcRegIgnoringCopies(OtherOp.getReg(), MRI)) 980 break; 981 } 982 } 983 984 if (!Op.isIdenticalTo(OtherOp)) { 985 if (handleReject() == RejectAndGiveUp) 986 return false; 987 } 988 break; 989 } 990 case GIM_CheckCanReplaceReg: { 991 uint64_t OldInsnID = readULEB(); 992 uint64_t OldOpIdx = readULEB(); 993 uint64_t NewInsnID = readULEB(); 994 uint64_t NewOpIdx = readULEB(); 995 996 DEBUG_WITH_TYPE(TgtExecutor::getName(), 997 dbgs() << CurrentIdx << ": GIM_CheckCanReplaceReg(MIs[" 998 << OldInsnID << "][" << OldOpIdx << "] = MIs[" 999 << 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, /*signed*/ 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 // TODO: Needs a test case once we have a pattern that uses this. 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); // Not a source operand of the old instruction. 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 } // end namespace llvm 1561 1562 #endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H 1563