1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- 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 /// \file 9 /// This file implements the targeting of the RegisterBankInfo class for Mips. 10 /// \todo This should be generated by TableGen. 11 //===----------------------------------------------------------------------===// 12 13 #include "MipsRegisterBankInfo.h" 14 #include "MipsInstrInfo.h" 15 #include "MipsTargetMachine.h" 16 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 17 #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 18 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 21 #define GET_TARGET_REGBANK_IMPL 22 23 #include "MipsGenRegisterBank.inc" 24 25 namespace llvm { 26 namespace Mips { 27 enum PartialMappingIdx { 28 PMI_GPR, 29 PMI_SPR, 30 PMI_DPR, 31 PMI_MSA, 32 PMI_Min = PMI_GPR, 33 }; 34 35 const RegisterBankInfo::PartialMapping PartMappings[]{ 36 {0, 32, GPRBRegBank}, 37 {0, 32, FPRBRegBank}, 38 {0, 64, FPRBRegBank}, 39 {0, 128, FPRBRegBank} 40 }; 41 42 enum ValueMappingIdx { 43 InvalidIdx = 0, 44 GPRIdx = 1, 45 SPRIdx = 4, 46 DPRIdx = 7, 47 MSAIdx = 10 48 }; 49 50 const RegisterBankInfo::ValueMapping ValueMappings[] = { 51 // invalid 52 {nullptr, 0}, 53 // up to 3 operands in GPRs 54 {&PartMappings[PMI_GPR - PMI_Min], 1}, 55 {&PartMappings[PMI_GPR - PMI_Min], 1}, 56 {&PartMappings[PMI_GPR - PMI_Min], 1}, 57 // up to 3 operands in FPRs - single precission 58 {&PartMappings[PMI_SPR - PMI_Min], 1}, 59 {&PartMappings[PMI_SPR - PMI_Min], 1}, 60 {&PartMappings[PMI_SPR - PMI_Min], 1}, 61 // up to 3 operands in FPRs - double precission 62 {&PartMappings[PMI_DPR - PMI_Min], 1}, 63 {&PartMappings[PMI_DPR - PMI_Min], 1}, 64 {&PartMappings[PMI_DPR - PMI_Min], 1}, 65 // up to 3 operands in FPRs - MSA 66 {&PartMappings[PMI_MSA - PMI_Min], 1}, 67 {&PartMappings[PMI_MSA - PMI_Min], 1}, 68 {&PartMappings[PMI_MSA - PMI_Min], 1} 69 }; 70 71 } // end namespace Mips 72 } // end namespace llvm 73 74 using namespace llvm; 75 76 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) {} 77 78 const RegisterBank & 79 MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, 80 LLT) const { 81 using namespace Mips; 82 83 switch (RC.getID()) { 84 case Mips::GPR32RegClassID: 85 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 86 case Mips::GPRMM16MovePPairFirstRegClassID: 87 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 88 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 89 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 90 case Mips::SP32RegClassID: 91 case Mips::GP32RegClassID: 92 return getRegBank(Mips::GPRBRegBankID); 93 case Mips::FGRCCRegClassID: 94 case Mips::FGR32RegClassID: 95 case Mips::FGR64RegClassID: 96 case Mips::AFGR64RegClassID: 97 case Mips::MSA128BRegClassID: 98 case Mips::MSA128HRegClassID: 99 case Mips::MSA128WRegClassID: 100 case Mips::MSA128DRegClassID: 101 return getRegBank(Mips::FPRBRegBankID); 102 default: 103 llvm_unreachable("Register class not supported"); 104 } 105 } 106 107 // Instructions where use operands are floating point registers. 108 // Def operands are general purpose. 109 static bool isFloatingPointOpcodeUse(unsigned Opc) { 110 switch (Opc) { 111 case TargetOpcode::G_FPTOSI: 112 case TargetOpcode::G_FPTOUI: 113 case TargetOpcode::G_FCMP: 114 return true; 115 default: 116 return isPreISelGenericFloatingPointOpcode(Opc); 117 } 118 } 119 120 // Instructions where def operands are floating point registers. 121 // Use operands are general purpose. 122 static bool isFloatingPointOpcodeDef(unsigned Opc) { 123 switch (Opc) { 124 case TargetOpcode::G_SITOFP: 125 case TargetOpcode::G_UITOFP: 126 return true; 127 default: 128 return isPreISelGenericFloatingPointOpcode(Opc); 129 } 130 } 131 132 static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI) { 133 if (MI->getOpcode() == TargetOpcode::G_LOAD || 134 MI->getOpcode() == TargetOpcode::G_STORE) { 135 auto MMO = *MI->memoperands_begin(); 136 const MipsSubtarget &STI = MI->getMF()->getSubtarget<MipsSubtarget>(); 137 if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() && 138 (!MMO->getSize().hasValue() || 139 MMO->getAlign() < MMO->getSize().getValue()))) 140 return true; 141 } 142 return false; 143 } 144 145 static bool isAmbiguous(unsigned Opc) { 146 switch (Opc) { 147 case TargetOpcode::G_LOAD: 148 case TargetOpcode::G_STORE: 149 case TargetOpcode::G_PHI: 150 case TargetOpcode::G_SELECT: 151 case TargetOpcode::G_IMPLICIT_DEF: 152 case TargetOpcode::G_UNMERGE_VALUES: 153 case TargetOpcode::G_MERGE_VALUES: 154 return true; 155 default: 156 return false; 157 } 158 } 159 160 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 161 Register Reg, const MachineRegisterInfo &MRI) { 162 assert(!MRI.getType(Reg).isPointer() && 163 "Pointers are gprb, they should not be considered as ambiguous.\n"); 164 for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 165 MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 166 // Copy with many uses. 167 if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 168 !NonCopyInstr->getOperand(0).getReg().isPhysical()) 169 addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 170 else 171 DefUses.push_back(skipCopiesOutgoing(&UseMI)); 172 } 173 } 174 175 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 176 Register Reg, const MachineRegisterInfo &MRI) { 177 assert(!MRI.getType(Reg).isPointer() && 178 "Pointers are gprb, they should not be considered as ambiguous.\n"); 179 MachineInstr *DefMI = MRI.getVRegDef(Reg); 180 UseDefs.push_back(skipCopiesIncoming(DefMI)); 181 } 182 183 MachineInstr * 184 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 185 MachineInstr *MI) const { 186 const MachineFunction &MF = *MI->getParent()->getParent(); 187 const MachineRegisterInfo &MRI = MF.getRegInfo(); 188 MachineInstr *Ret = MI; 189 while (Ret->getOpcode() == TargetOpcode::COPY && 190 !Ret->getOperand(0).getReg().isPhysical() && 191 MRI.hasOneUse(Ret->getOperand(0).getReg())) { 192 Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 193 } 194 return Ret; 195 } 196 197 MachineInstr * 198 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 199 MachineInstr *MI) const { 200 const MachineFunction &MF = *MI->getParent()->getParent(); 201 const MachineRegisterInfo &MRI = MF.getRegInfo(); 202 MachineInstr *Ret = MI; 203 while (Ret->getOpcode() == TargetOpcode::COPY && 204 !Ret->getOperand(1).getReg().isPhysical()) 205 Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 206 return Ret; 207 } 208 209 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 210 const MachineInstr *MI) { 211 assert(isAmbiguous(MI->getOpcode()) && 212 "Not implemented for non Ambiguous opcode.\n"); 213 214 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 215 216 if (MI->getOpcode() == TargetOpcode::G_LOAD) 217 addDefUses(MI->getOperand(0).getReg(), MRI); 218 219 if (MI->getOpcode() == TargetOpcode::G_STORE) 220 addUseDef(MI->getOperand(0).getReg(), MRI); 221 222 if (auto *PHI = dyn_cast<GPhi>(MI)) { 223 addDefUses(PHI->getReg(0), MRI); 224 225 for (unsigned I = 1; I < PHI->getNumIncomingValues(); ++I) 226 addUseDef(PHI->getIncomingValue(I), MRI); 227 } 228 229 if (MI->getOpcode() == TargetOpcode::G_SELECT) { 230 addDefUses(MI->getOperand(0).getReg(), MRI); 231 232 addUseDef(MI->getOperand(2).getReg(), MRI); 233 addUseDef(MI->getOperand(3).getReg(), MRI); 234 } 235 236 if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 237 addDefUses(MI->getOperand(0).getReg(), MRI); 238 239 if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) 240 addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI); 241 242 if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 243 addDefUses(MI->getOperand(0).getReg(), MRI); 244 } 245 246 bool MipsRegisterBankInfo::TypeInfoForMF::visit( 247 const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI, 248 InstType &AmbiguousTy) { 249 assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 250 if (wasVisited(MI)) 251 return true; // InstType has already been determined for MI. 252 253 startVisit(MI); 254 AmbiguousRegDefUseContainer DefUseContainer(MI); 255 256 if (isGprbTwoInstrUnalignedLoadOrStore(MI)) { 257 setTypes(MI, Integer); 258 return true; 259 } 260 261 if (AmbiguousTy == InstType::Ambiguous && 262 (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES || 263 MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)) 264 AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge; 265 266 // Visit instructions where MI's DEF operands are USED. 267 if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy)) 268 return true; 269 270 // Visit instructions that DEFINE MI's USE operands. 271 if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy)) 272 return true; 273 274 // All MI's adjacent instructions, are ambiguous. 275 if (!WaitingForTypeOfMI) { 276 // This is chain of ambiguous instructions. 277 setTypes(MI, AmbiguousTy); 278 return true; 279 } 280 // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 281 // instructions or has no other adjacent instructions. Anyway InstType could 282 // not be determined. There could be unexplored path from some of 283 // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 284 // mapping available. 285 // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 286 // this way when WaitingForTypeOfMI figures out its InstType same InstType 287 // will be assigned to all instructions in this branch. 288 addToWaitingQueue(WaitingForTypeOfMI, MI); 289 return false; 290 } 291 292 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 293 const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 294 bool isDefUse, InstType &AmbiguousTy) { 295 while (!AdjacentInstrs.empty()) { 296 MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 297 298 if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 299 : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 300 setTypes(MI, InstType::FloatingPoint); 301 return true; 302 } 303 304 // Determine InstType from register bank of phys register that is 305 // 'isDefUse ? def : use' of this copy. 306 if (AdjMI->getOpcode() == TargetOpcode::COPY) { 307 setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 308 return true; 309 } 310 311 // Defaults to integer instruction. Small registers in G_MERGE (uses) and 312 // G_UNMERGE (defs) will always be gprb. 313 if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) || 314 (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) || 315 !isAmbiguous(AdjMI->getOpcode())) { 316 setTypes(MI, InstType::Integer); 317 return true; 318 } 319 320 // When AdjMI was visited first, MI has to continue to explore remaining 321 // adjacent instructions and determine InstType without visiting AdjMI. 322 if (!wasVisited(AdjMI) || 323 getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 324 if (visit(AdjMI, MI, AmbiguousTy)) { 325 // InstType is successfully determined and is same as for AdjMI. 326 setTypes(MI, getRecordedTypeForInstr(AdjMI)); 327 return true; 328 } 329 } 330 } 331 return false; 332 } 333 334 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 335 InstType InstTy) { 336 changeRecordedTypeForInstr(MI, InstTy); 337 for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 338 setTypes(WaitingInstr, InstTy); 339 } 340 } 341 342 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 343 const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 344 assert((CopyInst->getOperand(Op).getReg().isPhysical()) && 345 "Copies of non physical registers should not be considered here.\n"); 346 347 const MachineFunction &MF = *CopyInst->getMF(); 348 const MachineRegisterInfo &MRI = MF.getRegInfo(); 349 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 350 const RegisterBankInfo &RBI = 351 *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 352 const RegisterBank *Bank = 353 RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 354 355 if (Bank == &Mips::FPRBRegBank) 356 setTypes(MI, InstType::FloatingPoint); 357 else if (Bank == &Mips::GPRBRegBank) 358 setTypes(MI, InstType::Integer); 359 else 360 llvm_unreachable("Unsupported register bank.\n"); 361 } 362 363 MipsRegisterBankInfo::InstType 364 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 365 InstType DefaultAmbiguousType = InstType::Ambiguous; 366 visit(MI, nullptr, DefaultAmbiguousType); 367 return getRecordedTypeForInstr(MI); 368 } 369 370 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 371 llvm::StringRef FunctionName) { 372 if (MFName != FunctionName) { 373 MFName = std::string(FunctionName); 374 WaitingQueues.clear(); 375 Types.clear(); 376 } 377 } 378 379 static const MipsRegisterBankInfo::ValueMapping * 380 getMSAMapping(const MachineFunction &MF) { 381 assert(MF.getSubtarget<MipsSubtarget>().hasMSA() && 382 "MSA mapping not available on target without MSA."); 383 return &Mips::ValueMappings[Mips::MSAIdx]; 384 } 385 386 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) { 387 return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 388 : &Mips::ValueMappings[Mips::DPRIdx]; 389 } 390 391 static const unsigned CustomMappingID = 1; 392 393 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e. 394 // will be split into two 32 bit registers in gprb. 395 static const MipsRegisterBankInfo::ValueMapping * 396 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) { 397 if (Size == 32) 398 return &Mips::ValueMappings[Mips::GPRIdx]; 399 400 MappingID = CustomMappingID; 401 return &Mips::ValueMappings[Mips::DPRIdx]; 402 } 403 404 const RegisterBankInfo::InstructionMapping & 405 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 406 407 static TypeInfoForMF TI; 408 409 // Reset TI internal data when MF changes. 410 TI.cleanupIfNewFunction(MI.getMF()->getName()); 411 412 unsigned Opc = MI.getOpcode(); 413 const MachineFunction &MF = *MI.getParent()->getParent(); 414 const MachineRegisterInfo &MRI = MF.getRegInfo(); 415 416 if (MI.getOpcode() != TargetOpcode::G_PHI) { 417 const RegisterBankInfo::InstructionMapping &Mapping = 418 getInstrMappingImpl(MI); 419 if (Mapping.isValid()) 420 return Mapping; 421 } 422 423 using namespace TargetOpcode; 424 425 unsigned NumOperands = MI.getNumOperands(); 426 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 427 unsigned MappingID = DefaultMappingID; 428 429 // Check if LLT sizes match sizes of available register banks. 430 for (const MachineOperand &Op : MI.operands()) { 431 if (Op.isReg()) { 432 LLT RegTy = MRI.getType(Op.getReg()); 433 434 if (RegTy.isScalar() && 435 (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64)) 436 return getInvalidInstructionMapping(); 437 438 if (RegTy.isVector() && RegTy.getSizeInBits() != 128) 439 return getInvalidInstructionMapping(); 440 } 441 } 442 443 const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg()); 444 unsigned Op0Size = Op0Ty.getSizeInBits(); 445 InstType InstTy = InstType::Integer; 446 447 switch (Opc) { 448 case G_TRUNC: 449 case G_UMULH: 450 case G_ZEXTLOAD: 451 case G_SEXTLOAD: 452 case G_PTR_ADD: 453 case G_INTTOPTR: 454 case G_PTRTOINT: 455 case G_AND: 456 case G_OR: 457 case G_XOR: 458 case G_SHL: 459 case G_ASHR: 460 case G_LSHR: 461 case G_BRINDIRECT: 462 case G_VASTART: 463 case G_BSWAP: 464 case G_CTLZ: 465 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 466 break; 467 case G_ADD: 468 case G_SUB: 469 case G_MUL: 470 case G_SDIV: 471 case G_SREM: 472 case G_UDIV: 473 case G_UREM: 474 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 475 if (Op0Size == 128) 476 OperandsMapping = getMSAMapping(MF); 477 break; 478 case G_STORE: 479 case G_LOAD: { 480 if (Op0Size == 128) { 481 OperandsMapping = getOperandsMapping( 482 {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]}); 483 break; 484 } 485 486 if (!Op0Ty.isPointer()) 487 InstTy = TI.determineInstType(&MI); 488 489 if (isFloatingPoint_32or64(InstTy, Op0Size) || 490 isAmbiguous_64(InstTy, Op0Size)) { 491 OperandsMapping = getOperandsMapping( 492 {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 493 } else { 494 assert((isInteger_32(InstTy, Op0Size) || 495 isAmbiguous_32(InstTy, Op0Size) || 496 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 497 "Unexpected Inst type"); 498 OperandsMapping = 499 getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID), 500 &Mips::ValueMappings[Mips::GPRIdx]}); 501 } 502 503 break; 504 } 505 case G_PHI: { 506 if (!Op0Ty.isPointer()) 507 InstTy = TI.determineInstType(&MI); 508 509 // PHI is copylike and should have one regbank in mapping for def register. 510 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) { 511 OperandsMapping = 512 getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 513 TI.clearTypeInfoData(&MI); 514 return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 515 /*NumOperands=*/1); 516 } 517 assert((isInteger_32(InstTy, Op0Size) || 518 isFloatingPoint_32or64(InstTy, Op0Size) || 519 isAmbiguous_32or64(InstTy, Op0Size)) && 520 "Unexpected Inst type"); 521 // Use default handling for PHI, i.e. set reg bank of def operand to match 522 // register banks of use operands. 523 return getInstrMappingImpl(MI); 524 } 525 case G_SELECT: { 526 if (!Op0Ty.isPointer()) 527 InstTy = TI.determineInstType(&MI); 528 if (isFloatingPoint_32or64(InstTy, Op0Size) || 529 isAmbiguous_64(InstTy, Op0Size)) { 530 const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size); 531 OperandsMapping = getOperandsMapping( 532 {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 533 break; 534 } else { 535 assert((isInteger_32(InstTy, Op0Size) || 536 isAmbiguous_32(InstTy, Op0Size) || 537 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 538 "Unexpected Inst type"); 539 const RegisterBankInfo::ValueMapping *Bank = 540 getGprbOrCustomMapping(Op0Size, MappingID); 541 OperandsMapping = getOperandsMapping( 542 {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 543 } 544 break; 545 } 546 case G_IMPLICIT_DEF: { 547 if (!Op0Ty.isPointer()) 548 InstTy = TI.determineInstType(&MI); 549 550 if (isFloatingPoint_32or64(InstTy, Op0Size)) 551 OperandsMapping = getFprbMapping(Op0Size); 552 else { 553 assert((isInteger_32(InstTy, Op0Size) || 554 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 555 "Unexpected Inst type"); 556 OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID); 557 } 558 } break; 559 case G_UNMERGE_VALUES: { 560 assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES"); 561 unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 562 InstTy = TI.determineInstType(&MI); 563 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) || 564 isFloatingPoint_64(InstTy, Op3Size)) && 565 "Unexpected Inst type"); 566 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 567 &Mips::ValueMappings[Mips::GPRIdx], 568 &Mips::ValueMappings[Mips::DPRIdx]}); 569 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size)) 570 MappingID = CustomMappingID; 571 break; 572 } 573 case G_MERGE_VALUES: { 574 InstTy = TI.determineInstType(&MI); 575 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) || 576 isFloatingPoint_64(InstTy, Op0Size)) && 577 "Unexpected Inst type"); 578 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 579 &Mips::ValueMappings[Mips::GPRIdx], 580 &Mips::ValueMappings[Mips::GPRIdx]}); 581 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) 582 MappingID = CustomMappingID; 583 break; 584 } 585 case G_FADD: 586 case G_FSUB: 587 case G_FMUL: 588 case G_FDIV: 589 case G_FABS: 590 case G_FSQRT: 591 OperandsMapping = getFprbMapping(Op0Size); 592 if (Op0Size == 128) 593 OperandsMapping = getMSAMapping(MF); 594 break; 595 case G_FCONSTANT: 596 OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr}); 597 break; 598 case G_FCMP: { 599 unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 600 OperandsMapping = 601 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 602 getFprbMapping(Op2Size), getFprbMapping(Op2Size)}); 603 break; 604 } 605 case G_FPEXT: 606 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 607 &Mips::ValueMappings[Mips::SPRIdx]}); 608 break; 609 case G_FPTRUNC: 610 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 611 &Mips::ValueMappings[Mips::DPRIdx]}); 612 break; 613 case G_FPTOSI: { 614 assert((Op0Size == 32) && "Unsupported integer size"); 615 unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 616 OperandsMapping = getOperandsMapping( 617 {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)}); 618 break; 619 } 620 case G_SITOFP: 621 assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) && 622 "Unsupported integer size"); 623 OperandsMapping = getOperandsMapping( 624 {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 625 break; 626 case G_CONSTANT: 627 case G_FRAME_INDEX: 628 case G_GLOBAL_VALUE: 629 case G_JUMP_TABLE: 630 case G_BRCOND: 631 OperandsMapping = 632 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 633 break; 634 case G_BRJT: 635 OperandsMapping = 636 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 637 &Mips::ValueMappings[Mips::GPRIdx]}); 638 break; 639 case G_ICMP: 640 OperandsMapping = 641 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 642 &Mips::ValueMappings[Mips::GPRIdx], 643 &Mips::ValueMappings[Mips::GPRIdx]}); 644 break; 645 default: 646 return getInvalidInstructionMapping(); 647 } 648 649 if (MappingID == CustomMappingID) 650 TI.clearTypeInfoData(&MI); 651 return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 652 NumOperands); 653 } 654 655 using InstListTy = GISelWorkList<4>; 656 namespace { 657 class InstManager : public GISelChangeObserver { 658 InstListTy &InstList; 659 MachineIRBuilder &B; 660 661 public: 662 InstManager(MachineIRBuilder &B, InstListTy &Insts) : InstList(Insts), B(B) { 663 assert(!B.isObservingChanges()); 664 B.setChangeObserver(*this); 665 } 666 667 ~InstManager() { B.stopObservingChanges(); } 668 669 void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 670 void erasingInstr(MachineInstr &MI) override {} 671 void changingInstr(MachineInstr &MI) override {} 672 void changedInstr(MachineInstr &MI) override {} 673 }; 674 } // end anonymous namespace 675 676 void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, 677 MachineRegisterInfo &MRI) const { 678 Register Dest = MI.getOperand(0).getReg(); 679 switch (MI.getOpcode()) { 680 case TargetOpcode::G_STORE: 681 // No def operands, skip this instruction. 682 break; 683 case TargetOpcode::G_CONSTANT: 684 case TargetOpcode::G_LOAD: 685 case TargetOpcode::G_SELECT: 686 case TargetOpcode::G_PHI: 687 case TargetOpcode::G_IMPLICIT_DEF: { 688 assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type."); 689 MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 690 break; 691 } 692 case TargetOpcode::G_PTR_ADD: { 693 assert(MRI.getType(Dest).isPointer() && "Unexpected operand type."); 694 MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 695 break; 696 } 697 default: 698 llvm_unreachable("Unexpected opcode."); 699 } 700 } 701 702 static void 703 combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, 704 GUnmerge &MI, GISelChangeObserver &Observer) { 705 SmallVector<Register, 4> UpdatedDefs; 706 SmallVector<MachineInstr *, 2> DeadInstrs; 707 ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs, 708 UpdatedDefs, Observer); 709 for (MachineInstr *DeadMI : DeadInstrs) 710 DeadMI->eraseFromParent(); 711 } 712 713 void MipsRegisterBankInfo::applyMappingImpl( 714 MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const { 715 MachineInstr &MI = OpdMapper.getMI(); 716 Builder.setInstrAndDebugLoc(MI); 717 718 InstListTy NewInstrs; 719 MachineFunction *MF = MI.getMF(); 720 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 721 const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo(); 722 723 InstManager NewInstrObserver(Builder, NewInstrs); 724 LegalizerHelper Helper(*MF, NewInstrObserver, Builder); 725 LegalizationArtifactCombiner ArtCombiner(Builder, MF->getRegInfo(), LegInfo); 726 727 switch (MI.getOpcode()) { 728 case TargetOpcode::G_LOAD: 729 case TargetOpcode::G_STORE: 730 case TargetOpcode::G_PHI: 731 case TargetOpcode::G_SELECT: 732 case TargetOpcode::G_IMPLICIT_DEF: { 733 Helper.narrowScalar(MI, 0, LLT::scalar(32)); 734 // Handle new instructions. 735 while (!NewInstrs.empty()) { 736 MachineInstr *NewMI = NewInstrs.pop_back_val(); 737 // This is new G_UNMERGE that was created during narrowScalar and will 738 // not be considered for regbank selection. RegBankSelect for mips 739 // visits/makes corresponding G_MERGE first. Combine them here. 740 if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI)) 741 combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver); 742 // This G_MERGE will be combined away when its corresponding G_UNMERGE 743 // gets regBankSelected. 744 else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 745 continue; 746 else 747 // Manually set register banks for def operands to 32 bit gprb. 748 setRegBank(*NewMI, MRI); 749 } 750 return; 751 } 752 case TargetOpcode::G_UNMERGE_VALUES: 753 combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI), 754 NewInstrObserver); 755 return; 756 default: 757 break; 758 } 759 760 return applyDefaultMapping(OpdMapper); 761 } 762