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