1fac93e28SPetar Jovanovic //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===// 2fac93e28SPetar Jovanovic // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fac93e28SPetar Jovanovic // 7fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===// 8fac93e28SPetar Jovanovic /// \file 9fac93e28SPetar Jovanovic /// This file implements the targeting of the RegisterBankInfo class for Mips. 10fac93e28SPetar Jovanovic /// \todo This should be generated by TableGen. 11fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===// 12fac93e28SPetar Jovanovic 13fac93e28SPetar Jovanovic #include "MipsRegisterBankInfo.h" 14ec575f6eSPetar Avramovic #include "MipsInstrInfo.h" 15599591f3SPetar Avramovic #include "MipsTargetMachine.h" 16ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 17ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 18ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 19fac93e28SPetar Jovanovic #include "llvm/CodeGen/MachineRegisterInfo.h" 20fac93e28SPetar Jovanovic 21366857a2SPetar Jovanovic #define GET_TARGET_REGBANK_IMPL 22fac93e28SPetar Jovanovic 23366857a2SPetar Jovanovic #include "MipsGenRegisterBank.inc" 24366857a2SPetar Jovanovic 25366857a2SPetar Jovanovic namespace llvm { 26366857a2SPetar Jovanovic namespace Mips { 27366857a2SPetar Jovanovic enum PartialMappingIdx { 28366857a2SPetar Jovanovic PMI_GPR, 291af05df3SPetar Avramovic PMI_SPR, 301af05df3SPetar Avramovic PMI_DPR, 31599591f3SPetar Avramovic PMI_MSA, 32366857a2SPetar Jovanovic PMI_Min = PMI_GPR, 33366857a2SPetar Jovanovic }; 34366857a2SPetar Jovanovic 35366857a2SPetar Jovanovic RegisterBankInfo::PartialMapping PartMappings[]{ 361af05df3SPetar Avramovic {0, 32, GPRBRegBank}, 371af05df3SPetar Avramovic {0, 32, FPRBRegBank}, 38599591f3SPetar Avramovic {0, 64, FPRBRegBank}, 39599591f3SPetar Avramovic {0, 128, FPRBRegBank} 40366857a2SPetar Jovanovic }; 41366857a2SPetar Jovanovic 421af05df3SPetar Avramovic enum ValueMappingIdx { 431af05df3SPetar Avramovic InvalidIdx = 0, 441af05df3SPetar Avramovic GPRIdx = 1, 451af05df3SPetar Avramovic SPRIdx = 4, 46599591f3SPetar Avramovic DPRIdx = 7, 47599591f3SPetar Avramovic MSAIdx = 10 481af05df3SPetar Avramovic }; 49366857a2SPetar Jovanovic 50366857a2SPetar Jovanovic RegisterBankInfo::ValueMapping ValueMappings[] = { 51366857a2SPetar Jovanovic // invalid 52366857a2SPetar Jovanovic {nullptr, 0}, 531af05df3SPetar Avramovic // up to 3 operands in GPRs 54366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 55366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 561af05df3SPetar Avramovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 57f7c213c9SPetar Avramovic // up to 3 operands in FPRs - single precission 581af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 591af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 601af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 61f7c213c9SPetar Avramovic // up to 3 operands in FPRs - double precission 621af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 631af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 64599591f3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 65599591f3SPetar Avramovic // up to 3 operands in FPRs - MSA 66599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1}, 67599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1}, 68599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1} 691af05df3SPetar Avramovic }; 70366857a2SPetar Jovanovic 71366857a2SPetar Jovanovic } // end namespace Mips 72366857a2SPetar Jovanovic } // end namespace llvm 73366857a2SPetar Jovanovic 74366857a2SPetar Jovanovic using namespace llvm; 75fac93e28SPetar Jovanovic 76fac93e28SPetar Jovanovic MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 77fac93e28SPetar Jovanovic : MipsGenRegisterBankInfo() {} 78366857a2SPetar Jovanovic 79366857a2SPetar Jovanovic const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 80366857a2SPetar Jovanovic const TargetRegisterClass &RC) const { 81366857a2SPetar Jovanovic using namespace Mips; 82366857a2SPetar Jovanovic 83366857a2SPetar Jovanovic switch (RC.getID()) { 84366857a2SPetar Jovanovic case Mips::GPR32RegClassID: 85366857a2SPetar Jovanovic case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 86852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirstRegClassID: 87852dd83bSSimon Atanasyan case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 88366857a2SPetar Jovanovic case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 89852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 90021e4c82SPetar Jovanovic case Mips::SP32RegClassID: 91efcd3c00SPetar Avramovic case Mips::GP32RegClassID: 92366857a2SPetar Jovanovic return getRegBank(Mips::GPRBRegBankID); 933dfa368dSPetar Avramovic case Mips::FGRCCRegClassID: 94afa3afa3SPetar Avramovic case Mips::FGR32RegClassID: 953dfa368dSPetar Avramovic case Mips::FGR64RegClassID: 963dfa368dSPetar Avramovic case Mips::AFGR64RegClassID: 97599591f3SPetar Avramovic case Mips::MSA128BRegClassID: 98599591f3SPetar Avramovic case Mips::MSA128HRegClassID: 99599591f3SPetar Avramovic case Mips::MSA128WRegClassID: 100599591f3SPetar Avramovic case Mips::MSA128DRegClassID: 1013dfa368dSPetar Avramovic return getRegBank(Mips::FPRBRegBankID); 102366857a2SPetar Jovanovic default: 103366857a2SPetar Jovanovic llvm_unreachable("Register class not supported"); 104366857a2SPetar Jovanovic } 105366857a2SPetar Jovanovic } 106366857a2SPetar Jovanovic 107ec575f6eSPetar Avramovic // Instructions where all register operands are floating point. 108ec575f6eSPetar Avramovic static bool isFloatingPointOpcode(unsigned Opc) { 109ec575f6eSPetar Avramovic switch (Opc) { 110ec575f6eSPetar Avramovic case TargetOpcode::G_FCONSTANT: 111ec575f6eSPetar Avramovic case TargetOpcode::G_FADD: 112ec575f6eSPetar Avramovic case TargetOpcode::G_FSUB: 113ec575f6eSPetar Avramovic case TargetOpcode::G_FMUL: 114ec575f6eSPetar Avramovic case TargetOpcode::G_FDIV: 115ec575f6eSPetar Avramovic case TargetOpcode::G_FABS: 116ec575f6eSPetar Avramovic case TargetOpcode::G_FSQRT: 117ec575f6eSPetar Avramovic case TargetOpcode::G_FCEIL: 118ec575f6eSPetar Avramovic case TargetOpcode::G_FFLOOR: 119ec575f6eSPetar Avramovic case TargetOpcode::G_FPEXT: 120ec575f6eSPetar Avramovic case TargetOpcode::G_FPTRUNC: 121ec575f6eSPetar Avramovic return true; 122ec575f6eSPetar Avramovic default: 123ec575f6eSPetar Avramovic return false; 124ec575f6eSPetar Avramovic } 125ec575f6eSPetar Avramovic } 126ec575f6eSPetar Avramovic 127aa699b20SPetar Avramovic // Instructions where use operands are floating point registers. 128aa699b20SPetar Avramovic // Def operands are general purpose. 129aa699b20SPetar Avramovic static bool isFloatingPointOpcodeUse(unsigned Opc) { 130aa699b20SPetar Avramovic switch (Opc) { 131aa699b20SPetar Avramovic case TargetOpcode::G_FPTOSI: 132aa699b20SPetar Avramovic case TargetOpcode::G_FPTOUI: 133aa699b20SPetar Avramovic case TargetOpcode::G_FCMP: 134aa699b20SPetar Avramovic case Mips::MFC1: 135aa699b20SPetar Avramovic case Mips::ExtractElementF64: 136aa699b20SPetar Avramovic case Mips::ExtractElementF64_64: 137aa699b20SPetar Avramovic return true; 138aa699b20SPetar Avramovic default: 139aa699b20SPetar Avramovic return isFloatingPointOpcode(Opc); 140aa699b20SPetar Avramovic } 141aa699b20SPetar Avramovic } 142aa699b20SPetar Avramovic 143ec575f6eSPetar Avramovic // Instructions where def operands are floating point registers. 144ec575f6eSPetar Avramovic // Use operands are general purpose. 145ec575f6eSPetar Avramovic static bool isFloatingPointOpcodeDef(unsigned Opc) { 146ec575f6eSPetar Avramovic switch (Opc) { 147ec575f6eSPetar Avramovic case TargetOpcode::G_SITOFP: 148ec575f6eSPetar Avramovic case TargetOpcode::G_UITOFP: 149ec575f6eSPetar Avramovic case Mips::MTC1: 150ec575f6eSPetar Avramovic case Mips::BuildPairF64: 151ec575f6eSPetar Avramovic case Mips::BuildPairF64_64: 152ec575f6eSPetar Avramovic return true; 153ec575f6eSPetar Avramovic default: 154ec575f6eSPetar Avramovic return isFloatingPointOpcode(Opc); 155ec575f6eSPetar Avramovic } 156ec575f6eSPetar Avramovic } 157ec575f6eSPetar Avramovic 158ec575f6eSPetar Avramovic static bool isAmbiguous(unsigned Opc) { 159ec575f6eSPetar Avramovic switch (Opc) { 160ec575f6eSPetar Avramovic case TargetOpcode::G_LOAD: 161ec575f6eSPetar Avramovic case TargetOpcode::G_STORE: 162ec575f6eSPetar Avramovic case TargetOpcode::G_PHI: 163ec575f6eSPetar Avramovic case TargetOpcode::G_SELECT: 16475e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: 165ec575f6eSPetar Avramovic return true; 166ec575f6eSPetar Avramovic default: 167ec575f6eSPetar Avramovic return false; 168ec575f6eSPetar Avramovic } 169ec575f6eSPetar Avramovic } 170ec575f6eSPetar Avramovic 171aa699b20SPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 172aa699b20SPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 173aa699b20SPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 174aa699b20SPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 175aa699b20SPetar Avramovic for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 17696252407SPetar Avramovic MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 17796252407SPetar Avramovic // Copy with many uses. 17896252407SPetar Avramovic if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 1792bea69bfSDaniel Sanders !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg())) 18096252407SPetar Avramovic addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 18196252407SPetar Avramovic else 18296252407SPetar Avramovic DefUses.push_back(skipCopiesOutgoing(&UseMI)); 183aa699b20SPetar Avramovic } 184aa699b20SPetar Avramovic } 185aa699b20SPetar Avramovic 186ec575f6eSPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 187ec575f6eSPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 188ec575f6eSPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 189ec575f6eSPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 190ec575f6eSPetar Avramovic MachineInstr *DefMI = MRI.getVRegDef(Reg); 19196252407SPetar Avramovic UseDefs.push_back(skipCopiesIncoming(DefMI)); 19296252407SPetar Avramovic } 193ec575f6eSPetar Avramovic 19496252407SPetar Avramovic MachineInstr * 19596252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 19696252407SPetar Avramovic MachineInstr *MI) const { 19796252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 19896252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 19996252407SPetar Avramovic MachineInstr *Ret = MI; 20096252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 2012bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) && 20296252407SPetar Avramovic MRI.hasOneUse(Ret->getOperand(0).getReg())) { 20396252407SPetar Avramovic Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 20496252407SPetar Avramovic } 20596252407SPetar Avramovic return Ret; 20696252407SPetar Avramovic } 20796252407SPetar Avramovic 20896252407SPetar Avramovic MachineInstr * 20996252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 21096252407SPetar Avramovic MachineInstr *MI) const { 21196252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 21296252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 21396252407SPetar Avramovic MachineInstr *Ret = MI; 21496252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 2152bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(1).getReg())) 21696252407SPetar Avramovic Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 21796252407SPetar Avramovic return Ret; 218ec575f6eSPetar Avramovic } 219ec575f6eSPetar Avramovic 220ec575f6eSPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 221ec575f6eSPetar Avramovic const MachineInstr *MI) { 222ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && 223ec575f6eSPetar Avramovic "Not implemented for non Ambiguous opcode.\n"); 224ec575f6eSPetar Avramovic 225ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 226ec575f6eSPetar Avramovic 227aa699b20SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_LOAD) 228aa699b20SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 229aa699b20SPetar Avramovic 230ec575f6eSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_STORE) 231ec575f6eSPetar Avramovic addUseDef(MI->getOperand(0).getReg(), MRI); 232dbb6d01dSPetar Avramovic 233be20e361SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_PHI) { 234be20e361SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 235be20e361SPetar Avramovic 236be20e361SPetar Avramovic for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 237be20e361SPetar Avramovic addUseDef(MI->getOperand(i).getReg(), MRI); 238be20e361SPetar Avramovic } 239be20e361SPetar Avramovic 240dbb6d01dSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_SELECT) { 241dbb6d01dSPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 242dbb6d01dSPetar Avramovic 243dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(2).getReg(), MRI); 244dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(3).getReg(), MRI); 245dbb6d01dSPetar Avramovic } 24675e43a60SPetar Avramovic 24775e43a60SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 24875e43a60SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 249ec575f6eSPetar Avramovic } 250ec575f6eSPetar Avramovic 251e3bb0a72SPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visit( 252e3bb0a72SPetar Avramovic const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) { 253ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 254e3bb0a72SPetar Avramovic if (wasVisited(MI)) 255e3bb0a72SPetar Avramovic return true; // InstType has already been determined for MI. 256ec575f6eSPetar Avramovic 257ec575f6eSPetar Avramovic startVisit(MI); 258ec575f6eSPetar Avramovic AmbiguousRegDefUseContainer DefUseContainer(MI); 259ec575f6eSPetar Avramovic 260aa699b20SPetar Avramovic // Visit instructions where MI's DEF operands are USED. 261aa699b20SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true)) 262aa699b20SPetar Avramovic return true; 263aa699b20SPetar Avramovic 264ec575f6eSPetar Avramovic // Visit instructions that DEFINE MI's USE operands. 265aa699b20SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false)) 266ec575f6eSPetar Avramovic return true; 267ec575f6eSPetar Avramovic 268e3bb0a72SPetar Avramovic // All MI's adjacent instructions, are ambiguous. 269e3bb0a72SPetar Avramovic if (!WaitingForTypeOfMI) { 270e3bb0a72SPetar Avramovic // This is chain of ambiguous instructions. 271e3bb0a72SPetar Avramovic setTypes(MI, InstType::Ambiguous); 272e3bb0a72SPetar Avramovic return true; 273e3bb0a72SPetar Avramovic } 274e3bb0a72SPetar Avramovic // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 275e3bb0a72SPetar Avramovic // instructions or has no other adjacent instructions. Anyway InstType could 276e3bb0a72SPetar Avramovic // not be determined. There could be unexplored path from some of 277e3bb0a72SPetar Avramovic // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 278e3bb0a72SPetar Avramovic // mapping available. 279e3bb0a72SPetar Avramovic // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 280e3bb0a72SPetar Avramovic // this way when WaitingForTypeOfMI figures out its InstType same InstType 281e3bb0a72SPetar Avramovic // will be assigned to all instructions in this branch. 282e3bb0a72SPetar Avramovic addToWaitingQueue(WaitingForTypeOfMI, MI); 283ec575f6eSPetar Avramovic return false; 284ec575f6eSPetar Avramovic } 285ec575f6eSPetar Avramovic 286ec575f6eSPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 287aa699b20SPetar Avramovic const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 288aa699b20SPetar Avramovic bool isDefUse) { 289ec575f6eSPetar Avramovic while (!AdjacentInstrs.empty()) { 290ec575f6eSPetar Avramovic MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 291ec575f6eSPetar Avramovic 292aa699b20SPetar Avramovic if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 293aa699b20SPetar Avramovic : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 294ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 295ec575f6eSPetar Avramovic return true; 296ec575f6eSPetar Avramovic } 297ec575f6eSPetar Avramovic 298ec575f6eSPetar Avramovic // Determine InstType from register bank of phys register that is 299aa699b20SPetar Avramovic // 'isDefUse ? def : use' of this copy. 300ec575f6eSPetar Avramovic if (AdjMI->getOpcode() == TargetOpcode::COPY) { 301aa699b20SPetar Avramovic setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 302ec575f6eSPetar Avramovic return true; 303ec575f6eSPetar Avramovic } 304ec575f6eSPetar Avramovic 305ec575f6eSPetar Avramovic // Defaults to integer instruction. Includes G_MERGE_VALUES and 306ec575f6eSPetar Avramovic // G_UNMERGE_VALUES. 307e3bb0a72SPetar Avramovic if (!isAmbiguous(AdjMI->getOpcode())) { 308ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 309ec575f6eSPetar Avramovic return true; 310ec575f6eSPetar Avramovic } 311e3bb0a72SPetar Avramovic 312e3bb0a72SPetar Avramovic // When AdjMI was visited first, MI has to continue to explore remaining 313e3bb0a72SPetar Avramovic // adjacent instructions and determine InstType without visiting AdjMI. 314e3bb0a72SPetar Avramovic if (!wasVisited(AdjMI) || 315e3bb0a72SPetar Avramovic getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 316e3bb0a72SPetar Avramovic if (visit(AdjMI, MI)) { 317e3bb0a72SPetar Avramovic // InstType is successfully determined and is same as for AdjMI. 318e3bb0a72SPetar Avramovic setTypes(MI, getRecordedTypeForInstr(AdjMI)); 319e3bb0a72SPetar Avramovic return true; 320e3bb0a72SPetar Avramovic } 321e3bb0a72SPetar Avramovic } 322e3bb0a72SPetar Avramovic } 323ec575f6eSPetar Avramovic return false; 324ec575f6eSPetar Avramovic } 325ec575f6eSPetar Avramovic 326ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 327ec575f6eSPetar Avramovic InstType InstTy) { 328ec575f6eSPetar Avramovic changeRecordedTypeForInstr(MI, InstTy); 329e3bb0a72SPetar Avramovic for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 330e3bb0a72SPetar Avramovic setTypes(WaitingInstr, InstTy); 331e3bb0a72SPetar Avramovic } 332ec575f6eSPetar Avramovic } 333ec575f6eSPetar Avramovic 334ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 335ec575f6eSPetar Avramovic const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 3362bea69bfSDaniel Sanders assert((Register::isPhysicalRegister(CopyInst->getOperand(Op).getReg())) && 337ec575f6eSPetar Avramovic "Copies of non physical registers should not be considered here.\n"); 338ec575f6eSPetar Avramovic 339ec575f6eSPetar Avramovic const MachineFunction &MF = *CopyInst->getMF(); 340ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 341ec575f6eSPetar Avramovic const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 342ec575f6eSPetar Avramovic const RegisterBankInfo &RBI = 343ec575f6eSPetar Avramovic *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 344ec575f6eSPetar Avramovic const RegisterBank *Bank = 345ec575f6eSPetar Avramovic RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 346ec575f6eSPetar Avramovic 347ec575f6eSPetar Avramovic if (Bank == &Mips::FPRBRegBank) 348ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 349ec575f6eSPetar Avramovic else if (Bank == &Mips::GPRBRegBank) 350ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 351ec575f6eSPetar Avramovic else 352ec575f6eSPetar Avramovic llvm_unreachable("Unsupported register bank.\n"); 353ec575f6eSPetar Avramovic } 354ec575f6eSPetar Avramovic 355ec575f6eSPetar Avramovic MipsRegisterBankInfo::InstType 356ec575f6eSPetar Avramovic MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 357e3bb0a72SPetar Avramovic visit(MI, nullptr); 358ec575f6eSPetar Avramovic return getRecordedTypeForInstr(MI); 359ec575f6eSPetar Avramovic } 360ec575f6eSPetar Avramovic 361ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 362ec575f6eSPetar Avramovic llvm::StringRef FunctionName) { 363ec575f6eSPetar Avramovic if (MFName != FunctionName) { 364ec575f6eSPetar Avramovic MFName = FunctionName; 365e3bb0a72SPetar Avramovic WaitingQueues.clear(); 366ec575f6eSPetar Avramovic Types.clear(); 367ec575f6eSPetar Avramovic } 368ec575f6eSPetar Avramovic } 369ec575f6eSPetar Avramovic 370599591f3SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping * 371599591f3SPetar Avramovic getMSAMapping(const MachineFunction &MF) { 372599591f3SPetar Avramovic assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() && 373599591f3SPetar Avramovic "MSA mapping not available on target without MSA."); 374599591f3SPetar Avramovic return &Mips::ValueMappings[Mips::MSAIdx]; 375599591f3SPetar Avramovic } 376599591f3SPetar Avramovic 377f7c213c9SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) { 378f7c213c9SPetar Avramovic return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 379f7c213c9SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 380f7c213c9SPetar Avramovic } 381f7c213c9SPetar Avramovic 382f7c213c9SPetar Avramovic static const unsigned CustomMappingID = 1; 383f7c213c9SPetar Avramovic 384f7c213c9SPetar Avramovic // Only 64 bit mapping is available in fprb and will be marked as custom, i.e. 385f7c213c9SPetar Avramovic // will be split into two 32 bit registers in gprb. 386f7c213c9SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping * 387f7c213c9SPetar Avramovic getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) { 388f7c213c9SPetar Avramovic if (Size == 32) 389f7c213c9SPetar Avramovic return &Mips::ValueMappings[Mips::GPRIdx]; 390f7c213c9SPetar Avramovic 391f7c213c9SPetar Avramovic MappingID = CustomMappingID; 392f7c213c9SPetar Avramovic return &Mips::ValueMappings[Mips::DPRIdx]; 393f7c213c9SPetar Avramovic } 394f7c213c9SPetar Avramovic 395366857a2SPetar Jovanovic const RegisterBankInfo::InstructionMapping & 396366857a2SPetar Jovanovic MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 397366857a2SPetar Jovanovic 398ec575f6eSPetar Avramovic static TypeInfoForMF TI; 399ec575f6eSPetar Avramovic 400ec575f6eSPetar Avramovic // Reset TI internal data when MF changes. 401ec575f6eSPetar Avramovic TI.cleanupIfNewFunction(MI.getMF()->getName()); 402ec575f6eSPetar Avramovic 403366857a2SPetar Jovanovic unsigned Opc = MI.getOpcode(); 4041af05df3SPetar Avramovic const MachineFunction &MF = *MI.getParent()->getParent(); 4051af05df3SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 406366857a2SPetar Jovanovic 407be20e361SPetar Avramovic if (MI.getOpcode() != TargetOpcode::G_PHI) { 408be20e361SPetar Avramovic const RegisterBankInfo::InstructionMapping &Mapping = 409be20e361SPetar Avramovic getInstrMappingImpl(MI); 410366857a2SPetar Jovanovic if (Mapping.isValid()) 411366857a2SPetar Jovanovic return Mapping; 412be20e361SPetar Avramovic } 413366857a2SPetar Jovanovic 414366857a2SPetar Jovanovic using namespace TargetOpcode; 415366857a2SPetar Jovanovic 416366857a2SPetar Jovanovic unsigned NumOperands = MI.getNumOperands(); 417366857a2SPetar Jovanovic const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 418ec575f6eSPetar Avramovic unsigned MappingID = DefaultMappingID; 419f7c213c9SPetar Avramovic 420f7c213c9SPetar Avramovic // Check if LLT sizes match sizes of available register banks. 421f7c213c9SPetar Avramovic for (const MachineOperand &Op : MI.operands()) { 422f7c213c9SPetar Avramovic if (Op.isReg()) { 423f7c213c9SPetar Avramovic LLT RegTy = MRI.getType(Op.getReg()); 424f7c213c9SPetar Avramovic 425f7c213c9SPetar Avramovic if (RegTy.isScalar() && 426f7c213c9SPetar Avramovic (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64)) 427f7c213c9SPetar Avramovic return getInvalidInstructionMapping(); 428599591f3SPetar Avramovic 429599591f3SPetar Avramovic if (RegTy.isVector() && RegTy.getSizeInBits() != 128) 430599591f3SPetar Avramovic return getInvalidInstructionMapping(); 431f7c213c9SPetar Avramovic } 432f7c213c9SPetar Avramovic } 433f7c213c9SPetar Avramovic 434f7c213c9SPetar Avramovic const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg()); 435f7c213c9SPetar Avramovic unsigned Op0Size = Op0Ty.getSizeInBits(); 436f7c213c9SPetar Avramovic InstType InstTy = InstType::Integer; 437366857a2SPetar Jovanovic 438366857a2SPetar Jovanovic switch (Opc) { 4397cecadb9SPetar Avramovic case G_TRUNC: 44056dc218dSPetar Avramovic case G_MUL: 441a48285a1SPetar Avramovic case G_UMULH: 44279df8596SPetar Avramovic case G_ZEXTLOAD: 44379df8596SPetar Avramovic case G_SEXTLOAD: 444021e4c82SPetar Jovanovic case G_GEP: 445b1fc6f61SPetar Avramovic case G_INTTOPTR: 446b1fc6f61SPetar Avramovic case G_PTRTOINT: 4473b953c37SPetar Jovanovic case G_AND: 4483b953c37SPetar Jovanovic case G_OR: 4493b953c37SPetar Jovanovic case G_XOR: 4503b953c37SPetar Jovanovic case G_SHL: 4513b953c37SPetar Jovanovic case G_ASHR: 4523b953c37SPetar Jovanovic case G_LSHR: 4530a5e4eb7SPetar Avramovic case G_SDIV: 4540a5e4eb7SPetar Avramovic case G_UDIV: 4550a5e4eb7SPetar Avramovic case G_SREM: 4560a5e4eb7SPetar Avramovic case G_UREM: 457ff6ac1ebSPetar Avramovic case G_BRINDIRECT: 458c063b0b0SPetar Avramovic case G_VASTART: 459366857a2SPetar Jovanovic OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 460366857a2SPetar Jovanovic break; 461e4af9de3SPetar Avramovic case G_ADD: 462*c46d24f5SPetar Avramovic case G_SUB: 463e4af9de3SPetar Avramovic OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 464e4af9de3SPetar Avramovic if (Op0Size == 128) 465e4af9de3SPetar Avramovic OperandsMapping = getMSAMapping(MF); 466e4af9de3SPetar Avramovic break; 467f7c213c9SPetar Avramovic case G_STORE: 468f7c213c9SPetar Avramovic case G_LOAD: 469599591f3SPetar Avramovic if (Op0Size == 128) { 470599591f3SPetar Avramovic OperandsMapping = getOperandsMapping( 471599591f3SPetar Avramovic {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]}); 472599591f3SPetar Avramovic break; 473599591f3SPetar Avramovic } 474599591f3SPetar Avramovic 475f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 476aa699b20SPetar Avramovic InstTy = TI.determineInstType(&MI); 477aa699b20SPetar Avramovic 478e3bb0a72SPetar Avramovic if (InstTy == InstType::FloatingPoint || 479f7c213c9SPetar Avramovic (Op0Size == 64 && InstTy == InstType::Ambiguous)) 480f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 481f7c213c9SPetar Avramovic {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 482f7c213c9SPetar Avramovic else 483aa699b20SPetar Avramovic OperandsMapping = 484f7c213c9SPetar Avramovic getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID), 485aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 486aa699b20SPetar Avramovic 487aa699b20SPetar Avramovic break; 488f7c213c9SPetar Avramovic case G_PHI: 489f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 490ec575f6eSPetar Avramovic InstTy = TI.determineInstType(&MI); 491be20e361SPetar Avramovic 492be20e361SPetar Avramovic // PHI is copylike and should have one regbank in mapping for def register. 493f7c213c9SPetar Avramovic if (InstTy == InstType::Integer && Op0Size == 64) { 494be20e361SPetar Avramovic OperandsMapping = 495be20e361SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 496be20e361SPetar Avramovic return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 497be20e361SPetar Avramovic /*NumOperands=*/1); 498be20e361SPetar Avramovic } 499be20e361SPetar Avramovic // Use default handling for PHI, i.e. set reg bank of def operand to match 500be20e361SPetar Avramovic // register banks of use operands. 501f7c213c9SPetar Avramovic return getInstrMappingImpl(MI); 502dbb6d01dSPetar Avramovic case G_SELECT: { 503f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 504dbb6d01dSPetar Avramovic InstTy = TI.determineInstType(&MI); 505dbb6d01dSPetar Avramovic 506e3bb0a72SPetar Avramovic if (InstTy == InstType::FloatingPoint || 507f7c213c9SPetar Avramovic (Op0Size == 64 && InstTy == InstType::Ambiguous)) { 508f7c213c9SPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size); 509dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 510dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 511dbb6d01dSPetar Avramovic break; 512f7c213c9SPetar Avramovic } else { 513dbb6d01dSPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = 514f7c213c9SPetar Avramovic getGprbOrCustomMapping(Op0Size, MappingID); 515dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 516dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 517dbb6d01dSPetar Avramovic } 518dbb6d01dSPetar Avramovic break; 519dbb6d01dSPetar Avramovic } 520f7c213c9SPetar Avramovic case G_IMPLICIT_DEF: 521f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 52275e43a60SPetar Avramovic InstTy = TI.determineInstType(&MI); 52375e43a60SPetar Avramovic 524f7c213c9SPetar Avramovic if (InstTy == InstType::FloatingPoint) 525f7c213c9SPetar Avramovic OperandsMapping = getFprbMapping(Op0Size); 526f7c213c9SPetar Avramovic else 527f7c213c9SPetar Avramovic OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID); 528f7c213c9SPetar Avramovic 52975e43a60SPetar Avramovic break; 530f7c213c9SPetar Avramovic case G_UNMERGE_VALUES: 531aa699b20SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 532aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 533aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 534aa699b20SPetar Avramovic MappingID = CustomMappingID; 535aa699b20SPetar Avramovic break; 536f7c213c9SPetar Avramovic case G_MERGE_VALUES: 537ec575f6eSPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 538ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 539ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 540ec575f6eSPetar Avramovic MappingID = CustomMappingID; 541ec575f6eSPetar Avramovic break; 542afa3afa3SPetar Avramovic case G_FADD: 543afa3afa3SPetar Avramovic case G_FSUB: 544afa3afa3SPetar Avramovic case G_FMUL: 5450a1fd355SPetar Avramovic case G_FDIV: 54681132ce0SPetar Avramovic case G_FABS: 547f7c213c9SPetar Avramovic case G_FSQRT: 548f7c213c9SPetar Avramovic OperandsMapping = getFprbMapping(Op0Size); 549afa3afa3SPetar Avramovic break; 550f7c213c9SPetar Avramovic case G_FCONSTANT: 551f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr}); 5521af05df3SPetar Avramovic break; 55322e99c43SPetar Avramovic case G_FCMP: { 554f7c213c9SPetar Avramovic unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 55522e99c43SPetar Avramovic OperandsMapping = 55622e99c43SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 557f7c213c9SPetar Avramovic getFprbMapping(Op2Size), getFprbMapping(Op2Size)}); 55822e99c43SPetar Avramovic break; 55922e99c43SPetar Avramovic } 560a7d00064SPetar Avramovic case G_FPEXT: 561a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 562a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::SPRIdx]}); 563a7d00064SPetar Avramovic break; 564a7d00064SPetar Avramovic case G_FPTRUNC: 565a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 566a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 567a7d00064SPetar Avramovic break; 5684b4dae1cSPetar Avramovic case G_FPTOSI: { 569f7c213c9SPetar Avramovic assert((Op0Size == 32) && "Unsupported integer size"); 5704b4dae1cSPetar Avramovic unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 571f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 572f7c213c9SPetar Avramovic {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)}); 573f7c213c9SPetar Avramovic break; 574f7c213c9SPetar Avramovic } 575f7c213c9SPetar Avramovic case G_SITOFP: 576f7c213c9SPetar Avramovic assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) && 577ddd056c9SFangrui Song "Unsupported integer size"); 578f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 579f7c213c9SPetar Avramovic {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 5804b4dae1cSPetar Avramovic break; 581021e4c82SPetar Jovanovic case G_CONSTANT: 582021e4c82SPetar Jovanovic case G_FRAME_INDEX: 58364c10ba8SPetar Jovanovic case G_GLOBAL_VALUE: 584caef9306SPetar Avramovic case G_JUMP_TABLE: 5855d9b8eedSPetar Avramovic case G_BRCOND: 586021e4c82SPetar Jovanovic OperandsMapping = 587021e4c82SPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 588021e4c82SPetar Jovanovic break; 589caef9306SPetar Avramovic case G_BRJT: 590caef9306SPetar Avramovic OperandsMapping = 591caef9306SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 592caef9306SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 593caef9306SPetar Avramovic break; 594ce4dd0aeSPetar Jovanovic case G_ICMP: 595ce4dd0aeSPetar Jovanovic OperandsMapping = 596ce4dd0aeSPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 597ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx], 598ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx]}); 599ce4dd0aeSPetar Jovanovic break; 600366857a2SPetar Jovanovic default: 601366857a2SPetar Jovanovic return getInvalidInstructionMapping(); 602366857a2SPetar Jovanovic } 603366857a2SPetar Jovanovic 604ec575f6eSPetar Avramovic return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 605366857a2SPetar Jovanovic NumOperands); 606366857a2SPetar Jovanovic } 607ec575f6eSPetar Avramovic 608ec575f6eSPetar Avramovic using InstListTy = GISelWorkList<4>; 609ec575f6eSPetar Avramovic namespace { 610ec575f6eSPetar Avramovic class InstManager : public GISelChangeObserver { 611ec575f6eSPetar Avramovic InstListTy &InstList; 612ec575f6eSPetar Avramovic 613ec575f6eSPetar Avramovic public: 614ec575f6eSPetar Avramovic InstManager(InstListTy &Insts) : InstList(Insts) {} 615ec575f6eSPetar Avramovic 616ec575f6eSPetar Avramovic void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 617ec575f6eSPetar Avramovic void erasingInstr(MachineInstr &MI) override {} 618ec575f6eSPetar Avramovic void changingInstr(MachineInstr &MI) override {} 619ec575f6eSPetar Avramovic void changedInstr(MachineInstr &MI) override {} 620ec575f6eSPetar Avramovic }; 621ec575f6eSPetar Avramovic } // end anonymous namespace 622ec575f6eSPetar Avramovic 623f7c213c9SPetar Avramovic void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, 624f7c213c9SPetar Avramovic MachineRegisterInfo &MRI) const { 625f7c213c9SPetar Avramovic Register Dest = MI.getOperand(0).getReg(); 626f7c213c9SPetar Avramovic switch (MI.getOpcode()) { 627f7c213c9SPetar Avramovic case TargetOpcode::G_STORE: 628f7c213c9SPetar Avramovic // No def operands, skip this instruction. 629f7c213c9SPetar Avramovic break; 630f7c213c9SPetar Avramovic case TargetOpcode::G_CONSTANT: 631f7c213c9SPetar Avramovic case TargetOpcode::G_LOAD: 632f7c213c9SPetar Avramovic case TargetOpcode::G_SELECT: 633f7c213c9SPetar Avramovic case TargetOpcode::G_PHI: 634f7c213c9SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: { 635f7c213c9SPetar Avramovic assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type."); 636f7c213c9SPetar Avramovic MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 637f7c213c9SPetar Avramovic break; 638f7c213c9SPetar Avramovic } 639f7c213c9SPetar Avramovic case TargetOpcode::G_GEP: { 640f7c213c9SPetar Avramovic assert(MRI.getType(Dest).isPointer() && "Unexpected operand type."); 641f7c213c9SPetar Avramovic MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 642f7c213c9SPetar Avramovic break; 643f7c213c9SPetar Avramovic } 644f7c213c9SPetar Avramovic default: 645f7c213c9SPetar Avramovic llvm_unreachable("Unexpected opcode."); 646f7c213c9SPetar Avramovic } 647f7c213c9SPetar Avramovic } 648f7c213c9SPetar Avramovic 649f7c213c9SPetar Avramovic static void 650f7c213c9SPetar Avramovic combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, 651f7c213c9SPetar Avramovic MachineInstr &MI) { 652f7c213c9SPetar Avramovic SmallVector<MachineInstr *, 2> DeadInstrs; 653f7c213c9SPetar Avramovic ArtCombiner.tryCombineMerges(MI, DeadInstrs); 654f7c213c9SPetar Avramovic for (MachineInstr *DeadMI : DeadInstrs) 655f7c213c9SPetar Avramovic DeadMI->eraseFromParent(); 656f7c213c9SPetar Avramovic } 657f7c213c9SPetar Avramovic 658ec575f6eSPetar Avramovic void MipsRegisterBankInfo::applyMappingImpl( 659ec575f6eSPetar Avramovic const OperandsMapper &OpdMapper) const { 660ec575f6eSPetar Avramovic MachineInstr &MI = OpdMapper.getMI(); 661ec575f6eSPetar Avramovic InstListTy NewInstrs; 662ec575f6eSPetar Avramovic MachineIRBuilder B(MI); 663ec575f6eSPetar Avramovic MachineFunction *MF = MI.getMF(); 664ec575f6eSPetar Avramovic MachineRegisterInfo &MRI = OpdMapper.getMRI(); 665f7c213c9SPetar Avramovic const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo(); 666ec575f6eSPetar Avramovic 667ec575f6eSPetar Avramovic InstManager NewInstrObserver(NewInstrs); 668ec575f6eSPetar Avramovic GISelObserverWrapper WrapperObserver(&NewInstrObserver); 669ec575f6eSPetar Avramovic LegalizerHelper Helper(*MF, WrapperObserver, B); 670f7c213c9SPetar Avramovic LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo); 671ec575f6eSPetar Avramovic 672ec575f6eSPetar Avramovic switch (MI.getOpcode()) { 673aa699b20SPetar Avramovic case TargetOpcode::G_LOAD: 674dbb6d01dSPetar Avramovic case TargetOpcode::G_STORE: 675be20e361SPetar Avramovic case TargetOpcode::G_PHI: 67675e43a60SPetar Avramovic case TargetOpcode::G_SELECT: 67775e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: { 678ec575f6eSPetar Avramovic Helper.narrowScalar(MI, 0, LLT::scalar(32)); 679ec575f6eSPetar Avramovic // Handle new instructions. 680ec575f6eSPetar Avramovic while (!NewInstrs.empty()) { 681ec575f6eSPetar Avramovic MachineInstr *NewMI = NewInstrs.pop_back_val(); 682ec575f6eSPetar Avramovic // This is new G_UNMERGE that was created during narrowScalar and will 683ec575f6eSPetar Avramovic // not be considered for regbank selection. RegBankSelect for mips 684ec575f6eSPetar Avramovic // visits/makes corresponding G_MERGE first. Combine them here. 685f7c213c9SPetar Avramovic if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) 686f7c213c9SPetar Avramovic combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI); 687aa699b20SPetar Avramovic // This G_MERGE will be combined away when its corresponding G_UNMERGE 688aa699b20SPetar Avramovic // gets regBankSelected. 689aa699b20SPetar Avramovic else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 690aa699b20SPetar Avramovic continue; 691aa699b20SPetar Avramovic else 692f7c213c9SPetar Avramovic // Manually set register banks for def operands to 32 bit gprb. 693f7c213c9SPetar Avramovic setRegBank(*NewMI, MRI); 694ec575f6eSPetar Avramovic } 695ec575f6eSPetar Avramovic return; 696ec575f6eSPetar Avramovic } 697f7c213c9SPetar Avramovic case TargetOpcode::G_UNMERGE_VALUES: 698f7c213c9SPetar Avramovic combineAwayG_UNMERGE_VALUES(ArtCombiner, MI); 699aa699b20SPetar Avramovic return; 700ec575f6eSPetar Avramovic default: 701ec575f6eSPetar Avramovic break; 702ec575f6eSPetar Avramovic } 703ec575f6eSPetar Avramovic 704ec575f6eSPetar Avramovic return applyDefaultMapping(OpdMapper); 705ec575f6eSPetar Avramovic } 706