10b57cec5SDimitry Andric //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// \file 90b57cec5SDimitry Andric /// This file implements the targeting of the RegisterBankInfo class for Mips. 100b57cec5SDimitry Andric /// \todo This should be generated by TableGen. 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MipsRegisterBankInfo.h" 140b57cec5SDimitry Andric #include "MipsInstrInfo.h" 15*8bcb0991SDimitry Andric #include "MipsTargetMachine.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #define GET_TARGET_REGBANK_IMPL 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #include "MipsGenRegisterBank.inc" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace llvm { 260b57cec5SDimitry Andric namespace Mips { 270b57cec5SDimitry Andric enum PartialMappingIdx { 280b57cec5SDimitry Andric PMI_GPR, 290b57cec5SDimitry Andric PMI_SPR, 300b57cec5SDimitry Andric PMI_DPR, 31*8bcb0991SDimitry Andric PMI_MSA, 320b57cec5SDimitry Andric PMI_Min = PMI_GPR, 330b57cec5SDimitry Andric }; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric RegisterBankInfo::PartialMapping PartMappings[]{ 360b57cec5SDimitry Andric {0, 32, GPRBRegBank}, 370b57cec5SDimitry Andric {0, 32, FPRBRegBank}, 38*8bcb0991SDimitry Andric {0, 64, FPRBRegBank}, 39*8bcb0991SDimitry Andric {0, 128, FPRBRegBank} 400b57cec5SDimitry Andric }; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric enum ValueMappingIdx { 430b57cec5SDimitry Andric InvalidIdx = 0, 440b57cec5SDimitry Andric GPRIdx = 1, 450b57cec5SDimitry Andric SPRIdx = 4, 46*8bcb0991SDimitry Andric DPRIdx = 7, 47*8bcb0991SDimitry Andric MSAIdx = 10 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric RegisterBankInfo::ValueMapping ValueMappings[] = { 510b57cec5SDimitry Andric // invalid 520b57cec5SDimitry Andric {nullptr, 0}, 530b57cec5SDimitry Andric // up to 3 operands in GPRs 540b57cec5SDimitry Andric {&PartMappings[PMI_GPR - PMI_Min], 1}, 550b57cec5SDimitry Andric {&PartMappings[PMI_GPR - PMI_Min], 1}, 560b57cec5SDimitry Andric {&PartMappings[PMI_GPR - PMI_Min], 1}, 57*8bcb0991SDimitry Andric // up to 3 operands in FPRs - single precission 580b57cec5SDimitry Andric {&PartMappings[PMI_SPR - PMI_Min], 1}, 590b57cec5SDimitry Andric {&PartMappings[PMI_SPR - PMI_Min], 1}, 600b57cec5SDimitry Andric {&PartMappings[PMI_SPR - PMI_Min], 1}, 61*8bcb0991SDimitry Andric // up to 3 operands in FPRs - double precission 620b57cec5SDimitry Andric {&PartMappings[PMI_DPR - PMI_Min], 1}, 630b57cec5SDimitry Andric {&PartMappings[PMI_DPR - PMI_Min], 1}, 64*8bcb0991SDimitry Andric {&PartMappings[PMI_DPR - PMI_Min], 1}, 65*8bcb0991SDimitry Andric // up to 3 operands in FPRs - MSA 66*8bcb0991SDimitry Andric {&PartMappings[PMI_MSA - PMI_Min], 1}, 67*8bcb0991SDimitry Andric {&PartMappings[PMI_MSA - PMI_Min], 1}, 68*8bcb0991SDimitry Andric {&PartMappings[PMI_MSA - PMI_Min], 1} 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric } // end namespace Mips 720b57cec5SDimitry Andric } // end namespace llvm 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric using namespace llvm; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 770b57cec5SDimitry Andric : MipsGenRegisterBankInfo() {} 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 800b57cec5SDimitry Andric const TargetRegisterClass &RC) const { 810b57cec5SDimitry Andric using namespace Mips; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric switch (RC.getID()) { 840b57cec5SDimitry Andric case Mips::GPR32RegClassID: 850b57cec5SDimitry Andric case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 860b57cec5SDimitry Andric case Mips::GPRMM16MovePPairFirstRegClassID: 870b57cec5SDimitry Andric case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 880b57cec5SDimitry Andric case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 890b57cec5SDimitry Andric case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 900b57cec5SDimitry Andric case Mips::SP32RegClassID: 910b57cec5SDimitry Andric case Mips::GP32RegClassID: 920b57cec5SDimitry Andric return getRegBank(Mips::GPRBRegBankID); 930b57cec5SDimitry Andric case Mips::FGRCCRegClassID: 940b57cec5SDimitry Andric case Mips::FGR32RegClassID: 950b57cec5SDimitry Andric case Mips::FGR64RegClassID: 960b57cec5SDimitry Andric case Mips::AFGR64RegClassID: 97*8bcb0991SDimitry Andric case Mips::MSA128BRegClassID: 98*8bcb0991SDimitry Andric case Mips::MSA128HRegClassID: 99*8bcb0991SDimitry Andric case Mips::MSA128WRegClassID: 100*8bcb0991SDimitry Andric case Mips::MSA128DRegClassID: 1010b57cec5SDimitry Andric return getRegBank(Mips::FPRBRegBankID); 1020b57cec5SDimitry Andric default: 1030b57cec5SDimitry Andric llvm_unreachable("Register class not supported"); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // Instructions where all register operands are floating point. 1080b57cec5SDimitry Andric static bool isFloatingPointOpcode(unsigned Opc) { 1090b57cec5SDimitry Andric switch (Opc) { 1100b57cec5SDimitry Andric case TargetOpcode::G_FCONSTANT: 1110b57cec5SDimitry Andric case TargetOpcode::G_FADD: 1120b57cec5SDimitry Andric case TargetOpcode::G_FSUB: 1130b57cec5SDimitry Andric case TargetOpcode::G_FMUL: 1140b57cec5SDimitry Andric case TargetOpcode::G_FDIV: 1150b57cec5SDimitry Andric case TargetOpcode::G_FABS: 1160b57cec5SDimitry Andric case TargetOpcode::G_FSQRT: 1170b57cec5SDimitry Andric case TargetOpcode::G_FCEIL: 1180b57cec5SDimitry Andric case TargetOpcode::G_FFLOOR: 1190b57cec5SDimitry Andric case TargetOpcode::G_FPEXT: 1200b57cec5SDimitry Andric case TargetOpcode::G_FPTRUNC: 1210b57cec5SDimitry Andric return true; 1220b57cec5SDimitry Andric default: 1230b57cec5SDimitry Andric return false; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // Instructions where use operands are floating point registers. 1280b57cec5SDimitry Andric // Def operands are general purpose. 1290b57cec5SDimitry Andric static bool isFloatingPointOpcodeUse(unsigned Opc) { 1300b57cec5SDimitry Andric switch (Opc) { 1310b57cec5SDimitry Andric case TargetOpcode::G_FPTOSI: 1320b57cec5SDimitry Andric case TargetOpcode::G_FPTOUI: 1330b57cec5SDimitry Andric case TargetOpcode::G_FCMP: 1340b57cec5SDimitry Andric case Mips::MFC1: 1350b57cec5SDimitry Andric case Mips::ExtractElementF64: 1360b57cec5SDimitry Andric case Mips::ExtractElementF64_64: 1370b57cec5SDimitry Andric return true; 1380b57cec5SDimitry Andric default: 1390b57cec5SDimitry Andric return isFloatingPointOpcode(Opc); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric // Instructions where def operands are floating point registers. 1440b57cec5SDimitry Andric // Use operands are general purpose. 1450b57cec5SDimitry Andric static bool isFloatingPointOpcodeDef(unsigned Opc) { 1460b57cec5SDimitry Andric switch (Opc) { 1470b57cec5SDimitry Andric case TargetOpcode::G_SITOFP: 1480b57cec5SDimitry Andric case TargetOpcode::G_UITOFP: 1490b57cec5SDimitry Andric case Mips::MTC1: 1500b57cec5SDimitry Andric case Mips::BuildPairF64: 1510b57cec5SDimitry Andric case Mips::BuildPairF64_64: 1520b57cec5SDimitry Andric return true; 1530b57cec5SDimitry Andric default: 1540b57cec5SDimitry Andric return isFloatingPointOpcode(Opc); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric static bool isAmbiguous(unsigned Opc) { 1590b57cec5SDimitry Andric switch (Opc) { 1600b57cec5SDimitry Andric case TargetOpcode::G_LOAD: 1610b57cec5SDimitry Andric case TargetOpcode::G_STORE: 1620b57cec5SDimitry Andric case TargetOpcode::G_PHI: 1630b57cec5SDimitry Andric case TargetOpcode::G_SELECT: 164*8bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: 1650b57cec5SDimitry Andric return true; 1660b57cec5SDimitry Andric default: 1670b57cec5SDimitry Andric return false; 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 1720b57cec5SDimitry Andric Register Reg, const MachineRegisterInfo &MRI) { 1730b57cec5SDimitry Andric assert(!MRI.getType(Reg).isPointer() && 1740b57cec5SDimitry Andric "Pointers are gprb, they should not be considered as ambiguous.\n"); 1750b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 1760b57cec5SDimitry Andric MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 1770b57cec5SDimitry Andric // Copy with many uses. 1780b57cec5SDimitry Andric if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 179*8bcb0991SDimitry Andric !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg())) 1800b57cec5SDimitry Andric addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 1810b57cec5SDimitry Andric else 1820b57cec5SDimitry Andric DefUses.push_back(skipCopiesOutgoing(&UseMI)); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 1870b57cec5SDimitry Andric Register Reg, const MachineRegisterInfo &MRI) { 1880b57cec5SDimitry Andric assert(!MRI.getType(Reg).isPointer() && 1890b57cec5SDimitry Andric "Pointers are gprb, they should not be considered as ambiguous.\n"); 1900b57cec5SDimitry Andric MachineInstr *DefMI = MRI.getVRegDef(Reg); 1910b57cec5SDimitry Andric UseDefs.push_back(skipCopiesIncoming(DefMI)); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric MachineInstr * 1950b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 1960b57cec5SDimitry Andric MachineInstr *MI) const { 1970b57cec5SDimitry Andric const MachineFunction &MF = *MI->getParent()->getParent(); 1980b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 1990b57cec5SDimitry Andric MachineInstr *Ret = MI; 2000b57cec5SDimitry Andric while (Ret->getOpcode() == TargetOpcode::COPY && 201*8bcb0991SDimitry Andric !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) && 2020b57cec5SDimitry Andric MRI.hasOneUse(Ret->getOperand(0).getReg())) { 2030b57cec5SDimitry Andric Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric return Ret; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric MachineInstr * 2090b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 2100b57cec5SDimitry Andric MachineInstr *MI) const { 2110b57cec5SDimitry Andric const MachineFunction &MF = *MI->getParent()->getParent(); 2120b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 2130b57cec5SDimitry Andric MachineInstr *Ret = MI; 2140b57cec5SDimitry Andric while (Ret->getOpcode() == TargetOpcode::COPY && 215*8bcb0991SDimitry Andric !Register::isPhysicalRegister(Ret->getOperand(1).getReg())) 2160b57cec5SDimitry Andric Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 2170b57cec5SDimitry Andric return Ret; 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 2210b57cec5SDimitry Andric const MachineInstr *MI) { 2220b57cec5SDimitry Andric assert(isAmbiguous(MI->getOpcode()) && 2230b57cec5SDimitry Andric "Not implemented for non Ambiguous opcode.\n"); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_LOAD) 2280b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_STORE) 2310b57cec5SDimitry Andric addUseDef(MI->getOperand(0).getReg(), MRI); 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_PHI) { 2340b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 2370b57cec5SDimitry Andric addUseDef(MI->getOperand(i).getReg(), MRI); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_SELECT) { 2410b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric addUseDef(MI->getOperand(2).getReg(), MRI); 2440b57cec5SDimitry Andric addUseDef(MI->getOperand(3).getReg(), MRI); 2450b57cec5SDimitry Andric } 246*8bcb0991SDimitry Andric 247*8bcb0991SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 248*8bcb0991SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric bool MipsRegisterBankInfo::TypeInfoForMF::visit( 2520b57cec5SDimitry Andric const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) { 2530b57cec5SDimitry Andric assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 2540b57cec5SDimitry Andric if (wasVisited(MI)) 2550b57cec5SDimitry Andric return true; // InstType has already been determined for MI. 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric startVisit(MI); 2580b57cec5SDimitry Andric AmbiguousRegDefUseContainer DefUseContainer(MI); 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric // Visit instructions where MI's DEF operands are USED. 2610b57cec5SDimitry Andric if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true)) 2620b57cec5SDimitry Andric return true; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Visit instructions that DEFINE MI's USE operands. 2650b57cec5SDimitry Andric if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false)) 2660b57cec5SDimitry Andric return true; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric // All MI's adjacent instructions, are ambiguous. 2690b57cec5SDimitry Andric if (!WaitingForTypeOfMI) { 2700b57cec5SDimitry Andric // This is chain of ambiguous instructions. 2710b57cec5SDimitry Andric setTypes(MI, InstType::Ambiguous); 2720b57cec5SDimitry Andric return true; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 2750b57cec5SDimitry Andric // instructions or has no other adjacent instructions. Anyway InstType could 2760b57cec5SDimitry Andric // not be determined. There could be unexplored path from some of 2770b57cec5SDimitry Andric // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 2780b57cec5SDimitry Andric // mapping available. 2790b57cec5SDimitry Andric // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 2800b57cec5SDimitry Andric // this way when WaitingForTypeOfMI figures out its InstType same InstType 2810b57cec5SDimitry Andric // will be assigned to all instructions in this branch. 2820b57cec5SDimitry Andric addToWaitingQueue(WaitingForTypeOfMI, MI); 2830b57cec5SDimitry Andric return false; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 2870b57cec5SDimitry Andric const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 2880b57cec5SDimitry Andric bool isDefUse) { 2890b57cec5SDimitry Andric while (!AdjacentInstrs.empty()) { 2900b57cec5SDimitry Andric MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 2930b57cec5SDimitry Andric : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 2940b57cec5SDimitry Andric setTypes(MI, InstType::FloatingPoint); 2950b57cec5SDimitry Andric return true; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric // Determine InstType from register bank of phys register that is 2990b57cec5SDimitry Andric // 'isDefUse ? def : use' of this copy. 3000b57cec5SDimitry Andric if (AdjMI->getOpcode() == TargetOpcode::COPY) { 3010b57cec5SDimitry Andric setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 3020b57cec5SDimitry Andric return true; 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric // Defaults to integer instruction. Includes G_MERGE_VALUES and 3060b57cec5SDimitry Andric // G_UNMERGE_VALUES. 3070b57cec5SDimitry Andric if (!isAmbiguous(AdjMI->getOpcode())) { 3080b57cec5SDimitry Andric setTypes(MI, InstType::Integer); 3090b57cec5SDimitry Andric return true; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // When AdjMI was visited first, MI has to continue to explore remaining 3130b57cec5SDimitry Andric // adjacent instructions and determine InstType without visiting AdjMI. 3140b57cec5SDimitry Andric if (!wasVisited(AdjMI) || 3150b57cec5SDimitry Andric getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 3160b57cec5SDimitry Andric if (visit(AdjMI, MI)) { 3170b57cec5SDimitry Andric // InstType is successfully determined and is same as for AdjMI. 3180b57cec5SDimitry Andric setTypes(MI, getRecordedTypeForInstr(AdjMI)); 3190b57cec5SDimitry Andric return true; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric return false; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 3270b57cec5SDimitry Andric InstType InstTy) { 3280b57cec5SDimitry Andric changeRecordedTypeForInstr(MI, InstTy); 3290b57cec5SDimitry Andric for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 3300b57cec5SDimitry Andric setTypes(WaitingInstr, InstTy); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 3350b57cec5SDimitry Andric const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 336*8bcb0991SDimitry Andric assert((Register::isPhysicalRegister(CopyInst->getOperand(Op).getReg())) && 3370b57cec5SDimitry Andric "Copies of non physical registers should not be considered here.\n"); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric const MachineFunction &MF = *CopyInst->getMF(); 3400b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 3410b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 3420b57cec5SDimitry Andric const RegisterBankInfo &RBI = 3430b57cec5SDimitry Andric *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 3440b57cec5SDimitry Andric const RegisterBank *Bank = 3450b57cec5SDimitry Andric RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric if (Bank == &Mips::FPRBRegBank) 3480b57cec5SDimitry Andric setTypes(MI, InstType::FloatingPoint); 3490b57cec5SDimitry Andric else if (Bank == &Mips::GPRBRegBank) 3500b57cec5SDimitry Andric setTypes(MI, InstType::Integer); 3510b57cec5SDimitry Andric else 3520b57cec5SDimitry Andric llvm_unreachable("Unsupported register bank.\n"); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric MipsRegisterBankInfo::InstType 3560b57cec5SDimitry Andric MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 3570b57cec5SDimitry Andric visit(MI, nullptr); 3580b57cec5SDimitry Andric return getRecordedTypeForInstr(MI); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 3620b57cec5SDimitry Andric llvm::StringRef FunctionName) { 3630b57cec5SDimitry Andric if (MFName != FunctionName) { 3640b57cec5SDimitry Andric MFName = FunctionName; 3650b57cec5SDimitry Andric WaitingQueues.clear(); 3660b57cec5SDimitry Andric Types.clear(); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 370*8bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping * 371*8bcb0991SDimitry Andric getMSAMapping(const MachineFunction &MF) { 372*8bcb0991SDimitry Andric assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() && 373*8bcb0991SDimitry Andric "MSA mapping not available on target without MSA."); 374*8bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::MSAIdx]; 375*8bcb0991SDimitry Andric } 376*8bcb0991SDimitry Andric 377*8bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) { 378*8bcb0991SDimitry Andric return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 379*8bcb0991SDimitry Andric : &Mips::ValueMappings[Mips::DPRIdx]; 380*8bcb0991SDimitry Andric } 381*8bcb0991SDimitry Andric 382*8bcb0991SDimitry Andric static const unsigned CustomMappingID = 1; 383*8bcb0991SDimitry Andric 384*8bcb0991SDimitry Andric // Only 64 bit mapping is available in fprb and will be marked as custom, i.e. 385*8bcb0991SDimitry Andric // will be split into two 32 bit registers in gprb. 386*8bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping * 387*8bcb0991SDimitry Andric getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) { 388*8bcb0991SDimitry Andric if (Size == 32) 389*8bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::GPRIdx]; 390*8bcb0991SDimitry Andric 391*8bcb0991SDimitry Andric MappingID = CustomMappingID; 392*8bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::DPRIdx]; 393*8bcb0991SDimitry Andric } 394*8bcb0991SDimitry Andric 3950b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping & 3960b57cec5SDimitry Andric MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric static TypeInfoForMF TI; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // Reset TI internal data when MF changes. 4010b57cec5SDimitry Andric TI.cleanupIfNewFunction(MI.getMF()->getName()); 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric unsigned Opc = MI.getOpcode(); 4040b57cec5SDimitry Andric const MachineFunction &MF = *MI.getParent()->getParent(); 4050b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric if (MI.getOpcode() != TargetOpcode::G_PHI) { 4080b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping &Mapping = 4090b57cec5SDimitry Andric getInstrMappingImpl(MI); 4100b57cec5SDimitry Andric if (Mapping.isValid()) 4110b57cec5SDimitry Andric return Mapping; 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric using namespace TargetOpcode; 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric unsigned NumOperands = MI.getNumOperands(); 4170b57cec5SDimitry Andric const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 4180b57cec5SDimitry Andric unsigned MappingID = DefaultMappingID; 419*8bcb0991SDimitry Andric 420*8bcb0991SDimitry Andric // Check if LLT sizes match sizes of available register banks. 421*8bcb0991SDimitry Andric for (const MachineOperand &Op : MI.operands()) { 422*8bcb0991SDimitry Andric if (Op.isReg()) { 423*8bcb0991SDimitry Andric LLT RegTy = MRI.getType(Op.getReg()); 424*8bcb0991SDimitry Andric 425*8bcb0991SDimitry Andric if (RegTy.isScalar() && 426*8bcb0991SDimitry Andric (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64)) 427*8bcb0991SDimitry Andric return getInvalidInstructionMapping(); 428*8bcb0991SDimitry Andric 429*8bcb0991SDimitry Andric if (RegTy.isVector() && RegTy.getSizeInBits() != 128) 430*8bcb0991SDimitry Andric return getInvalidInstructionMapping(); 431*8bcb0991SDimitry Andric } 432*8bcb0991SDimitry Andric } 433*8bcb0991SDimitry Andric 434*8bcb0991SDimitry Andric const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg()); 435*8bcb0991SDimitry Andric unsigned Op0Size = Op0Ty.getSizeInBits(); 436*8bcb0991SDimitry Andric InstType InstTy = InstType::Integer; 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric switch (Opc) { 4390b57cec5SDimitry Andric case G_TRUNC: 4400b57cec5SDimitry Andric case G_SUB: 4410b57cec5SDimitry Andric case G_MUL: 4420b57cec5SDimitry Andric case G_UMULH: 4430b57cec5SDimitry Andric case G_ZEXTLOAD: 4440b57cec5SDimitry Andric case G_SEXTLOAD: 4450b57cec5SDimitry Andric case G_GEP: 446*8bcb0991SDimitry Andric case G_INTTOPTR: 447*8bcb0991SDimitry Andric case G_PTRTOINT: 4480b57cec5SDimitry Andric case G_AND: 4490b57cec5SDimitry Andric case G_OR: 4500b57cec5SDimitry Andric case G_XOR: 4510b57cec5SDimitry Andric case G_SHL: 4520b57cec5SDimitry Andric case G_ASHR: 4530b57cec5SDimitry Andric case G_LSHR: 4540b57cec5SDimitry Andric case G_SDIV: 4550b57cec5SDimitry Andric case G_UDIV: 4560b57cec5SDimitry Andric case G_SREM: 4570b57cec5SDimitry Andric case G_UREM: 458*8bcb0991SDimitry Andric case G_BRINDIRECT: 459*8bcb0991SDimitry Andric case G_VASTART: 4600b57cec5SDimitry Andric OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 4610b57cec5SDimitry Andric break; 462*8bcb0991SDimitry Andric case G_ADD: 463*8bcb0991SDimitry Andric OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 464*8bcb0991SDimitry Andric if (Op0Size == 128) 465*8bcb0991SDimitry Andric OperandsMapping = getMSAMapping(MF); 466*8bcb0991SDimitry Andric break; 467*8bcb0991SDimitry Andric case G_STORE: 468*8bcb0991SDimitry Andric case G_LOAD: 469*8bcb0991SDimitry Andric if (Op0Size == 128) { 470*8bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 471*8bcb0991SDimitry Andric {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]}); 472*8bcb0991SDimitry Andric break; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 475*8bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 476*8bcb0991SDimitry Andric InstTy = TI.determineInstType(&MI); 477*8bcb0991SDimitry Andric 4780b57cec5SDimitry Andric if (InstTy == InstType::FloatingPoint || 479*8bcb0991SDimitry Andric (Op0Size == 64 && InstTy == InstType::Ambiguous)) 480*8bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 481*8bcb0991SDimitry Andric {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 482*8bcb0991SDimitry Andric else 4830b57cec5SDimitry Andric OperandsMapping = 484*8bcb0991SDimitry Andric getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID), 4850b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric break; 488*8bcb0991SDimitry Andric case G_PHI: 489*8bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 4900b57cec5SDimitry Andric InstTy = TI.determineInstType(&MI); 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric // PHI is copylike and should have one regbank in mapping for def register. 493*8bcb0991SDimitry Andric if (InstTy == InstType::Integer && Op0Size == 64) { 4940b57cec5SDimitry Andric OperandsMapping = 4950b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 4960b57cec5SDimitry Andric return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 4970b57cec5SDimitry Andric /*NumOperands=*/1); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric // Use default handling for PHI, i.e. set reg bank of def operand to match 5000b57cec5SDimitry Andric // register banks of use operands. 501*8bcb0991SDimitry Andric return getInstrMappingImpl(MI); 5020b57cec5SDimitry Andric case G_SELECT: { 503*8bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 5040b57cec5SDimitry Andric InstTy = TI.determineInstType(&MI); 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric if (InstTy == InstType::FloatingPoint || 507*8bcb0991SDimitry Andric (Op0Size == 64 && InstTy == InstType::Ambiguous)) { 508*8bcb0991SDimitry Andric const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size); 5090b57cec5SDimitry Andric OperandsMapping = getOperandsMapping( 5100b57cec5SDimitry Andric {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 5110b57cec5SDimitry Andric break; 512*8bcb0991SDimitry Andric } else { 5130b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping *Bank = 514*8bcb0991SDimitry Andric getGprbOrCustomMapping(Op0Size, MappingID); 5150b57cec5SDimitry Andric OperandsMapping = getOperandsMapping( 5160b57cec5SDimitry Andric {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric break; 5190b57cec5SDimitry Andric } 520*8bcb0991SDimitry Andric case G_IMPLICIT_DEF: 521*8bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 522*8bcb0991SDimitry Andric InstTy = TI.determineInstType(&MI); 523*8bcb0991SDimitry Andric 524*8bcb0991SDimitry Andric if (InstTy == InstType::FloatingPoint) 525*8bcb0991SDimitry Andric OperandsMapping = getFprbMapping(Op0Size); 526*8bcb0991SDimitry Andric else 527*8bcb0991SDimitry Andric OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID); 528*8bcb0991SDimitry Andric 529*8bcb0991SDimitry Andric break; 530*8bcb0991SDimitry Andric case G_UNMERGE_VALUES: 5310b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 5320b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 5330b57cec5SDimitry Andric &Mips::ValueMappings[Mips::DPRIdx]}); 5340b57cec5SDimitry Andric MappingID = CustomMappingID; 5350b57cec5SDimitry Andric break; 536*8bcb0991SDimitry Andric case G_MERGE_VALUES: 5370b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 5380b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 5390b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 5400b57cec5SDimitry Andric MappingID = CustomMappingID; 5410b57cec5SDimitry Andric break; 5420b57cec5SDimitry Andric case G_FADD: 5430b57cec5SDimitry Andric case G_FSUB: 5440b57cec5SDimitry Andric case G_FMUL: 5450b57cec5SDimitry Andric case G_FDIV: 5460b57cec5SDimitry Andric case G_FABS: 547*8bcb0991SDimitry Andric case G_FSQRT: 548*8bcb0991SDimitry Andric OperandsMapping = getFprbMapping(Op0Size); 5490b57cec5SDimitry Andric break; 550*8bcb0991SDimitry Andric case G_FCONSTANT: 551*8bcb0991SDimitry Andric OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr}); 5520b57cec5SDimitry Andric break; 5530b57cec5SDimitry Andric case G_FCMP: { 554*8bcb0991SDimitry Andric unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 5550b57cec5SDimitry Andric OperandsMapping = 5560b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 557*8bcb0991SDimitry Andric getFprbMapping(Op2Size), getFprbMapping(Op2Size)}); 5580b57cec5SDimitry Andric break; 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric case G_FPEXT: 5610b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 5620b57cec5SDimitry Andric &Mips::ValueMappings[Mips::SPRIdx]}); 5630b57cec5SDimitry Andric break; 5640b57cec5SDimitry Andric case G_FPTRUNC: 5650b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 5660b57cec5SDimitry Andric &Mips::ValueMappings[Mips::DPRIdx]}); 5670b57cec5SDimitry Andric break; 5680b57cec5SDimitry Andric case G_FPTOSI: { 569*8bcb0991SDimitry Andric assert((Op0Size == 32) && "Unsupported integer size"); 5700b57cec5SDimitry Andric unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 571*8bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 572*8bcb0991SDimitry Andric {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)}); 573*8bcb0991SDimitry Andric break; 574*8bcb0991SDimitry Andric } 575*8bcb0991SDimitry Andric case G_SITOFP: 576*8bcb0991SDimitry Andric assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) && 5770b57cec5SDimitry Andric "Unsupported integer size"); 578*8bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 579*8bcb0991SDimitry Andric {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 5800b57cec5SDimitry Andric break; 5810b57cec5SDimitry Andric case G_CONSTANT: 5820b57cec5SDimitry Andric case G_FRAME_INDEX: 5830b57cec5SDimitry Andric case G_GLOBAL_VALUE: 584*8bcb0991SDimitry Andric case G_JUMP_TABLE: 5850b57cec5SDimitry Andric case G_BRCOND: 5860b57cec5SDimitry Andric OperandsMapping = 5870b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 5880b57cec5SDimitry Andric break; 589*8bcb0991SDimitry Andric case G_BRJT: 590*8bcb0991SDimitry Andric OperandsMapping = 591*8bcb0991SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 592*8bcb0991SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 593*8bcb0991SDimitry Andric break; 5940b57cec5SDimitry Andric case G_ICMP: 5950b57cec5SDimitry Andric OperandsMapping = 5960b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 5970b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 5980b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 5990b57cec5SDimitry Andric break; 6000b57cec5SDimitry Andric default: 6010b57cec5SDimitry Andric return getInvalidInstructionMapping(); 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 6050b57cec5SDimitry Andric NumOperands); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric using InstListTy = GISelWorkList<4>; 6090b57cec5SDimitry Andric namespace { 6100b57cec5SDimitry Andric class InstManager : public GISelChangeObserver { 6110b57cec5SDimitry Andric InstListTy &InstList; 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric public: 6140b57cec5SDimitry Andric InstManager(InstListTy &Insts) : InstList(Insts) {} 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 6170b57cec5SDimitry Andric void erasingInstr(MachineInstr &MI) override {} 6180b57cec5SDimitry Andric void changingInstr(MachineInstr &MI) override {} 6190b57cec5SDimitry Andric void changedInstr(MachineInstr &MI) override {} 6200b57cec5SDimitry Andric }; 6210b57cec5SDimitry Andric } // end anonymous namespace 6220b57cec5SDimitry Andric 623*8bcb0991SDimitry Andric void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, 624*8bcb0991SDimitry Andric MachineRegisterInfo &MRI) const { 625*8bcb0991SDimitry Andric Register Dest = MI.getOperand(0).getReg(); 626*8bcb0991SDimitry Andric switch (MI.getOpcode()) { 627*8bcb0991SDimitry Andric case TargetOpcode::G_STORE: 628*8bcb0991SDimitry Andric // No def operands, skip this instruction. 629*8bcb0991SDimitry Andric break; 630*8bcb0991SDimitry Andric case TargetOpcode::G_CONSTANT: 631*8bcb0991SDimitry Andric case TargetOpcode::G_LOAD: 632*8bcb0991SDimitry Andric case TargetOpcode::G_SELECT: 633*8bcb0991SDimitry Andric case TargetOpcode::G_PHI: 634*8bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: { 635*8bcb0991SDimitry Andric assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type."); 636*8bcb0991SDimitry Andric MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 637*8bcb0991SDimitry Andric break; 638*8bcb0991SDimitry Andric } 639*8bcb0991SDimitry Andric case TargetOpcode::G_GEP: { 640*8bcb0991SDimitry Andric assert(MRI.getType(Dest).isPointer() && "Unexpected operand type."); 641*8bcb0991SDimitry Andric MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 642*8bcb0991SDimitry Andric break; 643*8bcb0991SDimitry Andric } 644*8bcb0991SDimitry Andric default: 645*8bcb0991SDimitry Andric llvm_unreachable("Unexpected opcode."); 646*8bcb0991SDimitry Andric } 647*8bcb0991SDimitry Andric } 648*8bcb0991SDimitry Andric 649*8bcb0991SDimitry Andric static void 650*8bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, 651*8bcb0991SDimitry Andric MachineInstr &MI) { 652*8bcb0991SDimitry Andric SmallVector<MachineInstr *, 2> DeadInstrs; 653*8bcb0991SDimitry Andric ArtCombiner.tryCombineMerges(MI, DeadInstrs); 654*8bcb0991SDimitry Andric for (MachineInstr *DeadMI : DeadInstrs) 655*8bcb0991SDimitry Andric DeadMI->eraseFromParent(); 656*8bcb0991SDimitry Andric } 657*8bcb0991SDimitry Andric 6580b57cec5SDimitry Andric void MipsRegisterBankInfo::applyMappingImpl( 6590b57cec5SDimitry Andric const OperandsMapper &OpdMapper) const { 6600b57cec5SDimitry Andric MachineInstr &MI = OpdMapper.getMI(); 6610b57cec5SDimitry Andric InstListTy NewInstrs; 6620b57cec5SDimitry Andric MachineIRBuilder B(MI); 6630b57cec5SDimitry Andric MachineFunction *MF = MI.getMF(); 6640b57cec5SDimitry Andric MachineRegisterInfo &MRI = OpdMapper.getMRI(); 665*8bcb0991SDimitry Andric const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo(); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric InstManager NewInstrObserver(NewInstrs); 6680b57cec5SDimitry Andric GISelObserverWrapper WrapperObserver(&NewInstrObserver); 6690b57cec5SDimitry Andric LegalizerHelper Helper(*MF, WrapperObserver, B); 670*8bcb0991SDimitry Andric LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric switch (MI.getOpcode()) { 6730b57cec5SDimitry Andric case TargetOpcode::G_LOAD: 6740b57cec5SDimitry Andric case TargetOpcode::G_STORE: 6750b57cec5SDimitry Andric case TargetOpcode::G_PHI: 676*8bcb0991SDimitry Andric case TargetOpcode::G_SELECT: 677*8bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: { 6780b57cec5SDimitry Andric Helper.narrowScalar(MI, 0, LLT::scalar(32)); 6790b57cec5SDimitry Andric // Handle new instructions. 6800b57cec5SDimitry Andric while (!NewInstrs.empty()) { 6810b57cec5SDimitry Andric MachineInstr *NewMI = NewInstrs.pop_back_val(); 6820b57cec5SDimitry Andric // This is new G_UNMERGE that was created during narrowScalar and will 6830b57cec5SDimitry Andric // not be considered for regbank selection. RegBankSelect for mips 6840b57cec5SDimitry Andric // visits/makes corresponding G_MERGE first. Combine them here. 685*8bcb0991SDimitry Andric if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) 686*8bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI); 6870b57cec5SDimitry Andric // This G_MERGE will be combined away when its corresponding G_UNMERGE 6880b57cec5SDimitry Andric // gets regBankSelected. 6890b57cec5SDimitry Andric else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 6900b57cec5SDimitry Andric continue; 6910b57cec5SDimitry Andric else 692*8bcb0991SDimitry Andric // Manually set register banks for def operands to 32 bit gprb. 693*8bcb0991SDimitry Andric setRegBank(*NewMI, MRI); 6940b57cec5SDimitry Andric } 6950b57cec5SDimitry Andric return; 6960b57cec5SDimitry Andric } 697*8bcb0991SDimitry Andric case TargetOpcode::G_UNMERGE_VALUES: 698*8bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(ArtCombiner, MI); 6990b57cec5SDimitry Andric return; 7000b57cec5SDimitry Andric default: 7010b57cec5SDimitry Andric break; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric return applyDefaultMapping(OpdMapper); 7050b57cec5SDimitry Andric } 706