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