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