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 "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 16 #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 17 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 20 #define GET_TARGET_REGBANK_IMPL 21 22 #include "MipsGenRegisterBank.inc" 23 24 namespace llvm { 25 namespace Mips { 26 enum PartialMappingIdx { 27 PMI_GPR, 28 PMI_SPR, 29 PMI_DPR, 30 PMI_Min = PMI_GPR, 31 }; 32 33 RegisterBankInfo::PartialMapping PartMappings[]{ 34 {0, 32, GPRBRegBank}, 35 {0, 32, FPRBRegBank}, 36 {0, 64, FPRBRegBank} 37 }; 38 39 enum ValueMappingIdx { 40 InvalidIdx = 0, 41 GPRIdx = 1, 42 SPRIdx = 4, 43 DPRIdx = 7 44 }; 45 46 RegisterBankInfo::ValueMapping ValueMappings[] = { 47 // invalid 48 {nullptr, 0}, 49 // up to 3 operands in GPRs 50 {&PartMappings[PMI_GPR - PMI_Min], 1}, 51 {&PartMappings[PMI_GPR - PMI_Min], 1}, 52 {&PartMappings[PMI_GPR - PMI_Min], 1}, 53 // up to 3 ops operands FPRs - single precission 54 {&PartMappings[PMI_SPR - PMI_Min], 1}, 55 {&PartMappings[PMI_SPR - PMI_Min], 1}, 56 {&PartMappings[PMI_SPR - PMI_Min], 1}, 57 // up to 3 ops operands FPRs - double precission 58 {&PartMappings[PMI_DPR - PMI_Min], 1}, 59 {&PartMappings[PMI_DPR - PMI_Min], 1}, 60 {&PartMappings[PMI_DPR - PMI_Min], 1} 61 }; 62 63 } // end namespace Mips 64 } // end namespace llvm 65 66 using namespace llvm; 67 68 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 69 : MipsGenRegisterBankInfo() {} 70 71 const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 72 const TargetRegisterClass &RC) const { 73 using namespace Mips; 74 75 switch (RC.getID()) { 76 case Mips::GPR32RegClassID: 77 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 78 case Mips::GPRMM16MovePPairFirstRegClassID: 79 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 80 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 81 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 82 case Mips::SP32RegClassID: 83 case Mips::GP32RegClassID: 84 return getRegBank(Mips::GPRBRegBankID); 85 case Mips::FGRCCRegClassID: 86 case Mips::FGR32RegClassID: 87 case Mips::FGR64RegClassID: 88 case Mips::AFGR64RegClassID: 89 return getRegBank(Mips::FPRBRegBankID); 90 default: 91 llvm_unreachable("Register class not supported"); 92 } 93 } 94 95 // Instructions where all register operands are floating point. 96 static bool isFloatingPointOpcode(unsigned Opc) { 97 switch (Opc) { 98 case TargetOpcode::G_FCONSTANT: 99 case TargetOpcode::G_FADD: 100 case TargetOpcode::G_FSUB: 101 case TargetOpcode::G_FMUL: 102 case TargetOpcode::G_FDIV: 103 case TargetOpcode::G_FABS: 104 case TargetOpcode::G_FSQRT: 105 case TargetOpcode::G_FCEIL: 106 case TargetOpcode::G_FFLOOR: 107 case TargetOpcode::G_FPEXT: 108 case TargetOpcode::G_FPTRUNC: 109 return true; 110 default: 111 return false; 112 } 113 } 114 115 // Instructions where use operands are floating point registers. 116 // Def operands are general purpose. 117 static bool isFloatingPointOpcodeUse(unsigned Opc) { 118 switch (Opc) { 119 case TargetOpcode::G_FPTOSI: 120 case TargetOpcode::G_FPTOUI: 121 case TargetOpcode::G_FCMP: 122 case Mips::MFC1: 123 case Mips::ExtractElementF64: 124 case Mips::ExtractElementF64_64: 125 return true; 126 default: 127 return isFloatingPointOpcode(Opc); 128 } 129 } 130 131 // Instructions where def operands are floating point registers. 132 // Use operands are general purpose. 133 static bool isFloatingPointOpcodeDef(unsigned Opc) { 134 switch (Opc) { 135 case TargetOpcode::G_SITOFP: 136 case TargetOpcode::G_UITOFP: 137 case Mips::MTC1: 138 case Mips::BuildPairF64: 139 case Mips::BuildPairF64_64: 140 return true; 141 default: 142 return isFloatingPointOpcode(Opc); 143 } 144 } 145 146 static bool isAmbiguous(unsigned Opc) { 147 switch (Opc) { 148 case TargetOpcode::G_LOAD: 149 case TargetOpcode::G_STORE: 150 case TargetOpcode::G_PHI: 151 case TargetOpcode::G_SELECT: 152 return true; 153 default: 154 return false; 155 } 156 } 157 158 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 159 Register Reg, const MachineRegisterInfo &MRI) { 160 assert(!MRI.getType(Reg).isPointer() && 161 "Pointers are gprb, they should not be considered as ambiguous.\n"); 162 for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 163 if (UseMI.getOpcode() == TargetOpcode::COPY && 164 !TargetRegisterInfo::isPhysicalRegister(UseMI.getOperand(0).getReg())) 165 // Copies of non-physical registers are not supported 166 return; 167 168 DefUses.push_back(&UseMI); 169 } 170 } 171 172 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 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 MachineInstr *DefMI = MRI.getVRegDef(Reg); 177 if (DefMI->getOpcode() == TargetOpcode::COPY && 178 !TargetRegisterInfo::isPhysicalRegister(DefMI->getOperand(1).getReg())) 179 // Copies from non-physical registers are not supported. 180 return; 181 182 UseDefs.push_back(DefMI); 183 } 184 185 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 186 const MachineInstr *MI) { 187 assert(isAmbiguous(MI->getOpcode()) && 188 "Not implemented for non Ambiguous opcode.\n"); 189 190 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 191 192 if (MI->getOpcode() == TargetOpcode::G_LOAD) 193 addDefUses(MI->getOperand(0).getReg(), MRI); 194 195 if (MI->getOpcode() == TargetOpcode::G_STORE) 196 addUseDef(MI->getOperand(0).getReg(), MRI); 197 198 if (MI->getOpcode() == TargetOpcode::G_PHI) { 199 addDefUses(MI->getOperand(0).getReg(), MRI); 200 201 for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 202 addUseDef(MI->getOperand(i).getReg(), MRI); 203 } 204 205 if (MI->getOpcode() == TargetOpcode::G_SELECT) { 206 addDefUses(MI->getOperand(0).getReg(), MRI); 207 208 addUseDef(MI->getOperand(2).getReg(), MRI); 209 addUseDef(MI->getOperand(3).getReg(), MRI); 210 } 211 } 212 213 bool MipsRegisterBankInfo::TypeInfoForMF::visit(const MachineInstr *MI) { 214 assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 215 216 startVisit(MI); 217 AmbiguousRegDefUseContainer DefUseContainer(MI); 218 219 // Visit instructions where MI's DEF operands are USED. 220 if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true)) 221 return true; 222 223 // Visit instructions that DEFINE MI's USE operands. 224 if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false)) 225 return true; 226 227 return false; 228 } 229 230 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 231 const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 232 bool isDefUse) { 233 while (!AdjacentInstrs.empty()) { 234 MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 235 236 if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 237 : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 238 setTypes(MI, InstType::FloatingPoint); 239 return true; 240 } 241 242 // Determine InstType from register bank of phys register that is 243 // 'isDefUse ? def : use' of this copy. 244 if (AdjMI->getOpcode() == TargetOpcode::COPY) { 245 setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 246 return true; 247 } 248 249 if (isAmbiguous(AdjMI->getOpcode())) { 250 // Chains of ambiguous instructions are not supported. 251 return false; 252 } 253 254 // Defaults to integer instruction. Includes G_MERGE_VALUES and 255 // G_UNMERGE_VALUES. 256 setTypes(MI, InstType::Integer); 257 return true; 258 } 259 return false; 260 } 261 262 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 263 InstType InstTy) { 264 changeRecordedTypeForInstr(MI, InstTy); 265 } 266 267 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 268 const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 269 assert((TargetRegisterInfo::isPhysicalRegister( 270 CopyInst->getOperand(Op).getReg())) && 271 "Copies of non physical registers should not be considered here.\n"); 272 273 const MachineFunction &MF = *CopyInst->getMF(); 274 const MachineRegisterInfo &MRI = MF.getRegInfo(); 275 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 276 const RegisterBankInfo &RBI = 277 *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 278 const RegisterBank *Bank = 279 RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 280 281 if (Bank == &Mips::FPRBRegBank) 282 setTypes(MI, InstType::FloatingPoint); 283 else if (Bank == &Mips::GPRBRegBank) 284 setTypes(MI, InstType::Integer); 285 else 286 llvm_unreachable("Unsupported register bank.\n"); 287 } 288 289 MipsRegisterBankInfo::InstType 290 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 291 visit(MI); 292 return getRecordedTypeForInstr(MI); 293 } 294 295 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 296 llvm::StringRef FunctionName) { 297 if (MFName != FunctionName) { 298 MFName = FunctionName; 299 Types.clear(); 300 } 301 } 302 303 const RegisterBankInfo::InstructionMapping & 304 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 305 306 static TypeInfoForMF TI; 307 308 // Reset TI internal data when MF changes. 309 TI.cleanupIfNewFunction(MI.getMF()->getName()); 310 311 unsigned Opc = MI.getOpcode(); 312 const MachineFunction &MF = *MI.getParent()->getParent(); 313 const MachineRegisterInfo &MRI = MF.getRegInfo(); 314 315 if (MI.getOpcode() != TargetOpcode::G_PHI) { 316 const RegisterBankInfo::InstructionMapping &Mapping = 317 getInstrMappingImpl(MI); 318 if (Mapping.isValid()) 319 return Mapping; 320 } 321 322 using namespace TargetOpcode; 323 324 unsigned NumOperands = MI.getNumOperands(); 325 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 326 unsigned MappingID = DefaultMappingID; 327 const unsigned CustomMappingID = 1; 328 329 switch (Opc) { 330 case G_TRUNC: 331 case G_ADD: 332 case G_SUB: 333 case G_MUL: 334 case G_UMULH: 335 case G_ZEXTLOAD: 336 case G_SEXTLOAD: 337 case G_GEP: 338 case G_AND: 339 case G_OR: 340 case G_XOR: 341 case G_SHL: 342 case G_ASHR: 343 case G_LSHR: 344 case G_SDIV: 345 case G_UDIV: 346 case G_SREM: 347 case G_UREM: 348 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 349 break; 350 case G_LOAD: { 351 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 352 InstType InstTy = InstType::Integer; 353 if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 354 InstTy = TI.determineInstType(&MI); 355 } 356 357 if (InstTy == InstType::FloatingPoint) { // fprb 358 OperandsMapping = 359 getOperandsMapping({Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 360 : &Mips::ValueMappings[Mips::DPRIdx], 361 &Mips::ValueMappings[Mips::GPRIdx]}); 362 break; 363 } else { // gprb 364 OperandsMapping = 365 getOperandsMapping({Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 366 : &Mips::ValueMappings[Mips::DPRIdx], 367 &Mips::ValueMappings[Mips::GPRIdx]}); 368 if (Size == 64) 369 MappingID = CustomMappingID; 370 } 371 372 break; 373 } 374 case G_STORE: { 375 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 376 InstType InstTy = InstType::Integer; 377 if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 378 InstTy = TI.determineInstType(&MI); 379 } 380 381 if (InstTy == InstType::FloatingPoint) { // fprb 382 OperandsMapping = 383 getOperandsMapping({Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 384 : &Mips::ValueMappings[Mips::DPRIdx], 385 &Mips::ValueMappings[Mips::GPRIdx]}); 386 break; 387 } else { // gprb 388 OperandsMapping = 389 getOperandsMapping({Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 390 : &Mips::ValueMappings[Mips::DPRIdx], 391 &Mips::ValueMappings[Mips::GPRIdx]}); 392 if (Size == 64) 393 MappingID = CustomMappingID; 394 } 395 break; 396 } 397 case G_PHI: { 398 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 399 InstType InstTy = InstType::Integer; 400 if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 401 InstTy = TI.determineInstType(&MI); 402 } 403 404 // PHI is copylike and should have one regbank in mapping for def register. 405 if (InstTy == InstType::Integer && Size == 64) { // fprb 406 OperandsMapping = 407 getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 408 return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 409 /*NumOperands=*/1); 410 } 411 // Use default handling for PHI, i.e. set reg bank of def operand to match 412 // register banks of use operands. 413 const RegisterBankInfo::InstructionMapping &Mapping = 414 getInstrMappingImpl(MI); 415 return Mapping; 416 } 417 case G_SELECT: { 418 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 419 InstType InstTy = InstType::Integer; 420 if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 421 InstTy = TI.determineInstType(&MI); 422 } 423 424 if (InstTy == InstType::FloatingPoint) { // fprb 425 const RegisterBankInfo::ValueMapping *Bank = 426 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 427 : &Mips::ValueMappings[Mips::DPRIdx]; 428 OperandsMapping = getOperandsMapping( 429 {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 430 break; 431 } else { // gprb 432 const RegisterBankInfo::ValueMapping *Bank = 433 Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 434 : &Mips::ValueMappings[Mips::DPRIdx]; 435 OperandsMapping = getOperandsMapping( 436 {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 437 if (Size == 64) 438 MappingID = CustomMappingID; 439 } 440 break; 441 } 442 case G_UNMERGE_VALUES: { 443 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 444 &Mips::ValueMappings[Mips::GPRIdx], 445 &Mips::ValueMappings[Mips::DPRIdx]}); 446 MappingID = CustomMappingID; 447 break; 448 } 449 case G_MERGE_VALUES: { 450 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 451 &Mips::ValueMappings[Mips::GPRIdx], 452 &Mips::ValueMappings[Mips::GPRIdx]}); 453 MappingID = CustomMappingID; 454 break; 455 } 456 case G_FADD: 457 case G_FSUB: 458 case G_FMUL: 459 case G_FDIV: 460 case G_FABS: 461 case G_FSQRT:{ 462 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 463 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 464 OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 465 : &Mips::ValueMappings[Mips::DPRIdx]; 466 break; 467 } 468 case G_FCONSTANT: { 469 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 470 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 471 const RegisterBankInfo::ValueMapping *FPRValueMapping = 472 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 473 : &Mips::ValueMappings[Mips::DPRIdx]; 474 OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 475 break; 476 } 477 case G_FCMP: { 478 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 479 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 480 const RegisterBankInfo::ValueMapping *FPRValueMapping = 481 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 482 : &Mips::ValueMappings[Mips::DPRIdx]; 483 OperandsMapping = 484 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 485 FPRValueMapping, FPRValueMapping}); 486 break; 487 } 488 case G_FPEXT: 489 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 490 &Mips::ValueMappings[Mips::SPRIdx]}); 491 break; 492 case G_FPTRUNC: 493 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 494 &Mips::ValueMappings[Mips::DPRIdx]}); 495 break; 496 case G_FPTOSI: { 497 unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 498 assert((MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 32) && 499 "Unsupported integer size"); 500 assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 501 OperandsMapping = getOperandsMapping({ 502 &Mips::ValueMappings[Mips::GPRIdx], 503 SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 504 : &Mips::ValueMappings[Mips::DPRIdx], 505 }); 506 break; 507 } 508 case G_SITOFP: { 509 unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 510 unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 511 (void)SizeInt; 512 assert((SizeInt == 32) && "Unsupported integer size"); 513 assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 514 OperandsMapping = 515 getOperandsMapping({SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 516 : &Mips::ValueMappings[Mips::DPRIdx], 517 &Mips::ValueMappings[Mips::GPRIdx]}); 518 break; 519 } 520 case G_CONSTANT: 521 case G_FRAME_INDEX: 522 case G_GLOBAL_VALUE: 523 case G_BRCOND: 524 OperandsMapping = 525 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 526 break; 527 case G_ICMP: 528 OperandsMapping = 529 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 530 &Mips::ValueMappings[Mips::GPRIdx], 531 &Mips::ValueMappings[Mips::GPRIdx]}); 532 break; 533 default: 534 return getInvalidInstructionMapping(); 535 } 536 537 return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 538 NumOperands); 539 } 540 541 using InstListTy = GISelWorkList<4>; 542 namespace { 543 class InstManager : public GISelChangeObserver { 544 InstListTy &InstList; 545 546 public: 547 InstManager(InstListTy &Insts) : InstList(Insts) {} 548 549 void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 550 void erasingInstr(MachineInstr &MI) override {} 551 void changingInstr(MachineInstr &MI) override {} 552 void changedInstr(MachineInstr &MI) override {} 553 }; 554 } // end anonymous namespace 555 556 /// Here we have to narrowScalar s64 operands to s32, combine away 557 /// G_MERGE/G_UNMERGE and erase instructions that became dead in the process. 558 /// We manually assign 32 bit gprb to register operands of all new instructions 559 /// that got created in the process since they will not end up in RegBankSelect 560 /// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++. 561 void MipsRegisterBankInfo::applyMappingImpl( 562 const OperandsMapper &OpdMapper) const { 563 MachineInstr &MI = OpdMapper.getMI(); 564 InstListTy NewInstrs; 565 MachineIRBuilder B(MI); 566 MachineFunction *MF = MI.getMF(); 567 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 568 569 InstManager NewInstrObserver(NewInstrs); 570 GISelObserverWrapper WrapperObserver(&NewInstrObserver); 571 LegalizerHelper Helper(*MF, WrapperObserver, B); 572 LegalizationArtifactCombiner ArtCombiner( 573 B, MF->getRegInfo(), *MF->getSubtarget().getLegalizerInfo()); 574 575 switch (MI.getOpcode()) { 576 case TargetOpcode::G_LOAD: 577 case TargetOpcode::G_STORE: 578 case TargetOpcode::G_PHI: 579 case TargetOpcode::G_SELECT: { 580 Helper.narrowScalar(MI, 0, LLT::scalar(32)); 581 // Handle new instructions. 582 while (!NewInstrs.empty()) { 583 MachineInstr *NewMI = NewInstrs.pop_back_val(); 584 // This is new G_UNMERGE that was created during narrowScalar and will 585 // not be considered for regbank selection. RegBankSelect for mips 586 // visits/makes corresponding G_MERGE first. Combine them here. 587 if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) { 588 SmallVector<MachineInstr *, 2> DeadInstrs; 589 ArtCombiner.tryCombineMerges(*NewMI, DeadInstrs); 590 for (MachineInstr *DeadMI : DeadInstrs) 591 DeadMI->eraseFromParent(); 592 } 593 // This G_MERGE will be combined away when its corresponding G_UNMERGE 594 // gets regBankSelected. 595 else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 596 continue; 597 else 598 // Manually set register banks for all register operands to 32 bit gprb. 599 for (auto Op : NewMI->operands()) { 600 if (Op.isReg()) { 601 assert(MRI.getType(Op.getReg()).getSizeInBits() == 32 && 602 "Only 32 bit gprb is handled here.\n"); 603 MRI.setRegBank(Op.getReg(), getRegBank(Mips::GPRBRegBankID)); 604 } 605 } 606 } 607 return; 608 } 609 case TargetOpcode::G_UNMERGE_VALUES: { 610 SmallVector<MachineInstr *, 2> DeadInstrs; 611 ArtCombiner.tryCombineMerges(MI, DeadInstrs); 612 for (MachineInstr *DeadMI : DeadInstrs) 613 DeadMI->eraseFromParent(); 614 return; 615 } 616 default: 617 break; 618 } 619 620 return applyDefaultMapping(OpdMapper); 621 } 622