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