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