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" 15ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 16ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 17ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 18fac93e28SPetar Jovanovic #include "llvm/CodeGen/MachineRegisterInfo.h" 19fac93e28SPetar Jovanovic 20366857a2SPetar Jovanovic #define GET_TARGET_REGBANK_IMPL 21fac93e28SPetar Jovanovic 22366857a2SPetar Jovanovic #include "MipsGenRegisterBank.inc" 23366857a2SPetar Jovanovic 24366857a2SPetar Jovanovic namespace llvm { 25366857a2SPetar Jovanovic namespace Mips { 26366857a2SPetar Jovanovic enum PartialMappingIdx { 27366857a2SPetar Jovanovic PMI_GPR, 281af05df3SPetar Avramovic PMI_SPR, 291af05df3SPetar Avramovic PMI_DPR, 30366857a2SPetar Jovanovic PMI_Min = PMI_GPR, 31366857a2SPetar Jovanovic }; 32366857a2SPetar Jovanovic 33366857a2SPetar Jovanovic RegisterBankInfo::PartialMapping PartMappings[]{ 341af05df3SPetar Avramovic {0, 32, GPRBRegBank}, 351af05df3SPetar Avramovic {0, 32, FPRBRegBank}, 361af05df3SPetar Avramovic {0, 64, FPRBRegBank} 37366857a2SPetar Jovanovic }; 38366857a2SPetar Jovanovic 391af05df3SPetar Avramovic enum ValueMappingIdx { 401af05df3SPetar Avramovic InvalidIdx = 0, 411af05df3SPetar Avramovic GPRIdx = 1, 421af05df3SPetar Avramovic SPRIdx = 4, 431af05df3SPetar Avramovic DPRIdx = 7 441af05df3SPetar Avramovic }; 45366857a2SPetar Jovanovic 46366857a2SPetar Jovanovic RegisterBankInfo::ValueMapping ValueMappings[] = { 47366857a2SPetar Jovanovic // invalid 48366857a2SPetar Jovanovic {nullptr, 0}, 491af05df3SPetar Avramovic // up to 3 operands in GPRs 50366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 51366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 521af05df3SPetar Avramovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 531af05df3SPetar Avramovic // up to 3 ops operands FPRs - single precission 541af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 551af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 561af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 571af05df3SPetar Avramovic // up to 3 ops operands FPRs - double precission 581af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 591af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 601af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1} 611af05df3SPetar Avramovic }; 62366857a2SPetar Jovanovic 63366857a2SPetar Jovanovic } // end namespace Mips 64366857a2SPetar Jovanovic } // end namespace llvm 65366857a2SPetar Jovanovic 66366857a2SPetar Jovanovic using namespace llvm; 67fac93e28SPetar Jovanovic 68fac93e28SPetar Jovanovic MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 69fac93e28SPetar Jovanovic : MipsGenRegisterBankInfo() {} 70366857a2SPetar Jovanovic 71366857a2SPetar Jovanovic const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 72366857a2SPetar Jovanovic const TargetRegisterClass &RC) const { 73366857a2SPetar Jovanovic using namespace Mips; 74366857a2SPetar Jovanovic 75366857a2SPetar Jovanovic switch (RC.getID()) { 76366857a2SPetar Jovanovic case Mips::GPR32RegClassID: 77366857a2SPetar Jovanovic case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 78852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirstRegClassID: 79852dd83bSSimon Atanasyan case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 80366857a2SPetar Jovanovic case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 81852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 82021e4c82SPetar Jovanovic case Mips::SP32RegClassID: 83efcd3c00SPetar Avramovic case Mips::GP32RegClassID: 84366857a2SPetar Jovanovic return getRegBank(Mips::GPRBRegBankID); 853dfa368dSPetar Avramovic case Mips::FGRCCRegClassID: 86afa3afa3SPetar Avramovic case Mips::FGR32RegClassID: 873dfa368dSPetar Avramovic case Mips::FGR64RegClassID: 883dfa368dSPetar Avramovic case Mips::AFGR64RegClassID: 893dfa368dSPetar Avramovic return getRegBank(Mips::FPRBRegBankID); 90366857a2SPetar Jovanovic default: 91366857a2SPetar Jovanovic llvm_unreachable("Register class not supported"); 92366857a2SPetar Jovanovic } 93366857a2SPetar Jovanovic } 94366857a2SPetar Jovanovic 95ec575f6eSPetar Avramovic // Instructions where all register operands are floating point. 96ec575f6eSPetar Avramovic static bool isFloatingPointOpcode(unsigned Opc) { 97ec575f6eSPetar Avramovic switch (Opc) { 98ec575f6eSPetar Avramovic case TargetOpcode::G_FCONSTANT: 99ec575f6eSPetar Avramovic case TargetOpcode::G_FADD: 100ec575f6eSPetar Avramovic case TargetOpcode::G_FSUB: 101ec575f6eSPetar Avramovic case TargetOpcode::G_FMUL: 102ec575f6eSPetar Avramovic case TargetOpcode::G_FDIV: 103ec575f6eSPetar Avramovic case TargetOpcode::G_FABS: 104ec575f6eSPetar Avramovic case TargetOpcode::G_FSQRT: 105ec575f6eSPetar Avramovic case TargetOpcode::G_FCEIL: 106ec575f6eSPetar Avramovic case TargetOpcode::G_FFLOOR: 107ec575f6eSPetar Avramovic case TargetOpcode::G_FPEXT: 108ec575f6eSPetar Avramovic case TargetOpcode::G_FPTRUNC: 109ec575f6eSPetar Avramovic return true; 110ec575f6eSPetar Avramovic default: 111ec575f6eSPetar Avramovic return false; 112ec575f6eSPetar Avramovic } 113ec575f6eSPetar Avramovic } 114ec575f6eSPetar Avramovic 115aa699b20SPetar Avramovic // Instructions where use operands are floating point registers. 116aa699b20SPetar Avramovic // Def operands are general purpose. 117aa699b20SPetar Avramovic static bool isFloatingPointOpcodeUse(unsigned Opc) { 118aa699b20SPetar Avramovic switch (Opc) { 119aa699b20SPetar Avramovic case TargetOpcode::G_FPTOSI: 120aa699b20SPetar Avramovic case TargetOpcode::G_FPTOUI: 121aa699b20SPetar Avramovic case TargetOpcode::G_FCMP: 122aa699b20SPetar Avramovic case Mips::MFC1: 123aa699b20SPetar Avramovic case Mips::ExtractElementF64: 124aa699b20SPetar Avramovic case Mips::ExtractElementF64_64: 125aa699b20SPetar Avramovic return true; 126aa699b20SPetar Avramovic default: 127aa699b20SPetar Avramovic return isFloatingPointOpcode(Opc); 128aa699b20SPetar Avramovic } 129aa699b20SPetar Avramovic } 130aa699b20SPetar Avramovic 131ec575f6eSPetar Avramovic // Instructions where def operands are floating point registers. 132ec575f6eSPetar Avramovic // Use operands are general purpose. 133ec575f6eSPetar Avramovic static bool isFloatingPointOpcodeDef(unsigned Opc) { 134ec575f6eSPetar Avramovic switch (Opc) { 135ec575f6eSPetar Avramovic case TargetOpcode::G_SITOFP: 136ec575f6eSPetar Avramovic case TargetOpcode::G_UITOFP: 137ec575f6eSPetar Avramovic case Mips::MTC1: 138ec575f6eSPetar Avramovic case Mips::BuildPairF64: 139ec575f6eSPetar Avramovic case Mips::BuildPairF64_64: 140ec575f6eSPetar Avramovic return true; 141ec575f6eSPetar Avramovic default: 142ec575f6eSPetar Avramovic return isFloatingPointOpcode(Opc); 143ec575f6eSPetar Avramovic } 144ec575f6eSPetar Avramovic } 145ec575f6eSPetar Avramovic 146ec575f6eSPetar Avramovic static bool isAmbiguous(unsigned Opc) { 147ec575f6eSPetar Avramovic switch (Opc) { 148ec575f6eSPetar Avramovic case TargetOpcode::G_LOAD: 149ec575f6eSPetar Avramovic case TargetOpcode::G_STORE: 150ec575f6eSPetar Avramovic case TargetOpcode::G_PHI: 151ec575f6eSPetar Avramovic case TargetOpcode::G_SELECT: 15275e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: 153ec575f6eSPetar Avramovic return true; 154ec575f6eSPetar Avramovic default: 155ec575f6eSPetar Avramovic return false; 156ec575f6eSPetar Avramovic } 157ec575f6eSPetar Avramovic } 158ec575f6eSPetar Avramovic 159aa699b20SPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 160aa699b20SPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 161aa699b20SPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 162aa699b20SPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 163aa699b20SPetar Avramovic for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 16496252407SPetar Avramovic MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 16596252407SPetar Avramovic // Copy with many uses. 16696252407SPetar Avramovic if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 1672bea69bfSDaniel Sanders !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg())) 16896252407SPetar Avramovic addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 16996252407SPetar Avramovic else 17096252407SPetar Avramovic DefUses.push_back(skipCopiesOutgoing(&UseMI)); 171aa699b20SPetar Avramovic } 172aa699b20SPetar Avramovic } 173aa699b20SPetar Avramovic 174ec575f6eSPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 175ec575f6eSPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 176ec575f6eSPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 177ec575f6eSPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 178ec575f6eSPetar Avramovic MachineInstr *DefMI = MRI.getVRegDef(Reg); 17996252407SPetar Avramovic UseDefs.push_back(skipCopiesIncoming(DefMI)); 18096252407SPetar Avramovic } 181ec575f6eSPetar Avramovic 18296252407SPetar Avramovic MachineInstr * 18396252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 18496252407SPetar Avramovic MachineInstr *MI) const { 18596252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 18696252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 18796252407SPetar Avramovic MachineInstr *Ret = MI; 18896252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 1892bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) && 19096252407SPetar Avramovic MRI.hasOneUse(Ret->getOperand(0).getReg())) { 19196252407SPetar Avramovic Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 19296252407SPetar Avramovic } 19396252407SPetar Avramovic return Ret; 19496252407SPetar Avramovic } 19596252407SPetar Avramovic 19696252407SPetar Avramovic MachineInstr * 19796252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 19896252407SPetar Avramovic MachineInstr *MI) const { 19996252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 20096252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 20196252407SPetar Avramovic MachineInstr *Ret = MI; 20296252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 2032bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(1).getReg())) 20496252407SPetar Avramovic Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 20596252407SPetar Avramovic return Ret; 206ec575f6eSPetar Avramovic } 207ec575f6eSPetar Avramovic 208ec575f6eSPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 209ec575f6eSPetar Avramovic const MachineInstr *MI) { 210ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && 211ec575f6eSPetar Avramovic "Not implemented for non Ambiguous opcode.\n"); 212ec575f6eSPetar Avramovic 213ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 214ec575f6eSPetar Avramovic 215aa699b20SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_LOAD) 216aa699b20SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 217aa699b20SPetar Avramovic 218ec575f6eSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_STORE) 219ec575f6eSPetar Avramovic addUseDef(MI->getOperand(0).getReg(), MRI); 220dbb6d01dSPetar Avramovic 221be20e361SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_PHI) { 222be20e361SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 223be20e361SPetar Avramovic 224be20e361SPetar Avramovic for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 225be20e361SPetar Avramovic addUseDef(MI->getOperand(i).getReg(), MRI); 226be20e361SPetar Avramovic } 227be20e361SPetar Avramovic 228dbb6d01dSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_SELECT) { 229dbb6d01dSPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 230dbb6d01dSPetar Avramovic 231dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(2).getReg(), MRI); 232dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(3).getReg(), MRI); 233dbb6d01dSPetar Avramovic } 23475e43a60SPetar Avramovic 23575e43a60SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 23675e43a60SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 237ec575f6eSPetar Avramovic } 238ec575f6eSPetar Avramovic 239e3bb0a72SPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visit( 240e3bb0a72SPetar Avramovic const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) { 241ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 242e3bb0a72SPetar Avramovic if (wasVisited(MI)) 243e3bb0a72SPetar Avramovic return true; // InstType has already been determined for MI. 244ec575f6eSPetar Avramovic 245ec575f6eSPetar Avramovic startVisit(MI); 246ec575f6eSPetar Avramovic AmbiguousRegDefUseContainer DefUseContainer(MI); 247ec575f6eSPetar Avramovic 248aa699b20SPetar Avramovic // Visit instructions where MI's DEF operands are USED. 249aa699b20SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true)) 250aa699b20SPetar Avramovic return true; 251aa699b20SPetar Avramovic 252ec575f6eSPetar Avramovic // Visit instructions that DEFINE MI's USE operands. 253aa699b20SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false)) 254ec575f6eSPetar Avramovic return true; 255ec575f6eSPetar Avramovic 256e3bb0a72SPetar Avramovic // All MI's adjacent instructions, are ambiguous. 257e3bb0a72SPetar Avramovic if (!WaitingForTypeOfMI) { 258e3bb0a72SPetar Avramovic // This is chain of ambiguous instructions. 259e3bb0a72SPetar Avramovic setTypes(MI, InstType::Ambiguous); 260e3bb0a72SPetar Avramovic return true; 261e3bb0a72SPetar Avramovic } 262e3bb0a72SPetar Avramovic // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 263e3bb0a72SPetar Avramovic // instructions or has no other adjacent instructions. Anyway InstType could 264e3bb0a72SPetar Avramovic // not be determined. There could be unexplored path from some of 265e3bb0a72SPetar Avramovic // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 266e3bb0a72SPetar Avramovic // mapping available. 267e3bb0a72SPetar Avramovic // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 268e3bb0a72SPetar Avramovic // this way when WaitingForTypeOfMI figures out its InstType same InstType 269e3bb0a72SPetar Avramovic // will be assigned to all instructions in this branch. 270e3bb0a72SPetar Avramovic addToWaitingQueue(WaitingForTypeOfMI, MI); 271ec575f6eSPetar Avramovic return false; 272ec575f6eSPetar Avramovic } 273ec575f6eSPetar Avramovic 274ec575f6eSPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 275aa699b20SPetar Avramovic const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 276aa699b20SPetar Avramovic bool isDefUse) { 277ec575f6eSPetar Avramovic while (!AdjacentInstrs.empty()) { 278ec575f6eSPetar Avramovic MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 279ec575f6eSPetar Avramovic 280aa699b20SPetar Avramovic if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 281aa699b20SPetar Avramovic : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 282ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 283ec575f6eSPetar Avramovic return true; 284ec575f6eSPetar Avramovic } 285ec575f6eSPetar Avramovic 286ec575f6eSPetar Avramovic // Determine InstType from register bank of phys register that is 287aa699b20SPetar Avramovic // 'isDefUse ? def : use' of this copy. 288ec575f6eSPetar Avramovic if (AdjMI->getOpcode() == TargetOpcode::COPY) { 289aa699b20SPetar Avramovic setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 290ec575f6eSPetar Avramovic return true; 291ec575f6eSPetar Avramovic } 292ec575f6eSPetar Avramovic 293ec575f6eSPetar Avramovic // Defaults to integer instruction. Includes G_MERGE_VALUES and 294ec575f6eSPetar Avramovic // G_UNMERGE_VALUES. 295e3bb0a72SPetar Avramovic if (!isAmbiguous(AdjMI->getOpcode())) { 296ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 297ec575f6eSPetar Avramovic return true; 298ec575f6eSPetar Avramovic } 299e3bb0a72SPetar Avramovic 300e3bb0a72SPetar Avramovic // When AdjMI was visited first, MI has to continue to explore remaining 301e3bb0a72SPetar Avramovic // adjacent instructions and determine InstType without visiting AdjMI. 302e3bb0a72SPetar Avramovic if (!wasVisited(AdjMI) || 303e3bb0a72SPetar Avramovic getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 304e3bb0a72SPetar Avramovic if (visit(AdjMI, MI)) { 305e3bb0a72SPetar Avramovic // InstType is successfully determined and is same as for AdjMI. 306e3bb0a72SPetar Avramovic setTypes(MI, getRecordedTypeForInstr(AdjMI)); 307e3bb0a72SPetar Avramovic return true; 308e3bb0a72SPetar Avramovic } 309e3bb0a72SPetar Avramovic } 310e3bb0a72SPetar Avramovic } 311ec575f6eSPetar Avramovic return false; 312ec575f6eSPetar Avramovic } 313ec575f6eSPetar Avramovic 314ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 315ec575f6eSPetar Avramovic InstType InstTy) { 316ec575f6eSPetar Avramovic changeRecordedTypeForInstr(MI, InstTy); 317e3bb0a72SPetar Avramovic for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 318e3bb0a72SPetar Avramovic setTypes(WaitingInstr, InstTy); 319e3bb0a72SPetar Avramovic } 320ec575f6eSPetar Avramovic } 321ec575f6eSPetar Avramovic 322ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 323ec575f6eSPetar Avramovic const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 3242bea69bfSDaniel Sanders assert((Register::isPhysicalRegister(CopyInst->getOperand(Op).getReg())) && 325ec575f6eSPetar Avramovic "Copies of non physical registers should not be considered here.\n"); 326ec575f6eSPetar Avramovic 327ec575f6eSPetar Avramovic const MachineFunction &MF = *CopyInst->getMF(); 328ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 329ec575f6eSPetar Avramovic const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 330ec575f6eSPetar Avramovic const RegisterBankInfo &RBI = 331ec575f6eSPetar Avramovic *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 332ec575f6eSPetar Avramovic const RegisterBank *Bank = 333ec575f6eSPetar Avramovic RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 334ec575f6eSPetar Avramovic 335ec575f6eSPetar Avramovic if (Bank == &Mips::FPRBRegBank) 336ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 337ec575f6eSPetar Avramovic else if (Bank == &Mips::GPRBRegBank) 338ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 339ec575f6eSPetar Avramovic else 340ec575f6eSPetar Avramovic llvm_unreachable("Unsupported register bank.\n"); 341ec575f6eSPetar Avramovic } 342ec575f6eSPetar Avramovic 343ec575f6eSPetar Avramovic MipsRegisterBankInfo::InstType 344ec575f6eSPetar Avramovic MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 345e3bb0a72SPetar Avramovic visit(MI, nullptr); 346ec575f6eSPetar Avramovic return getRecordedTypeForInstr(MI); 347ec575f6eSPetar Avramovic } 348ec575f6eSPetar Avramovic 349ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 350ec575f6eSPetar Avramovic llvm::StringRef FunctionName) { 351ec575f6eSPetar Avramovic if (MFName != FunctionName) { 352ec575f6eSPetar Avramovic MFName = FunctionName; 353e3bb0a72SPetar Avramovic WaitingQueues.clear(); 354ec575f6eSPetar Avramovic Types.clear(); 355ec575f6eSPetar Avramovic } 356ec575f6eSPetar Avramovic } 357ec575f6eSPetar Avramovic 358366857a2SPetar Jovanovic const RegisterBankInfo::InstructionMapping & 359366857a2SPetar Jovanovic MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 360366857a2SPetar Jovanovic 361ec575f6eSPetar Avramovic static TypeInfoForMF TI; 362ec575f6eSPetar Avramovic 363ec575f6eSPetar Avramovic // Reset TI internal data when MF changes. 364ec575f6eSPetar Avramovic TI.cleanupIfNewFunction(MI.getMF()->getName()); 365ec575f6eSPetar Avramovic 366366857a2SPetar Jovanovic unsigned Opc = MI.getOpcode(); 3671af05df3SPetar Avramovic const MachineFunction &MF = *MI.getParent()->getParent(); 3681af05df3SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 369366857a2SPetar Jovanovic 370be20e361SPetar Avramovic if (MI.getOpcode() != TargetOpcode::G_PHI) { 371be20e361SPetar Avramovic const RegisterBankInfo::InstructionMapping &Mapping = 372be20e361SPetar Avramovic getInstrMappingImpl(MI); 373366857a2SPetar Jovanovic if (Mapping.isValid()) 374366857a2SPetar Jovanovic return Mapping; 375be20e361SPetar Avramovic } 376366857a2SPetar Jovanovic 377366857a2SPetar Jovanovic using namespace TargetOpcode; 378366857a2SPetar Jovanovic 379366857a2SPetar Jovanovic unsigned NumOperands = MI.getNumOperands(); 380366857a2SPetar Jovanovic const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 381ec575f6eSPetar Avramovic unsigned MappingID = DefaultMappingID; 382ec575f6eSPetar Avramovic const unsigned CustomMappingID = 1; 383366857a2SPetar Jovanovic 384366857a2SPetar Jovanovic switch (Opc) { 3857cecadb9SPetar Avramovic case G_TRUNC: 386366857a2SPetar Jovanovic case G_ADD: 3877cecadb9SPetar Avramovic case G_SUB: 38856dc218dSPetar Avramovic case G_MUL: 389a48285a1SPetar Avramovic case G_UMULH: 39079df8596SPetar Avramovic case G_ZEXTLOAD: 39179df8596SPetar Avramovic case G_SEXTLOAD: 392021e4c82SPetar Jovanovic case G_GEP: 393b1fc6f61SPetar Avramovic case G_INTTOPTR: 394b1fc6f61SPetar Avramovic case G_PTRTOINT: 3953b953c37SPetar Jovanovic case G_AND: 3963b953c37SPetar Jovanovic case G_OR: 3973b953c37SPetar Jovanovic case G_XOR: 3983b953c37SPetar Jovanovic case G_SHL: 3993b953c37SPetar Jovanovic case G_ASHR: 4003b953c37SPetar Jovanovic case G_LSHR: 4010a5e4eb7SPetar Avramovic case G_SDIV: 4020a5e4eb7SPetar Avramovic case G_UDIV: 4030a5e4eb7SPetar Avramovic case G_SREM: 4040a5e4eb7SPetar Avramovic case G_UREM: 405*ff6ac1ebSPetar Avramovic case G_BRINDIRECT: 406366857a2SPetar Jovanovic OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 407366857a2SPetar Jovanovic break; 408aa699b20SPetar Avramovic case G_LOAD: { 409aa699b20SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 410aa699b20SPetar Avramovic InstType InstTy = InstType::Integer; 411aa699b20SPetar Avramovic if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 412aa699b20SPetar Avramovic InstTy = TI.determineInstType(&MI); 413aa699b20SPetar Avramovic } 414aa699b20SPetar Avramovic 415e3bb0a72SPetar Avramovic if (InstTy == InstType::FloatingPoint || 416e3bb0a72SPetar Avramovic (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb 417aa699b20SPetar Avramovic OperandsMapping = 418aa699b20SPetar Avramovic getOperandsMapping({Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 419aa699b20SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 420aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 421aa699b20SPetar Avramovic break; 422aa699b20SPetar Avramovic } else { // gprb 423aa699b20SPetar Avramovic OperandsMapping = 424aa699b20SPetar Avramovic getOperandsMapping({Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 425aa699b20SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 426aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 427aa699b20SPetar Avramovic if (Size == 64) 428aa699b20SPetar Avramovic MappingID = CustomMappingID; 429aa699b20SPetar Avramovic } 430aa699b20SPetar Avramovic 431aa699b20SPetar Avramovic break; 432aa699b20SPetar Avramovic } 433ec575f6eSPetar Avramovic case G_STORE: { 434ec575f6eSPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 435ec575f6eSPetar Avramovic InstType InstTy = InstType::Integer; 436ec575f6eSPetar Avramovic if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 437ec575f6eSPetar Avramovic InstTy = TI.determineInstType(&MI); 438ec575f6eSPetar Avramovic } 439ec575f6eSPetar Avramovic 440e3bb0a72SPetar Avramovic if (InstTy == InstType::FloatingPoint || 441e3bb0a72SPetar Avramovic (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb 442ec575f6eSPetar Avramovic OperandsMapping = 443ec575f6eSPetar Avramovic getOperandsMapping({Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 444ec575f6eSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 445ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 446ec575f6eSPetar Avramovic break; 447ec575f6eSPetar Avramovic } else { // gprb 448ec575f6eSPetar Avramovic OperandsMapping = 449ec575f6eSPetar Avramovic getOperandsMapping({Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 450ec575f6eSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 451ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 452ec575f6eSPetar Avramovic if (Size == 64) 453ec575f6eSPetar Avramovic MappingID = CustomMappingID; 454ec575f6eSPetar Avramovic } 455ec575f6eSPetar Avramovic break; 456ec575f6eSPetar Avramovic } 457be20e361SPetar Avramovic case G_PHI: { 458be20e361SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 459be20e361SPetar Avramovic InstType InstTy = InstType::Integer; 460be20e361SPetar Avramovic if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 461be20e361SPetar Avramovic InstTy = TI.determineInstType(&MI); 462be20e361SPetar Avramovic } 463be20e361SPetar Avramovic 464be20e361SPetar Avramovic // PHI is copylike and should have one regbank in mapping for def register. 465be20e361SPetar Avramovic if (InstTy == InstType::Integer && Size == 64) { // fprb 466be20e361SPetar Avramovic OperandsMapping = 467be20e361SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 468be20e361SPetar Avramovic return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 469be20e361SPetar Avramovic /*NumOperands=*/1); 470be20e361SPetar Avramovic } 471be20e361SPetar Avramovic // Use default handling for PHI, i.e. set reg bank of def operand to match 472be20e361SPetar Avramovic // register banks of use operands. 473be20e361SPetar Avramovic const RegisterBankInfo::InstructionMapping &Mapping = 474be20e361SPetar Avramovic getInstrMappingImpl(MI); 475be20e361SPetar Avramovic return Mapping; 476be20e361SPetar Avramovic } 477dbb6d01dSPetar Avramovic case G_SELECT: { 478dbb6d01dSPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 479dbb6d01dSPetar Avramovic InstType InstTy = InstType::Integer; 480dbb6d01dSPetar Avramovic if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 481dbb6d01dSPetar Avramovic InstTy = TI.determineInstType(&MI); 482dbb6d01dSPetar Avramovic } 483dbb6d01dSPetar Avramovic 484e3bb0a72SPetar Avramovic if (InstTy == InstType::FloatingPoint || 485e3bb0a72SPetar Avramovic (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb 486dbb6d01dSPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = 487dbb6d01dSPetar Avramovic Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 488dbb6d01dSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 489dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 490dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 491dbb6d01dSPetar Avramovic break; 492dbb6d01dSPetar Avramovic } else { // gprb 493dbb6d01dSPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = 494dbb6d01dSPetar Avramovic Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx] 495dbb6d01dSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 496dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 497dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 498dbb6d01dSPetar Avramovic if (Size == 64) 499dbb6d01dSPetar Avramovic MappingID = CustomMappingID; 500dbb6d01dSPetar Avramovic } 501dbb6d01dSPetar Avramovic break; 502dbb6d01dSPetar Avramovic } 50375e43a60SPetar Avramovic case G_IMPLICIT_DEF: { 50475e43a60SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 50575e43a60SPetar Avramovic InstType InstTy = InstType::Integer; 50675e43a60SPetar Avramovic if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) { 50775e43a60SPetar Avramovic InstTy = TI.determineInstType(&MI); 50875e43a60SPetar Avramovic } 50975e43a60SPetar Avramovic 51075e43a60SPetar Avramovic if (InstTy == InstType::FloatingPoint) { // fprb 51175e43a60SPetar Avramovic OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 51275e43a60SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 51375e43a60SPetar Avramovic } else { // gprb 51475e43a60SPetar Avramovic OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::GPRIdx] 51575e43a60SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 51675e43a60SPetar Avramovic if (Size == 64) 51775e43a60SPetar Avramovic MappingID = CustomMappingID; 51875e43a60SPetar Avramovic } 51975e43a60SPetar Avramovic break; 52075e43a60SPetar Avramovic } 521aa699b20SPetar Avramovic case G_UNMERGE_VALUES: { 522aa699b20SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 523aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 524aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 525aa699b20SPetar Avramovic MappingID = CustomMappingID; 526aa699b20SPetar Avramovic break; 527aa699b20SPetar Avramovic } 528ec575f6eSPetar Avramovic case G_MERGE_VALUES: { 529ec575f6eSPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 530ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 531ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 532ec575f6eSPetar Avramovic MappingID = CustomMappingID; 533ec575f6eSPetar Avramovic break; 534ec575f6eSPetar Avramovic } 535afa3afa3SPetar Avramovic case G_FADD: 536afa3afa3SPetar Avramovic case G_FSUB: 537afa3afa3SPetar Avramovic case G_FMUL: 5380a1fd355SPetar Avramovic case G_FDIV: 53981132ce0SPetar Avramovic case G_FABS: 54081132ce0SPetar Avramovic case G_FSQRT:{ 541afa3afa3SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 542afa3afa3SPetar Avramovic assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 543afa3afa3SPetar Avramovic OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 544afa3afa3SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 545afa3afa3SPetar Avramovic break; 546afa3afa3SPetar Avramovic } 5471af05df3SPetar Avramovic case G_FCONSTANT: { 548afa3afa3SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 549afa3afa3SPetar Avramovic assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 5501af05df3SPetar Avramovic const RegisterBankInfo::ValueMapping *FPRValueMapping = 5511af05df3SPetar Avramovic Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 5521af05df3SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 5531af05df3SPetar Avramovic OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 5541af05df3SPetar Avramovic break; 5551af05df3SPetar Avramovic } 55622e99c43SPetar Avramovic case G_FCMP: { 55722e99c43SPetar Avramovic unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 55822e99c43SPetar Avramovic assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 55922e99c43SPetar Avramovic const RegisterBankInfo::ValueMapping *FPRValueMapping = 56022e99c43SPetar Avramovic Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 56122e99c43SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 56222e99c43SPetar Avramovic OperandsMapping = 56322e99c43SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 56422e99c43SPetar Avramovic FPRValueMapping, FPRValueMapping}); 56522e99c43SPetar Avramovic break; 56622e99c43SPetar Avramovic } 567a7d00064SPetar Avramovic case G_FPEXT: 568a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 569a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::SPRIdx]}); 570a7d00064SPetar Avramovic break; 571a7d00064SPetar Avramovic case G_FPTRUNC: 572a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 573a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 574a7d00064SPetar Avramovic break; 5754b4dae1cSPetar Avramovic case G_FPTOSI: { 5764b4dae1cSPetar Avramovic unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 577ddd056c9SFangrui Song assert((MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 32) && 578ddd056c9SFangrui Song "Unsupported integer size"); 5794b4dae1cSPetar Avramovic assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 5804b4dae1cSPetar Avramovic OperandsMapping = getOperandsMapping({ 5814b4dae1cSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 5824b4dae1cSPetar Avramovic SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 5834b4dae1cSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 5844b4dae1cSPetar Avramovic }); 5854b4dae1cSPetar Avramovic break; 5864b4dae1cSPetar Avramovic } 587153bd24eSPetar Avramovic case G_SITOFP: { 588153bd24eSPetar Avramovic unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 589153bd24eSPetar Avramovic unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 590ddd056c9SFangrui Song (void)SizeInt; 591153bd24eSPetar Avramovic assert((SizeInt == 32) && "Unsupported integer size"); 592153bd24eSPetar Avramovic assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 593153bd24eSPetar Avramovic OperandsMapping = 594153bd24eSPetar Avramovic getOperandsMapping({SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 595153bd24eSPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx], 596153bd24eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 597153bd24eSPetar Avramovic break; 598153bd24eSPetar Avramovic } 599021e4c82SPetar Jovanovic case G_CONSTANT: 600021e4c82SPetar Jovanovic case G_FRAME_INDEX: 60164c10ba8SPetar Jovanovic case G_GLOBAL_VALUE: 602caef9306SPetar Avramovic case G_JUMP_TABLE: 6035d9b8eedSPetar Avramovic case G_BRCOND: 604021e4c82SPetar Jovanovic OperandsMapping = 605021e4c82SPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 606021e4c82SPetar Jovanovic break; 607caef9306SPetar Avramovic case G_BRJT: 608caef9306SPetar Avramovic OperandsMapping = 609caef9306SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 610caef9306SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 611caef9306SPetar Avramovic break; 612ce4dd0aeSPetar Jovanovic case G_ICMP: 613ce4dd0aeSPetar Jovanovic OperandsMapping = 614ce4dd0aeSPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 615ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx], 616ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx]}); 617ce4dd0aeSPetar Jovanovic break; 618366857a2SPetar Jovanovic default: 619366857a2SPetar Jovanovic return getInvalidInstructionMapping(); 620366857a2SPetar Jovanovic } 621366857a2SPetar Jovanovic 622ec575f6eSPetar Avramovic return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 623366857a2SPetar Jovanovic NumOperands); 624366857a2SPetar Jovanovic } 625ec575f6eSPetar Avramovic 626ec575f6eSPetar Avramovic using InstListTy = GISelWorkList<4>; 627ec575f6eSPetar Avramovic namespace { 628ec575f6eSPetar Avramovic class InstManager : public GISelChangeObserver { 629ec575f6eSPetar Avramovic InstListTy &InstList; 630ec575f6eSPetar Avramovic 631ec575f6eSPetar Avramovic public: 632ec575f6eSPetar Avramovic InstManager(InstListTy &Insts) : InstList(Insts) {} 633ec575f6eSPetar Avramovic 634ec575f6eSPetar Avramovic void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 635ec575f6eSPetar Avramovic void erasingInstr(MachineInstr &MI) override {} 636ec575f6eSPetar Avramovic void changingInstr(MachineInstr &MI) override {} 637ec575f6eSPetar Avramovic void changedInstr(MachineInstr &MI) override {} 638ec575f6eSPetar Avramovic }; 639ec575f6eSPetar Avramovic } // end anonymous namespace 640ec575f6eSPetar Avramovic 641ec575f6eSPetar Avramovic /// Here we have to narrowScalar s64 operands to s32, combine away 642ec575f6eSPetar Avramovic /// G_MERGE/G_UNMERGE and erase instructions that became dead in the process. 643ec575f6eSPetar Avramovic /// We manually assign 32 bit gprb to register operands of all new instructions 644ec575f6eSPetar Avramovic /// that got created in the process since they will not end up in RegBankSelect 645ec575f6eSPetar Avramovic /// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++. 646ec575f6eSPetar Avramovic void MipsRegisterBankInfo::applyMappingImpl( 647ec575f6eSPetar Avramovic const OperandsMapper &OpdMapper) const { 648ec575f6eSPetar Avramovic MachineInstr &MI = OpdMapper.getMI(); 649ec575f6eSPetar Avramovic InstListTy NewInstrs; 650ec575f6eSPetar Avramovic MachineIRBuilder B(MI); 651ec575f6eSPetar Avramovic MachineFunction *MF = MI.getMF(); 652ec575f6eSPetar Avramovic MachineRegisterInfo &MRI = OpdMapper.getMRI(); 653ec575f6eSPetar Avramovic 654ec575f6eSPetar Avramovic InstManager NewInstrObserver(NewInstrs); 655ec575f6eSPetar Avramovic GISelObserverWrapper WrapperObserver(&NewInstrObserver); 656ec575f6eSPetar Avramovic LegalizerHelper Helper(*MF, WrapperObserver, B); 657ec575f6eSPetar Avramovic LegalizationArtifactCombiner ArtCombiner( 658ec575f6eSPetar Avramovic B, MF->getRegInfo(), *MF->getSubtarget().getLegalizerInfo()); 659ec575f6eSPetar Avramovic 660ec575f6eSPetar Avramovic switch (MI.getOpcode()) { 661aa699b20SPetar Avramovic case TargetOpcode::G_LOAD: 662dbb6d01dSPetar Avramovic case TargetOpcode::G_STORE: 663be20e361SPetar Avramovic case TargetOpcode::G_PHI: 66475e43a60SPetar Avramovic case TargetOpcode::G_SELECT: 66575e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: { 666ec575f6eSPetar Avramovic Helper.narrowScalar(MI, 0, LLT::scalar(32)); 667ec575f6eSPetar Avramovic // Handle new instructions. 668ec575f6eSPetar Avramovic while (!NewInstrs.empty()) { 669ec575f6eSPetar Avramovic MachineInstr *NewMI = NewInstrs.pop_back_val(); 670ec575f6eSPetar Avramovic // This is new G_UNMERGE that was created during narrowScalar and will 671ec575f6eSPetar Avramovic // not be considered for regbank selection. RegBankSelect for mips 672ec575f6eSPetar Avramovic // visits/makes corresponding G_MERGE first. Combine them here. 673ec575f6eSPetar Avramovic if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) { 674ec575f6eSPetar Avramovic SmallVector<MachineInstr *, 2> DeadInstrs; 675ec575f6eSPetar Avramovic ArtCombiner.tryCombineMerges(*NewMI, DeadInstrs); 676ec575f6eSPetar Avramovic for (MachineInstr *DeadMI : DeadInstrs) 677ec575f6eSPetar Avramovic DeadMI->eraseFromParent(); 678aa699b20SPetar Avramovic } 679aa699b20SPetar Avramovic // This G_MERGE will be combined away when its corresponding G_UNMERGE 680aa699b20SPetar Avramovic // gets regBankSelected. 681aa699b20SPetar Avramovic else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 682aa699b20SPetar Avramovic continue; 683aa699b20SPetar Avramovic else 684ec575f6eSPetar Avramovic // Manually set register banks for all register operands to 32 bit gprb. 685ec575f6eSPetar Avramovic for (auto Op : NewMI->operands()) { 686ec575f6eSPetar Avramovic if (Op.isReg()) { 687ec575f6eSPetar Avramovic assert(MRI.getType(Op.getReg()).getSizeInBits() == 32 && 688ec575f6eSPetar Avramovic "Only 32 bit gprb is handled here.\n"); 689ec575f6eSPetar Avramovic MRI.setRegBank(Op.getReg(), getRegBank(Mips::GPRBRegBankID)); 690ec575f6eSPetar Avramovic } 691ec575f6eSPetar Avramovic } 692ec575f6eSPetar Avramovic } 693ec575f6eSPetar Avramovic return; 694ec575f6eSPetar Avramovic } 695aa699b20SPetar Avramovic case TargetOpcode::G_UNMERGE_VALUES: { 696aa699b20SPetar Avramovic SmallVector<MachineInstr *, 2> DeadInstrs; 697aa699b20SPetar Avramovic ArtCombiner.tryCombineMerges(MI, DeadInstrs); 698aa699b20SPetar Avramovic for (MachineInstr *DeadMI : DeadInstrs) 699aa699b20SPetar Avramovic DeadMI->eraseFromParent(); 700aa699b20SPetar Avramovic return; 701aa699b20SPetar Avramovic } 702ec575f6eSPetar Avramovic default: 703ec575f6eSPetar Avramovic break; 704ec575f6eSPetar Avramovic } 705ec575f6eSPetar Avramovic 706ec575f6eSPetar Avramovic return applyDefaultMapping(OpdMapper); 707ec575f6eSPetar Avramovic } 708