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