InstructionSelectorImpl.h revision 360784
1//===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.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 declares the API for the instruction selector. 10/// This class is responsible for selecting machine instructions. 11/// It's implemented by the target. It's used by the InstructionSelect pass. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H 16#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H 17 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 20#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 21#include "llvm/CodeGen/GlobalISel/Utils.h" 22#include "llvm/CodeGen/MachineInstrBuilder.h" 23#include "llvm/CodeGen/MachineOperand.h" 24#include "llvm/CodeGen/MachineRegisterInfo.h" 25#include "llvm/CodeGen/TargetInstrInfo.h" 26#include "llvm/CodeGen/TargetOpcodes.h" 27#include "llvm/CodeGen/TargetRegisterInfo.h" 28#include "llvm/IR/Constants.h" 29#include "llvm/IR/DataLayout.h" 30#include "llvm/Support/Debug.h" 31#include "llvm/Support/ErrorHandling.h" 32#include "llvm/Support/raw_ostream.h" 33#include <cassert> 34#include <cstddef> 35#include <cstdint> 36 37namespace llvm { 38 39/// GlobalISel PatFrag Predicates 40enum { 41 GIPFP_I64_Invalid = 0, 42 GIPFP_APInt_Invalid = 0, 43 GIPFP_APFloat_Invalid = 0, 44 GIPFP_MI_Invalid = 0, 45}; 46 47template <class TgtInstructionSelector, class PredicateBitset, 48 class ComplexMatcherMemFn, class CustomRendererFn> 49bool InstructionSelector::executeMatchTable( 50 TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, 51 const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> 52 &ISelInfo, 53 const int64_t *MatchTable, const TargetInstrInfo &TII, 54 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 55 const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, 56 CodeGenCoverage &CoverageInfo) const { 57 58 uint64_t CurrentIdx = 0; 59 SmallVector<uint64_t, 4> OnFailResumeAt; 60 61 enum RejectAction { RejectAndGiveUp, RejectAndResume }; 62 auto handleReject = [&]() -> RejectAction { 63 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 64 dbgs() << CurrentIdx << ": Rejected\n"); 65 if (OnFailResumeAt.empty()) 66 return RejectAndGiveUp; 67 CurrentIdx = OnFailResumeAt.pop_back_val(); 68 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 69 dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " (" 70 << OnFailResumeAt.size() << " try-blocks remain)\n"); 71 return RejectAndResume; 72 }; 73 74 while (true) { 75 assert(CurrentIdx != ~0u && "Invalid MatchTable index"); 76 int64_t MatcherOpcode = MatchTable[CurrentIdx++]; 77 switch (MatcherOpcode) { 78 case GIM_Try: { 79 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 80 dbgs() << CurrentIdx << ": Begin try-block\n"); 81 OnFailResumeAt.push_back(MatchTable[CurrentIdx++]); 82 break; 83 } 84 85 case GIM_RecordInsn: { 86 int64_t NewInsnID = MatchTable[CurrentIdx++]; 87 int64_t InsnID = MatchTable[CurrentIdx++]; 88 int64_t OpIdx = MatchTable[CurrentIdx++]; 89 90 // As an optimisation we require that MIs[0] is always the root. Refuse 91 // any attempt to modify it. 92 assert(NewInsnID != 0 && "Refusing to modify MIs[0]"); 93 94 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 95 if (!MO.isReg()) { 96 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 97 dbgs() << CurrentIdx << ": Not a register\n"); 98 if (handleReject() == RejectAndGiveUp) 99 return false; 100 break; 101 } 102 if (Register::isPhysicalRegister(MO.getReg())) { 103 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 104 dbgs() << CurrentIdx << ": Is a physical register\n"); 105 if (handleReject() == RejectAndGiveUp) 106 return false; 107 break; 108 } 109 110 MachineInstr *NewMI = MRI.getVRegDef(MO.getReg()); 111 if ((size_t)NewInsnID < State.MIs.size()) 112 State.MIs[NewInsnID] = NewMI; 113 else { 114 assert((size_t)NewInsnID == State.MIs.size() && 115 "Expected to store MIs in order"); 116 State.MIs.push_back(NewMI); 117 } 118 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 119 dbgs() << CurrentIdx << ": MIs[" << NewInsnID 120 << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx 121 << ")\n"); 122 break; 123 } 124 125 case GIM_CheckFeatures: { 126 int64_t ExpectedBitsetID = MatchTable[CurrentIdx++]; 127 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 128 dbgs() << CurrentIdx 129 << ": GIM_CheckFeatures(ExpectedBitsetID=" 130 << ExpectedBitsetID << ")\n"); 131 if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) != 132 ISelInfo.FeatureBitsets[ExpectedBitsetID]) { 133 if (handleReject() == RejectAndGiveUp) 134 return false; 135 } 136 break; 137 } 138 139 case GIM_CheckOpcode: { 140 int64_t InsnID = MatchTable[CurrentIdx++]; 141 int64_t Expected = MatchTable[CurrentIdx++]; 142 143 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 144 unsigned Opcode = State.MIs[InsnID]->getOpcode(); 145 146 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 147 dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID 148 << "], ExpectedOpcode=" << Expected 149 << ") // Got=" << Opcode << "\n"); 150 if (Opcode != Expected) { 151 if (handleReject() == RejectAndGiveUp) 152 return false; 153 } 154 break; 155 } 156 157 case GIM_SwitchOpcode: { 158 int64_t InsnID = MatchTable[CurrentIdx++]; 159 int64_t LowerBound = MatchTable[CurrentIdx++]; 160 int64_t UpperBound = MatchTable[CurrentIdx++]; 161 int64_t Default = MatchTable[CurrentIdx++]; 162 163 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 164 const int64_t Opcode = State.MIs[InsnID]->getOpcode(); 165 166 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { 167 dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], [" 168 << LowerBound << ", " << UpperBound << "), Default=" << Default 169 << ", JumpTable...) // Got=" << Opcode << "\n"; 170 }); 171 if (Opcode < LowerBound || UpperBound <= Opcode) { 172 CurrentIdx = Default; 173 break; 174 } 175 CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)]; 176 if (!CurrentIdx) { 177 CurrentIdx = Default; 178 break; 179 } 180 OnFailResumeAt.push_back(Default); 181 break; 182 } 183 184 case GIM_SwitchType: { 185 int64_t InsnID = MatchTable[CurrentIdx++]; 186 int64_t OpIdx = MatchTable[CurrentIdx++]; 187 int64_t LowerBound = MatchTable[CurrentIdx++]; 188 int64_t UpperBound = MatchTable[CurrentIdx++]; 189 int64_t Default = MatchTable[CurrentIdx++]; 190 191 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 192 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 193 194 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { 195 dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID 196 << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", " 197 << UpperBound << "), Default=" << Default 198 << ", JumpTable...) // Got="; 199 if (!MO.isReg()) 200 dbgs() << "Not a VReg\n"; 201 else 202 dbgs() << MRI.getType(MO.getReg()) << "\n"; 203 }); 204 if (!MO.isReg()) { 205 CurrentIdx = Default; 206 break; 207 } 208 const LLT Ty = MRI.getType(MO.getReg()); 209 const auto TyI = ISelInfo.TypeIDMap.find(Ty); 210 if (TyI == ISelInfo.TypeIDMap.end()) { 211 CurrentIdx = Default; 212 break; 213 } 214 const int64_t TypeID = TyI->second; 215 if (TypeID < LowerBound || UpperBound <= TypeID) { 216 CurrentIdx = Default; 217 break; 218 } 219 CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)]; 220 if (!CurrentIdx) { 221 CurrentIdx = Default; 222 break; 223 } 224 OnFailResumeAt.push_back(Default); 225 break; 226 } 227 228 case GIM_CheckNumOperands: { 229 int64_t InsnID = MatchTable[CurrentIdx++]; 230 int64_t Expected = MatchTable[CurrentIdx++]; 231 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 232 dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs[" 233 << InsnID << "], Expected=" << Expected << ")\n"); 234 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 235 if (State.MIs[InsnID]->getNumOperands() != Expected) { 236 if (handleReject() == RejectAndGiveUp) 237 return false; 238 } 239 break; 240 } 241 case GIM_CheckI64ImmPredicate: { 242 int64_t InsnID = MatchTable[CurrentIdx++]; 243 int64_t Predicate = MatchTable[CurrentIdx++]; 244 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 245 dbgs() 246 << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs[" 247 << InsnID << "], Predicate=" << Predicate << ")\n"); 248 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 249 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && 250 "Expected G_CONSTANT"); 251 assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate"); 252 int64_t Value = 0; 253 if (State.MIs[InsnID]->getOperand(1).isCImm()) 254 Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue(); 255 else if (State.MIs[InsnID]->getOperand(1).isImm()) 256 Value = State.MIs[InsnID]->getOperand(1).getImm(); 257 else 258 llvm_unreachable("Expected Imm or CImm operand"); 259 260 if (!testImmPredicate_I64(Predicate, Value)) 261 if (handleReject() == RejectAndGiveUp) 262 return false; 263 break; 264 } 265 case GIM_CheckAPIntImmPredicate: { 266 int64_t InsnID = MatchTable[CurrentIdx++]; 267 int64_t Predicate = MatchTable[CurrentIdx++]; 268 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 269 dbgs() 270 << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs[" 271 << InsnID << "], Predicate=" << Predicate << ")\n"); 272 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 273 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && 274 "Expected G_CONSTANT"); 275 assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate"); 276 APInt Value; 277 if (State.MIs[InsnID]->getOperand(1).isCImm()) 278 Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue(); 279 else 280 llvm_unreachable("Expected Imm or CImm operand"); 281 282 if (!testImmPredicate_APInt(Predicate, Value)) 283 if (handleReject() == RejectAndGiveUp) 284 return false; 285 break; 286 } 287 case GIM_CheckAPFloatImmPredicate: { 288 int64_t InsnID = MatchTable[CurrentIdx++]; 289 int64_t Predicate = MatchTable[CurrentIdx++]; 290 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 291 dbgs() 292 << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs[" 293 << InsnID << "], Predicate=" << Predicate << ")\n"); 294 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 295 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && 296 "Expected G_FCONSTANT"); 297 assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand"); 298 assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate"); 299 APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); 300 301 if (!testImmPredicate_APFloat(Predicate, Value)) 302 if (handleReject() == RejectAndGiveUp) 303 return false; 304 break; 305 } 306 case GIM_CheckCxxInsnPredicate: { 307 int64_t InsnID = MatchTable[CurrentIdx++]; 308 int64_t Predicate = MatchTable[CurrentIdx++]; 309 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 310 dbgs() 311 << CurrentIdx << ": GIM_CheckCxxPredicate(MIs[" 312 << InsnID << "], Predicate=" << Predicate << ")\n"); 313 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 314 assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate"); 315 316 if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID])) 317 if (handleReject() == RejectAndGiveUp) 318 return false; 319 break; 320 } 321 case GIM_CheckAtomicOrdering: { 322 int64_t InsnID = MatchTable[CurrentIdx++]; 323 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 324 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 325 dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs[" 326 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 327 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 328 if (!State.MIs[InsnID]->hasOneMemOperand()) 329 if (handleReject() == RejectAndGiveUp) 330 return false; 331 332 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 333 if (MMO->getOrdering() != Ordering) 334 if (handleReject() == RejectAndGiveUp) 335 return false; 336 break; 337 } 338 case GIM_CheckAtomicOrderingOrStrongerThan: { 339 int64_t InsnID = MatchTable[CurrentIdx++]; 340 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 341 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 342 dbgs() << CurrentIdx 343 << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs[" 344 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 345 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 346 if (!State.MIs[InsnID]->hasOneMemOperand()) 347 if (handleReject() == RejectAndGiveUp) 348 return false; 349 350 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 351 if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering)) 352 if (handleReject() == RejectAndGiveUp) 353 return false; 354 break; 355 } 356 case GIM_CheckAtomicOrderingWeakerThan: { 357 int64_t InsnID = MatchTable[CurrentIdx++]; 358 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++]; 359 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 360 dbgs() << CurrentIdx 361 << ": GIM_CheckAtomicOrderingWeakerThan(MIs[" 362 << InsnID << "], " << (uint64_t)Ordering << ")\n"); 363 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 364 if (!State.MIs[InsnID]->hasOneMemOperand()) 365 if (handleReject() == RejectAndGiveUp) 366 return false; 367 368 for (const auto &MMO : State.MIs[InsnID]->memoperands()) 369 if (!isStrongerThan(Ordering, MMO->getOrdering())) 370 if (handleReject() == RejectAndGiveUp) 371 return false; 372 break; 373 } 374 case GIM_CheckMemoryAddressSpace: { 375 int64_t InsnID = MatchTable[CurrentIdx++]; 376 int64_t MMOIdx = MatchTable[CurrentIdx++]; 377 // This accepts a list of possible address spaces. 378 const int NumAddrSpace = MatchTable[CurrentIdx++]; 379 380 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 381 if (handleReject() == RejectAndGiveUp) 382 return false; 383 break; 384 } 385 386 // Need to still jump to the end of the list of address spaces if we find 387 // a match earlier. 388 const uint64_t LastIdx = CurrentIdx + NumAddrSpace; 389 390 const MachineMemOperand *MMO 391 = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 392 const unsigned MMOAddrSpace = MMO->getAddrSpace(); 393 394 bool Success = false; 395 for (int I = 0; I != NumAddrSpace; ++I) { 396 unsigned AddrSpace = MatchTable[CurrentIdx++]; 397 DEBUG_WITH_TYPE( 398 TgtInstructionSelector::getName(), 399 dbgs() << "addrspace(" << MMOAddrSpace << ") vs " 400 << AddrSpace << '\n'); 401 402 if (AddrSpace == MMOAddrSpace) { 403 Success = true; 404 break; 405 } 406 } 407 408 CurrentIdx = LastIdx; 409 if (!Success && handleReject() == RejectAndGiveUp) 410 return false; 411 break; 412 } 413 case GIM_CheckMemoryAlignment: { 414 int64_t InsnID = MatchTable[CurrentIdx++]; 415 int64_t MMOIdx = MatchTable[CurrentIdx++]; 416 unsigned MinAlign = MatchTable[CurrentIdx++]; 417 418 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 419 420 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 421 if (handleReject() == RejectAndGiveUp) 422 return false; 423 break; 424 } 425 426 MachineMemOperand *MMO 427 = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 428 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 429 dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment" 430 << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx 431 << ")->getAlignment() >= " << MinAlign << ")\n"); 432 if (MMO->getAlignment() < MinAlign && handleReject() == RejectAndGiveUp) 433 return false; 434 435 break; 436 } 437 case GIM_CheckMemorySizeEqualTo: { 438 int64_t InsnID = MatchTable[CurrentIdx++]; 439 int64_t MMOIdx = MatchTable[CurrentIdx++]; 440 uint64_t Size = MatchTable[CurrentIdx++]; 441 442 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 443 dbgs() << CurrentIdx 444 << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID 445 << "]->memoperands() + " << MMOIdx 446 << ", Size=" << Size << ")\n"); 447 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 448 449 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 450 if (handleReject() == RejectAndGiveUp) 451 return false; 452 break; 453 } 454 455 MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 456 457 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 458 dbgs() << MMO->getSize() << " bytes vs " << Size 459 << " bytes\n"); 460 if (MMO->getSize() != Size) 461 if (handleReject() == RejectAndGiveUp) 462 return false; 463 464 break; 465 } 466 case GIM_CheckMemorySizeEqualToLLT: 467 case GIM_CheckMemorySizeLessThanLLT: 468 case GIM_CheckMemorySizeGreaterThanLLT: { 469 int64_t InsnID = MatchTable[CurrentIdx++]; 470 int64_t MMOIdx = MatchTable[CurrentIdx++]; 471 int64_t OpIdx = MatchTable[CurrentIdx++]; 472 473 DEBUG_WITH_TYPE( 474 TgtInstructionSelector::getName(), 475 dbgs() << CurrentIdx << ": GIM_CheckMemorySize" 476 << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT 477 ? "EqualTo" 478 : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT 479 ? "GreaterThan" 480 : "LessThan") 481 << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx 482 << ", OpIdx=" << OpIdx << ")\n"); 483 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 484 485 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 486 if (!MO.isReg()) { 487 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 488 dbgs() << CurrentIdx << ": Not a register\n"); 489 if (handleReject() == RejectAndGiveUp) 490 return false; 491 break; 492 } 493 494 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { 495 if (handleReject() == RejectAndGiveUp) 496 return false; 497 break; 498 } 499 500 MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); 501 502 unsigned Size = MRI.getType(MO.getReg()).getSizeInBits(); 503 if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT && 504 MMO->getSizeInBits() != Size) { 505 if (handleReject() == RejectAndGiveUp) 506 return false; 507 } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT && 508 MMO->getSizeInBits() >= Size) { 509 if (handleReject() == RejectAndGiveUp) 510 return false; 511 } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT && 512 MMO->getSizeInBits() <= Size) 513 if (handleReject() == RejectAndGiveUp) 514 return false; 515 516 break; 517 } 518 case GIM_CheckType: { 519 int64_t InsnID = MatchTable[CurrentIdx++]; 520 int64_t OpIdx = MatchTable[CurrentIdx++]; 521 int64_t TypeID = MatchTable[CurrentIdx++]; 522 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 523 dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID 524 << "]->getOperand(" << OpIdx 525 << "), TypeID=" << TypeID << ")\n"); 526 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 527 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 528 if (!MO.isReg() || 529 MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) { 530 if (handleReject() == RejectAndGiveUp) 531 return false; 532 } 533 break; 534 } 535 case GIM_CheckPointerToAny: { 536 int64_t InsnID = MatchTable[CurrentIdx++]; 537 int64_t OpIdx = MatchTable[CurrentIdx++]; 538 int64_t SizeInBits = MatchTable[CurrentIdx++]; 539 540 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 541 dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs[" 542 << InsnID << "]->getOperand(" << OpIdx 543 << "), SizeInBits=" << SizeInBits << ")\n"); 544 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 545 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 546 const LLT Ty = MRI.getType(MO.getReg()); 547 548 // iPTR must be looked up in the target. 549 if (SizeInBits == 0) { 550 MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent(); 551 const unsigned AddrSpace = Ty.getAddressSpace(); 552 SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace); 553 } 554 555 assert(SizeInBits != 0 && "Pointer size must be known"); 556 557 if (MO.isReg()) { 558 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) 559 if (handleReject() == RejectAndGiveUp) 560 return false; 561 } else if (handleReject() == RejectAndGiveUp) 562 return false; 563 564 break; 565 } 566 case GIM_CheckRegBankForClass: { 567 int64_t InsnID = MatchTable[CurrentIdx++]; 568 int64_t OpIdx = MatchTable[CurrentIdx++]; 569 int64_t RCEnum = MatchTable[CurrentIdx++]; 570 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 571 dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs[" 572 << InsnID << "]->getOperand(" << OpIdx 573 << "), RCEnum=" << RCEnum << ")\n"); 574 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 575 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 576 if (!MO.isReg() || 577 &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum), 578 MRI.getType(MO.getReg())) != 579 RBI.getRegBank(MO.getReg(), MRI, TRI)) { 580 if (handleReject() == RejectAndGiveUp) 581 return false; 582 } 583 break; 584 } 585 586 case GIM_CheckComplexPattern: { 587 int64_t InsnID = MatchTable[CurrentIdx++]; 588 int64_t OpIdx = MatchTable[CurrentIdx++]; 589 int64_t RendererID = MatchTable[CurrentIdx++]; 590 int64_t ComplexPredicateID = MatchTable[CurrentIdx++]; 591 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 592 dbgs() << CurrentIdx << ": State.Renderers[" << RendererID 593 << "] = GIM_CheckComplexPattern(MIs[" << InsnID 594 << "]->getOperand(" << OpIdx 595 << "), ComplexPredicateID=" << ComplexPredicateID 596 << ")\n"); 597 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 598 // FIXME: Use std::invoke() when it's available. 599 ComplexRendererFns Renderer = 600 (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])( 601 State.MIs[InsnID]->getOperand(OpIdx)); 602 if (Renderer.hasValue()) 603 State.Renderers[RendererID] = Renderer.getValue(); 604 else 605 if (handleReject() == RejectAndGiveUp) 606 return false; 607 break; 608 } 609 610 case GIM_CheckConstantInt: { 611 int64_t InsnID = MatchTable[CurrentIdx++]; 612 int64_t OpIdx = MatchTable[CurrentIdx++]; 613 int64_t Value = MatchTable[CurrentIdx++]; 614 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 615 dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs[" 616 << InsnID << "]->getOperand(" << OpIdx 617 << "), Value=" << Value << ")\n"); 618 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 619 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 620 if (MO.isReg()) { 621 // isOperandImmEqual() will sign-extend to 64-bits, so should we. 622 LLT Ty = MRI.getType(MO.getReg()); 623 Value = SignExtend64(Value, Ty.getSizeInBits()); 624 625 if (!isOperandImmEqual(MO, Value, MRI)) { 626 if (handleReject() == RejectAndGiveUp) 627 return false; 628 } 629 } else if (handleReject() == RejectAndGiveUp) 630 return false; 631 632 break; 633 } 634 635 case GIM_CheckLiteralInt: { 636 int64_t InsnID = MatchTable[CurrentIdx++]; 637 int64_t OpIdx = MatchTable[CurrentIdx++]; 638 int64_t Value = MatchTable[CurrentIdx++]; 639 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 640 dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs[" 641 << InsnID << "]->getOperand(" << OpIdx 642 << "), Value=" << Value << ")\n"); 643 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 644 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 645 if (MO.isImm() && MO.getImm() == Value) 646 break; 647 648 if (MO.isCImm() && MO.getCImm()->equalsInt(Value)) 649 break; 650 651 if (handleReject() == RejectAndGiveUp) 652 return false; 653 654 break; 655 } 656 657 case GIM_CheckIntrinsicID: { 658 int64_t InsnID = MatchTable[CurrentIdx++]; 659 int64_t OpIdx = MatchTable[CurrentIdx++]; 660 int64_t Value = MatchTable[CurrentIdx++]; 661 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 662 dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs[" 663 << InsnID << "]->getOperand(" << OpIdx 664 << "), Value=" << Value << ")\n"); 665 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 666 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 667 if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value) 668 if (handleReject() == RejectAndGiveUp) 669 return false; 670 break; 671 } 672 case GIM_CheckCmpPredicate: { 673 int64_t InsnID = MatchTable[CurrentIdx++]; 674 int64_t OpIdx = MatchTable[CurrentIdx++]; 675 int64_t Value = MatchTable[CurrentIdx++]; 676 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 677 dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs[" 678 << InsnID << "]->getOperand(" << OpIdx 679 << "), Value=" << Value << ")\n"); 680 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 681 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); 682 if (!MO.isPredicate() || MO.getPredicate() != Value) 683 if (handleReject() == RejectAndGiveUp) 684 return false; 685 break; 686 } 687 case GIM_CheckIsMBB: { 688 int64_t InsnID = MatchTable[CurrentIdx++]; 689 int64_t OpIdx = MatchTable[CurrentIdx++]; 690 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 691 dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID 692 << "]->getOperand(" << OpIdx << "))\n"); 693 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 694 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) { 695 if (handleReject() == RejectAndGiveUp) 696 return false; 697 } 698 break; 699 } 700 case GIM_CheckIsImm: { 701 int64_t InsnID = MatchTable[CurrentIdx++]; 702 int64_t OpIdx = MatchTable[CurrentIdx++]; 703 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 704 dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID 705 << "]->getOperand(" << OpIdx << "))\n"); 706 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 707 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) { 708 if (handleReject() == RejectAndGiveUp) 709 return false; 710 } 711 break; 712 } 713 case GIM_CheckIsSafeToFold: { 714 int64_t InsnID = MatchTable[CurrentIdx++]; 715 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 716 dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs[" 717 << InsnID << "])\n"); 718 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 719 if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) { 720 if (handleReject() == RejectAndGiveUp) 721 return false; 722 } 723 break; 724 } 725 case GIM_CheckIsSameOperand: { 726 int64_t InsnID = MatchTable[CurrentIdx++]; 727 int64_t OpIdx = MatchTable[CurrentIdx++]; 728 int64_t OtherInsnID = MatchTable[CurrentIdx++]; 729 int64_t OtherOpIdx = MatchTable[CurrentIdx++]; 730 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 731 dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs[" 732 << InsnID << "][" << OpIdx << "], MIs[" 733 << OtherInsnID << "][" << OtherOpIdx << "])\n"); 734 assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); 735 assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined"); 736 if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo( 737 State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) { 738 if (handleReject() == RejectAndGiveUp) 739 return false; 740 } 741 break; 742 } 743 case GIM_Reject: 744 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 745 dbgs() << CurrentIdx << ": GIM_Reject\n"); 746 if (handleReject() == RejectAndGiveUp) 747 return false; 748 break; 749 750 case GIR_MutateOpcode: { 751 int64_t OldInsnID = MatchTable[CurrentIdx++]; 752 uint64_t NewInsnID = MatchTable[CurrentIdx++]; 753 int64_t NewOpcode = MatchTable[CurrentIdx++]; 754 if (NewInsnID >= OutMIs.size()) 755 OutMIs.resize(NewInsnID + 1); 756 757 OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(), 758 State.MIs[OldInsnID]); 759 OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode)); 760 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 761 dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs[" 762 << NewInsnID << "], MIs[" << OldInsnID << "], " 763 << NewOpcode << ")\n"); 764 break; 765 } 766 767 case GIR_BuildMI: { 768 uint64_t NewInsnID = MatchTable[CurrentIdx++]; 769 int64_t Opcode = MatchTable[CurrentIdx++]; 770 if (NewInsnID >= OutMIs.size()) 771 OutMIs.resize(NewInsnID + 1); 772 773 OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0], 774 State.MIs[0]->getDebugLoc(), TII.get(Opcode)); 775 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 776 dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs[" 777 << NewInsnID << "], " << Opcode << ")\n"); 778 break; 779 } 780 781 case GIR_Copy: { 782 int64_t NewInsnID = MatchTable[CurrentIdx++]; 783 int64_t OldInsnID = MatchTable[CurrentIdx++]; 784 int64_t OpIdx = MatchTable[CurrentIdx++]; 785 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); 786 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx)); 787 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 788 dbgs() 789 << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID 790 << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n"); 791 break; 792 } 793 794 case GIR_CopyOrAddZeroReg: { 795 int64_t NewInsnID = MatchTable[CurrentIdx++]; 796 int64_t OldInsnID = MatchTable[CurrentIdx++]; 797 int64_t OpIdx = MatchTable[CurrentIdx++]; 798 int64_t ZeroReg = MatchTable[CurrentIdx++]; 799 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); 800 MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx); 801 if (isOperandImmEqual(MO, 0, MRI)) 802 OutMIs[NewInsnID].addReg(ZeroReg); 803 else 804 OutMIs[NewInsnID].add(MO); 805 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 806 dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs[" 807 << NewInsnID << "], MIs[" << OldInsnID << "], " 808 << OpIdx << ", " << ZeroReg << ")\n"); 809 break; 810 } 811 812 case GIR_CopySubReg: { 813 int64_t NewInsnID = MatchTable[CurrentIdx++]; 814 int64_t OldInsnID = MatchTable[CurrentIdx++]; 815 int64_t OpIdx = MatchTable[CurrentIdx++]; 816 int64_t SubRegIdx = MatchTable[CurrentIdx++]; 817 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); 818 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(), 819 0, SubRegIdx); 820 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 821 dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs[" 822 << NewInsnID << "], MIs[" << OldInsnID << "], " 823 << OpIdx << ", " << SubRegIdx << ")\n"); 824 break; 825 } 826 827 case GIR_AddImplicitDef: { 828 int64_t InsnID = MatchTable[CurrentIdx++]; 829 int64_t RegNum = MatchTable[CurrentIdx++]; 830 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 831 OutMIs[InsnID].addDef(RegNum, RegState::Implicit); 832 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 833 dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs[" 834 << InsnID << "], " << RegNum << ")\n"); 835 break; 836 } 837 838 case GIR_AddImplicitUse: { 839 int64_t InsnID = MatchTable[CurrentIdx++]; 840 int64_t RegNum = MatchTable[CurrentIdx++]; 841 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 842 OutMIs[InsnID].addUse(RegNum, RegState::Implicit); 843 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 844 dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs[" 845 << InsnID << "], " << RegNum << ")\n"); 846 break; 847 } 848 849 case GIR_AddRegister: { 850 int64_t InsnID = MatchTable[CurrentIdx++]; 851 int64_t RegNum = MatchTable[CurrentIdx++]; 852 uint64_t RegFlags = MatchTable[CurrentIdx++]; 853 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 854 OutMIs[InsnID].addReg(RegNum, RegFlags); 855 DEBUG_WITH_TYPE( 856 TgtInstructionSelector::getName(), 857 dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs[" 858 << InsnID << "], " << RegNum << ", " << RegFlags << ")\n"); 859 break; 860 } 861 862 case GIR_AddTempRegister: { 863 int64_t InsnID = MatchTable[CurrentIdx++]; 864 int64_t TempRegID = MatchTable[CurrentIdx++]; 865 uint64_t TempRegFlags = MatchTable[CurrentIdx++]; 866 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 867 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags); 868 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 869 dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" 870 << InsnID << "], TempRegisters[" << TempRegID 871 << "], " << TempRegFlags << ")\n"); 872 break; 873 } 874 875 case GIR_AddImm: { 876 int64_t InsnID = MatchTable[CurrentIdx++]; 877 int64_t Imm = MatchTable[CurrentIdx++]; 878 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 879 OutMIs[InsnID].addImm(Imm); 880 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 881 dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID 882 << "], " << Imm << ")\n"); 883 break; 884 } 885 886 case GIR_ComplexRenderer: { 887 int64_t InsnID = MatchTable[CurrentIdx++]; 888 int64_t RendererID = MatchTable[CurrentIdx++]; 889 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 890 for (const auto &RenderOpFn : State.Renderers[RendererID]) 891 RenderOpFn(OutMIs[InsnID]); 892 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 893 dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs[" 894 << InsnID << "], " << RendererID << ")\n"); 895 break; 896 } 897 case GIR_ComplexSubOperandRenderer: { 898 int64_t InsnID = MatchTable[CurrentIdx++]; 899 int64_t RendererID = MatchTable[CurrentIdx++]; 900 int64_t RenderOpID = MatchTable[CurrentIdx++]; 901 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 902 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]); 903 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 904 dbgs() << CurrentIdx 905 << ": GIR_ComplexSubOperandRenderer(OutMIs[" 906 << InsnID << "], " << RendererID << ", " 907 << RenderOpID << ")\n"); 908 break; 909 } 910 911 case GIR_CopyConstantAsSImm: { 912 int64_t NewInsnID = MatchTable[CurrentIdx++]; 913 int64_t OldInsnID = MatchTable[CurrentIdx++]; 914 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); 915 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT"); 916 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) { 917 OutMIs[NewInsnID].addImm( 918 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue()); 919 } else if (State.MIs[OldInsnID]->getOperand(1).isImm()) 920 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1)); 921 else 922 llvm_unreachable("Expected Imm or CImm operand"); 923 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 924 dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs[" 925 << NewInsnID << "], MIs[" << OldInsnID << "])\n"); 926 break; 927 } 928 929 // TODO: Needs a test case once we have a pattern that uses this. 930 case GIR_CopyFConstantAsFPImm: { 931 int64_t NewInsnID = MatchTable[CurrentIdx++]; 932 int64_t OldInsnID = MatchTable[CurrentIdx++]; 933 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); 934 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT"); 935 if (State.MIs[OldInsnID]->getOperand(1).isFPImm()) 936 OutMIs[NewInsnID].addFPImm( 937 State.MIs[OldInsnID]->getOperand(1).getFPImm()); 938 else 939 llvm_unreachable("Expected FPImm operand"); 940 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 941 dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs[" 942 << NewInsnID << "], MIs[" << OldInsnID << "])\n"); 943 break; 944 } 945 946 case GIR_CustomRenderer: { 947 int64_t InsnID = MatchTable[CurrentIdx++]; 948 int64_t OldInsnID = MatchTable[CurrentIdx++]; 949 int64_t RendererFnID = MatchTable[CurrentIdx++]; 950 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 951 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 952 dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs[" 953 << InsnID << "], MIs[" << OldInsnID << "], " 954 << RendererFnID << ")\n"); 955 (ISel.*ISelInfo.CustomRenderers[RendererFnID])( 956 OutMIs[InsnID], *State.MIs[OldInsnID], 957 -1); // Not a source operand of the old instruction. 958 break; 959 } 960 case GIR_CustomOperandRenderer: { 961 int64_t InsnID = MatchTable[CurrentIdx++]; 962 int64_t OldInsnID = MatchTable[CurrentIdx++]; 963 int64_t OpIdx = MatchTable[CurrentIdx++]; 964 int64_t RendererFnID = MatchTable[CurrentIdx++]; 965 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 966 967 DEBUG_WITH_TYPE( 968 TgtInstructionSelector::getName(), 969 dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs[" 970 << InsnID << "], MIs[" << OldInsnID << "]->getOperand(" 971 << OpIdx << "), " 972 << RendererFnID << ")\n"); 973 (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID], 974 *State.MIs[OldInsnID], 975 OpIdx); 976 break; 977 } 978 case GIR_ConstrainOperandRC: { 979 int64_t InsnID = MatchTable[CurrentIdx++]; 980 int64_t OpIdx = MatchTable[CurrentIdx++]; 981 int64_t RCEnum = MatchTable[CurrentIdx++]; 982 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 983 constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx, 984 *TRI.getRegClass(RCEnum), TII, TRI, RBI); 985 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 986 dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs[" 987 << InsnID << "], " << OpIdx << ", " << RCEnum 988 << ")\n"); 989 break; 990 } 991 992 case GIR_ConstrainSelectedInstOperands: { 993 int64_t InsnID = MatchTable[CurrentIdx++]; 994 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 995 constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI, 996 RBI); 997 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 998 dbgs() << CurrentIdx 999 << ": GIR_ConstrainSelectedInstOperands(OutMIs[" 1000 << InsnID << "])\n"); 1001 break; 1002 } 1003 1004 case GIR_MergeMemOperands: { 1005 int64_t InsnID = MatchTable[CurrentIdx++]; 1006 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction"); 1007 1008 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1009 dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs[" 1010 << InsnID << "]"); 1011 int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList; 1012 while ((MergeInsnID = MatchTable[CurrentIdx++]) != 1013 GIU_MergeMemOperands_EndOfList) { 1014 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1015 dbgs() << ", MIs[" << MergeInsnID << "]"); 1016 for (const auto &MMO : State.MIs[MergeInsnID]->memoperands()) 1017 OutMIs[InsnID].addMemOperand(MMO); 1018 } 1019 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n"); 1020 break; 1021 } 1022 1023 case GIR_EraseFromParent: { 1024 int64_t InsnID = MatchTable[CurrentIdx++]; 1025 assert(State.MIs[InsnID] && 1026 "Attempted to erase an undefined instruction"); 1027 State.MIs[InsnID]->eraseFromParent(); 1028 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1029 dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs[" 1030 << InsnID << "])\n"); 1031 break; 1032 } 1033 1034 case GIR_MakeTempReg: { 1035 int64_t TempRegID = MatchTable[CurrentIdx++]; 1036 int64_t TypeID = MatchTable[CurrentIdx++]; 1037 1038 State.TempRegisters[TempRegID] = 1039 MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]); 1040 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1041 dbgs() << CurrentIdx << ": TempRegs[" << TempRegID 1042 << "] = GIR_MakeTempReg(" << TypeID << ")\n"); 1043 break; 1044 } 1045 1046 case GIR_Coverage: { 1047 int64_t RuleID = MatchTable[CurrentIdx++]; 1048 CoverageInfo.setCovered(RuleID); 1049 1050 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1051 dbgs() 1052 << CurrentIdx << ": GIR_Coverage(" << RuleID << ")"); 1053 break; 1054 } 1055 1056 case GIR_Done: 1057 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), 1058 dbgs() << CurrentIdx << ": GIR_Done\n"); 1059 return true; 1060 1061 default: 1062 llvm_unreachable("Unexpected command"); 1063 } 1064 } 1065} 1066 1067} // end namespace llvm 1068 1069#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H 1070