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" 158bcb0991SDimitry 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, 318bcb0991SDimitry 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}, 388bcb0991SDimitry Andric {0, 64, FPRBRegBank}, 398bcb0991SDimitry Andric {0, 128, FPRBRegBank} 400b57cec5SDimitry Andric }; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric enum ValueMappingIdx { 430b57cec5SDimitry Andric InvalidIdx = 0, 440b57cec5SDimitry Andric GPRIdx = 1, 450b57cec5SDimitry Andric SPRIdx = 4, 468bcb0991SDimitry Andric DPRIdx = 7, 478bcb0991SDimitry 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}, 578bcb0991SDimitry 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}, 618bcb0991SDimitry 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}, 648bcb0991SDimitry Andric {&PartMappings[PMI_DPR - PMI_Min], 1}, 658bcb0991SDimitry Andric // up to 3 operands in FPRs - MSA 668bcb0991SDimitry Andric {&PartMappings[PMI_MSA - PMI_Min], 1}, 678bcb0991SDimitry Andric {&PartMappings[PMI_MSA - PMI_Min], 1}, 688bcb0991SDimitry 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 79*480093f4SDimitry Andric const RegisterBank & 80*480093f4SDimitry Andric MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, 81*480093f4SDimitry Andric LLT) const { 820b57cec5SDimitry Andric using namespace Mips; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric switch (RC.getID()) { 850b57cec5SDimitry Andric case Mips::GPR32RegClassID: 860b57cec5SDimitry Andric case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 870b57cec5SDimitry Andric case Mips::GPRMM16MovePPairFirstRegClassID: 880b57cec5SDimitry Andric case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 890b57cec5SDimitry Andric case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 900b57cec5SDimitry Andric case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 910b57cec5SDimitry Andric case Mips::SP32RegClassID: 920b57cec5SDimitry Andric case Mips::GP32RegClassID: 930b57cec5SDimitry Andric return getRegBank(Mips::GPRBRegBankID); 940b57cec5SDimitry Andric case Mips::FGRCCRegClassID: 950b57cec5SDimitry Andric case Mips::FGR32RegClassID: 960b57cec5SDimitry Andric case Mips::FGR64RegClassID: 970b57cec5SDimitry Andric case Mips::AFGR64RegClassID: 988bcb0991SDimitry Andric case Mips::MSA128BRegClassID: 998bcb0991SDimitry Andric case Mips::MSA128HRegClassID: 1008bcb0991SDimitry Andric case Mips::MSA128WRegClassID: 1018bcb0991SDimitry Andric case Mips::MSA128DRegClassID: 1020b57cec5SDimitry Andric return getRegBank(Mips::FPRBRegBankID); 1030b57cec5SDimitry Andric default: 1040b57cec5SDimitry Andric llvm_unreachable("Register class not supported"); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric // Instructions where all register operands are floating point. 1090b57cec5SDimitry Andric static bool isFloatingPointOpcode(unsigned Opc) { 1100b57cec5SDimitry Andric switch (Opc) { 1110b57cec5SDimitry Andric case TargetOpcode::G_FCONSTANT: 1120b57cec5SDimitry Andric case TargetOpcode::G_FADD: 1130b57cec5SDimitry Andric case TargetOpcode::G_FSUB: 1140b57cec5SDimitry Andric case TargetOpcode::G_FMUL: 1150b57cec5SDimitry Andric case TargetOpcode::G_FDIV: 1160b57cec5SDimitry Andric case TargetOpcode::G_FABS: 1170b57cec5SDimitry Andric case TargetOpcode::G_FSQRT: 1180b57cec5SDimitry Andric case TargetOpcode::G_FCEIL: 1190b57cec5SDimitry Andric case TargetOpcode::G_FFLOOR: 1200b57cec5SDimitry Andric case TargetOpcode::G_FPEXT: 1210b57cec5SDimitry Andric case TargetOpcode::G_FPTRUNC: 1220b57cec5SDimitry Andric return true; 1230b57cec5SDimitry Andric default: 1240b57cec5SDimitry Andric return false; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric // Instructions where use operands are floating point registers. 1290b57cec5SDimitry Andric // Def operands are general purpose. 1300b57cec5SDimitry Andric static bool isFloatingPointOpcodeUse(unsigned Opc) { 1310b57cec5SDimitry Andric switch (Opc) { 1320b57cec5SDimitry Andric case TargetOpcode::G_FPTOSI: 1330b57cec5SDimitry Andric case TargetOpcode::G_FPTOUI: 1340b57cec5SDimitry Andric case TargetOpcode::G_FCMP: 1350b57cec5SDimitry Andric case Mips::MFC1: 1360b57cec5SDimitry Andric case Mips::ExtractElementF64: 1370b57cec5SDimitry Andric case Mips::ExtractElementF64_64: 1380b57cec5SDimitry Andric return true; 1390b57cec5SDimitry Andric default: 1400b57cec5SDimitry Andric return isFloatingPointOpcode(Opc); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric // Instructions where def operands are floating point registers. 1450b57cec5SDimitry Andric // Use operands are general purpose. 1460b57cec5SDimitry Andric static bool isFloatingPointOpcodeDef(unsigned Opc) { 1470b57cec5SDimitry Andric switch (Opc) { 1480b57cec5SDimitry Andric case TargetOpcode::G_SITOFP: 1490b57cec5SDimitry Andric case TargetOpcode::G_UITOFP: 1500b57cec5SDimitry Andric case Mips::MTC1: 1510b57cec5SDimitry Andric case Mips::BuildPairF64: 1520b57cec5SDimitry Andric case Mips::BuildPairF64_64: 1530b57cec5SDimitry Andric return true; 1540b57cec5SDimitry Andric default: 1550b57cec5SDimitry Andric return isFloatingPointOpcode(Opc); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric static bool isAmbiguous(unsigned Opc) { 1600b57cec5SDimitry Andric switch (Opc) { 1610b57cec5SDimitry Andric case TargetOpcode::G_LOAD: 1620b57cec5SDimitry Andric case TargetOpcode::G_STORE: 1630b57cec5SDimitry Andric case TargetOpcode::G_PHI: 1640b57cec5SDimitry Andric case TargetOpcode::G_SELECT: 1658bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: 1660b57cec5SDimitry Andric return true; 1670b57cec5SDimitry Andric default: 1680b57cec5SDimitry Andric return false; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 1730b57cec5SDimitry Andric Register Reg, const MachineRegisterInfo &MRI) { 1740b57cec5SDimitry Andric assert(!MRI.getType(Reg).isPointer() && 1750b57cec5SDimitry Andric "Pointers are gprb, they should not be considered as ambiguous.\n"); 1760b57cec5SDimitry Andric for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 1770b57cec5SDimitry Andric MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 1780b57cec5SDimitry Andric // Copy with many uses. 1790b57cec5SDimitry Andric if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 1808bcb0991SDimitry Andric !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg())) 1810b57cec5SDimitry Andric addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 1820b57cec5SDimitry Andric else 1830b57cec5SDimitry Andric DefUses.push_back(skipCopiesOutgoing(&UseMI)); 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 1880b57cec5SDimitry Andric Register Reg, const MachineRegisterInfo &MRI) { 1890b57cec5SDimitry Andric assert(!MRI.getType(Reg).isPointer() && 1900b57cec5SDimitry Andric "Pointers are gprb, they should not be considered as ambiguous.\n"); 1910b57cec5SDimitry Andric MachineInstr *DefMI = MRI.getVRegDef(Reg); 1920b57cec5SDimitry Andric UseDefs.push_back(skipCopiesIncoming(DefMI)); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric MachineInstr * 1960b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 1970b57cec5SDimitry Andric MachineInstr *MI) const { 1980b57cec5SDimitry Andric const MachineFunction &MF = *MI->getParent()->getParent(); 1990b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 2000b57cec5SDimitry Andric MachineInstr *Ret = MI; 2010b57cec5SDimitry Andric while (Ret->getOpcode() == TargetOpcode::COPY && 2028bcb0991SDimitry Andric !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) && 2030b57cec5SDimitry Andric MRI.hasOneUse(Ret->getOperand(0).getReg())) { 2040b57cec5SDimitry Andric Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric return Ret; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric MachineInstr * 2100b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 2110b57cec5SDimitry Andric MachineInstr *MI) const { 2120b57cec5SDimitry Andric const MachineFunction &MF = *MI->getParent()->getParent(); 2130b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 2140b57cec5SDimitry Andric MachineInstr *Ret = MI; 2150b57cec5SDimitry Andric while (Ret->getOpcode() == TargetOpcode::COPY && 2168bcb0991SDimitry Andric !Register::isPhysicalRegister(Ret->getOperand(1).getReg())) 2170b57cec5SDimitry Andric Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 2180b57cec5SDimitry Andric return Ret; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 2220b57cec5SDimitry Andric const MachineInstr *MI) { 2230b57cec5SDimitry Andric assert(isAmbiguous(MI->getOpcode()) && 2240b57cec5SDimitry Andric "Not implemented for non Ambiguous opcode.\n"); 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_LOAD) 2290b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_STORE) 2320b57cec5SDimitry Andric addUseDef(MI->getOperand(0).getReg(), MRI); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_PHI) { 2350b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 2380b57cec5SDimitry Andric addUseDef(MI->getOperand(i).getReg(), MRI); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_SELECT) { 2420b57cec5SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric addUseDef(MI->getOperand(2).getReg(), MRI); 2450b57cec5SDimitry Andric addUseDef(MI->getOperand(3).getReg(), MRI); 2460b57cec5SDimitry Andric } 2478bcb0991SDimitry Andric 2488bcb0991SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 2498bcb0991SDimitry Andric addDefUses(MI->getOperand(0).getReg(), MRI); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric bool MipsRegisterBankInfo::TypeInfoForMF::visit( 2530b57cec5SDimitry Andric const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) { 2540b57cec5SDimitry Andric assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 2550b57cec5SDimitry Andric if (wasVisited(MI)) 2560b57cec5SDimitry Andric return true; // InstType has already been determined for MI. 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric startVisit(MI); 2590b57cec5SDimitry Andric AmbiguousRegDefUseContainer DefUseContainer(MI); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric // Visit instructions where MI's DEF operands are USED. 2620b57cec5SDimitry Andric if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true)) 2630b57cec5SDimitry Andric return true; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric // Visit instructions that DEFINE MI's USE operands. 2660b57cec5SDimitry Andric if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false)) 2670b57cec5SDimitry Andric return true; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric // All MI's adjacent instructions, are ambiguous. 2700b57cec5SDimitry Andric if (!WaitingForTypeOfMI) { 2710b57cec5SDimitry Andric // This is chain of ambiguous instructions. 2720b57cec5SDimitry Andric setTypes(MI, InstType::Ambiguous); 2730b57cec5SDimitry Andric return true; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 2760b57cec5SDimitry Andric // instructions or has no other adjacent instructions. Anyway InstType could 2770b57cec5SDimitry Andric // not be determined. There could be unexplored path from some of 2780b57cec5SDimitry Andric // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 2790b57cec5SDimitry Andric // mapping available. 2800b57cec5SDimitry Andric // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 2810b57cec5SDimitry Andric // this way when WaitingForTypeOfMI figures out its InstType same InstType 2820b57cec5SDimitry Andric // will be assigned to all instructions in this branch. 2830b57cec5SDimitry Andric addToWaitingQueue(WaitingForTypeOfMI, MI); 2840b57cec5SDimitry Andric return false; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 2880b57cec5SDimitry Andric const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 2890b57cec5SDimitry Andric bool isDefUse) { 2900b57cec5SDimitry Andric while (!AdjacentInstrs.empty()) { 2910b57cec5SDimitry Andric MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 2940b57cec5SDimitry Andric : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 2950b57cec5SDimitry Andric setTypes(MI, InstType::FloatingPoint); 2960b57cec5SDimitry Andric return true; 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric // Determine InstType from register bank of phys register that is 3000b57cec5SDimitry Andric // 'isDefUse ? def : use' of this copy. 3010b57cec5SDimitry Andric if (AdjMI->getOpcode() == TargetOpcode::COPY) { 3020b57cec5SDimitry Andric setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 3030b57cec5SDimitry Andric return true; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric // Defaults to integer instruction. Includes G_MERGE_VALUES and 3070b57cec5SDimitry Andric // G_UNMERGE_VALUES. 3080b57cec5SDimitry Andric if (!isAmbiguous(AdjMI->getOpcode())) { 3090b57cec5SDimitry Andric setTypes(MI, InstType::Integer); 3100b57cec5SDimitry Andric return true; 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric // When AdjMI was visited first, MI has to continue to explore remaining 3140b57cec5SDimitry Andric // adjacent instructions and determine InstType without visiting AdjMI. 3150b57cec5SDimitry Andric if (!wasVisited(AdjMI) || 3160b57cec5SDimitry Andric getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 3170b57cec5SDimitry Andric if (visit(AdjMI, MI)) { 3180b57cec5SDimitry Andric // InstType is successfully determined and is same as for AdjMI. 3190b57cec5SDimitry Andric setTypes(MI, getRecordedTypeForInstr(AdjMI)); 3200b57cec5SDimitry Andric return true; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric return false; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 3280b57cec5SDimitry Andric InstType InstTy) { 3290b57cec5SDimitry Andric changeRecordedTypeForInstr(MI, InstTy); 3300b57cec5SDimitry Andric for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 3310b57cec5SDimitry Andric setTypes(WaitingInstr, InstTy); 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 3360b57cec5SDimitry Andric const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 3378bcb0991SDimitry Andric assert((Register::isPhysicalRegister(CopyInst->getOperand(Op).getReg())) && 3380b57cec5SDimitry Andric "Copies of non physical registers should not be considered here.\n"); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric const MachineFunction &MF = *CopyInst->getMF(); 3410b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 3420b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 3430b57cec5SDimitry Andric const RegisterBankInfo &RBI = 3440b57cec5SDimitry Andric *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 3450b57cec5SDimitry Andric const RegisterBank *Bank = 3460b57cec5SDimitry Andric RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric if (Bank == &Mips::FPRBRegBank) 3490b57cec5SDimitry Andric setTypes(MI, InstType::FloatingPoint); 3500b57cec5SDimitry Andric else if (Bank == &Mips::GPRBRegBank) 3510b57cec5SDimitry Andric setTypes(MI, InstType::Integer); 3520b57cec5SDimitry Andric else 3530b57cec5SDimitry Andric llvm_unreachable("Unsupported register bank.\n"); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric MipsRegisterBankInfo::InstType 3570b57cec5SDimitry Andric MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 3580b57cec5SDimitry Andric visit(MI, nullptr); 3590b57cec5SDimitry Andric return getRecordedTypeForInstr(MI); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 3630b57cec5SDimitry Andric llvm::StringRef FunctionName) { 3640b57cec5SDimitry Andric if (MFName != FunctionName) { 3650b57cec5SDimitry Andric MFName = FunctionName; 3660b57cec5SDimitry Andric WaitingQueues.clear(); 3670b57cec5SDimitry Andric Types.clear(); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3718bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping * 3728bcb0991SDimitry Andric getMSAMapping(const MachineFunction &MF) { 3738bcb0991SDimitry Andric assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() && 3748bcb0991SDimitry Andric "MSA mapping not available on target without MSA."); 3758bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::MSAIdx]; 3768bcb0991SDimitry Andric } 3778bcb0991SDimitry Andric 3788bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) { 3798bcb0991SDimitry Andric return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 3808bcb0991SDimitry Andric : &Mips::ValueMappings[Mips::DPRIdx]; 3818bcb0991SDimitry Andric } 3828bcb0991SDimitry Andric 3838bcb0991SDimitry Andric static const unsigned CustomMappingID = 1; 3848bcb0991SDimitry Andric 3858bcb0991SDimitry Andric // Only 64 bit mapping is available in fprb and will be marked as custom, i.e. 3868bcb0991SDimitry Andric // will be split into two 32 bit registers in gprb. 3878bcb0991SDimitry Andric static const MipsRegisterBankInfo::ValueMapping * 3888bcb0991SDimitry Andric getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) { 3898bcb0991SDimitry Andric if (Size == 32) 3908bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::GPRIdx]; 3918bcb0991SDimitry Andric 3928bcb0991SDimitry Andric MappingID = CustomMappingID; 3938bcb0991SDimitry Andric return &Mips::ValueMappings[Mips::DPRIdx]; 3948bcb0991SDimitry Andric } 3958bcb0991SDimitry Andric 3960b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping & 3970b57cec5SDimitry Andric MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric static TypeInfoForMF TI; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric // Reset TI internal data when MF changes. 4020b57cec5SDimitry Andric TI.cleanupIfNewFunction(MI.getMF()->getName()); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric unsigned Opc = MI.getOpcode(); 4050b57cec5SDimitry Andric const MachineFunction &MF = *MI.getParent()->getParent(); 4060b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric if (MI.getOpcode() != TargetOpcode::G_PHI) { 4090b57cec5SDimitry Andric const RegisterBankInfo::InstructionMapping &Mapping = 4100b57cec5SDimitry Andric getInstrMappingImpl(MI); 4110b57cec5SDimitry Andric if (Mapping.isValid()) 4120b57cec5SDimitry Andric return Mapping; 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric using namespace TargetOpcode; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric unsigned NumOperands = MI.getNumOperands(); 4180b57cec5SDimitry Andric const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 4190b57cec5SDimitry Andric unsigned MappingID = DefaultMappingID; 4208bcb0991SDimitry Andric 4218bcb0991SDimitry Andric // Check if LLT sizes match sizes of available register banks. 4228bcb0991SDimitry Andric for (const MachineOperand &Op : MI.operands()) { 4238bcb0991SDimitry Andric if (Op.isReg()) { 4248bcb0991SDimitry Andric LLT RegTy = MRI.getType(Op.getReg()); 4258bcb0991SDimitry Andric 4268bcb0991SDimitry Andric if (RegTy.isScalar() && 4278bcb0991SDimitry Andric (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64)) 4288bcb0991SDimitry Andric return getInvalidInstructionMapping(); 4298bcb0991SDimitry Andric 4308bcb0991SDimitry Andric if (RegTy.isVector() && RegTy.getSizeInBits() != 128) 4318bcb0991SDimitry Andric return getInvalidInstructionMapping(); 4328bcb0991SDimitry Andric } 4338bcb0991SDimitry Andric } 4348bcb0991SDimitry Andric 4358bcb0991SDimitry Andric const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg()); 4368bcb0991SDimitry Andric unsigned Op0Size = Op0Ty.getSizeInBits(); 4378bcb0991SDimitry Andric InstType InstTy = InstType::Integer; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric switch (Opc) { 4400b57cec5SDimitry Andric case G_TRUNC: 4410b57cec5SDimitry Andric case G_UMULH: 4420b57cec5SDimitry Andric case G_ZEXTLOAD: 4430b57cec5SDimitry Andric case G_SEXTLOAD: 444*480093f4SDimitry Andric case G_PTR_ADD: 4458bcb0991SDimitry Andric case G_INTTOPTR: 4468bcb0991SDimitry Andric case G_PTRTOINT: 4470b57cec5SDimitry Andric case G_AND: 4480b57cec5SDimitry Andric case G_OR: 4490b57cec5SDimitry Andric case G_XOR: 4500b57cec5SDimitry Andric case G_SHL: 4510b57cec5SDimitry Andric case G_ASHR: 4520b57cec5SDimitry Andric case G_LSHR: 4538bcb0991SDimitry Andric case G_BRINDIRECT: 4548bcb0991SDimitry Andric case G_VASTART: 455*480093f4SDimitry Andric case G_BSWAP: 4560b57cec5SDimitry Andric OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 4570b57cec5SDimitry Andric break; 4588bcb0991SDimitry Andric case G_ADD: 459*480093f4SDimitry Andric case G_SUB: 460*480093f4SDimitry Andric case G_MUL: 461*480093f4SDimitry Andric case G_SDIV: 462*480093f4SDimitry Andric case G_SREM: 463*480093f4SDimitry Andric case G_UDIV: 464*480093f4SDimitry Andric case G_UREM: 4658bcb0991SDimitry Andric OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 4668bcb0991SDimitry Andric if (Op0Size == 128) 4678bcb0991SDimitry Andric OperandsMapping = getMSAMapping(MF); 4688bcb0991SDimitry Andric break; 4698bcb0991SDimitry Andric case G_STORE: 4708bcb0991SDimitry Andric case G_LOAD: 4718bcb0991SDimitry Andric if (Op0Size == 128) { 4728bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 4738bcb0991SDimitry Andric {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]}); 4748bcb0991SDimitry Andric break; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4778bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 4788bcb0991SDimitry Andric InstTy = TI.determineInstType(&MI); 4798bcb0991SDimitry Andric 4800b57cec5SDimitry Andric if (InstTy == InstType::FloatingPoint || 4818bcb0991SDimitry Andric (Op0Size == 64 && InstTy == InstType::Ambiguous)) 4828bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 4838bcb0991SDimitry Andric {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 4848bcb0991SDimitry Andric else 4850b57cec5SDimitry Andric OperandsMapping = 4868bcb0991SDimitry Andric getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID), 4870b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric break; 4908bcb0991SDimitry Andric case G_PHI: 4918bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 4920b57cec5SDimitry Andric InstTy = TI.determineInstType(&MI); 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric // PHI is copylike and should have one regbank in mapping for def register. 4958bcb0991SDimitry Andric if (InstTy == InstType::Integer && Op0Size == 64) { 4960b57cec5SDimitry Andric OperandsMapping = 4970b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 4980b57cec5SDimitry Andric return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 4990b57cec5SDimitry Andric /*NumOperands=*/1); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric // Use default handling for PHI, i.e. set reg bank of def operand to match 5020b57cec5SDimitry Andric // register banks of use operands. 5038bcb0991SDimitry Andric return getInstrMappingImpl(MI); 5040b57cec5SDimitry Andric case G_SELECT: { 5058bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 5060b57cec5SDimitry Andric InstTy = TI.determineInstType(&MI); 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric if (InstTy == InstType::FloatingPoint || 5098bcb0991SDimitry Andric (Op0Size == 64 && InstTy == InstType::Ambiguous)) { 5108bcb0991SDimitry Andric const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size); 5110b57cec5SDimitry Andric OperandsMapping = getOperandsMapping( 5120b57cec5SDimitry Andric {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 5130b57cec5SDimitry Andric break; 5148bcb0991SDimitry Andric } else { 5150b57cec5SDimitry Andric const RegisterBankInfo::ValueMapping *Bank = 5168bcb0991SDimitry Andric getGprbOrCustomMapping(Op0Size, MappingID); 5170b57cec5SDimitry Andric OperandsMapping = getOperandsMapping( 5180b57cec5SDimitry Andric {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric break; 5210b57cec5SDimitry Andric } 5228bcb0991SDimitry Andric case G_IMPLICIT_DEF: 5238bcb0991SDimitry Andric if (!Op0Ty.isPointer()) 5248bcb0991SDimitry Andric InstTy = TI.determineInstType(&MI); 5258bcb0991SDimitry Andric 5268bcb0991SDimitry Andric if (InstTy == InstType::FloatingPoint) 5278bcb0991SDimitry Andric OperandsMapping = getFprbMapping(Op0Size); 5288bcb0991SDimitry Andric else 5298bcb0991SDimitry Andric OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID); 5308bcb0991SDimitry Andric 5318bcb0991SDimitry Andric break; 5328bcb0991SDimitry Andric case G_UNMERGE_VALUES: 5330b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 5340b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 5350b57cec5SDimitry Andric &Mips::ValueMappings[Mips::DPRIdx]}); 5360b57cec5SDimitry Andric MappingID = CustomMappingID; 5370b57cec5SDimitry Andric break; 5388bcb0991SDimitry Andric case G_MERGE_VALUES: 5390b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 5400b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 5410b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 5420b57cec5SDimitry Andric MappingID = CustomMappingID; 5430b57cec5SDimitry Andric break; 5440b57cec5SDimitry Andric case G_FADD: 5450b57cec5SDimitry Andric case G_FSUB: 5460b57cec5SDimitry Andric case G_FMUL: 5470b57cec5SDimitry Andric case G_FDIV: 5480b57cec5SDimitry Andric case G_FABS: 5498bcb0991SDimitry Andric case G_FSQRT: 5508bcb0991SDimitry Andric OperandsMapping = getFprbMapping(Op0Size); 551*480093f4SDimitry Andric if (Op0Size == 128) 552*480093f4SDimitry Andric OperandsMapping = getMSAMapping(MF); 5530b57cec5SDimitry Andric break; 5548bcb0991SDimitry Andric case G_FCONSTANT: 5558bcb0991SDimitry Andric OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr}); 5560b57cec5SDimitry Andric break; 5570b57cec5SDimitry Andric case G_FCMP: { 5588bcb0991SDimitry Andric unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 5590b57cec5SDimitry Andric OperandsMapping = 5600b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 5618bcb0991SDimitry Andric getFprbMapping(Op2Size), getFprbMapping(Op2Size)}); 5620b57cec5SDimitry Andric break; 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric case G_FPEXT: 5650b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 5660b57cec5SDimitry Andric &Mips::ValueMappings[Mips::SPRIdx]}); 5670b57cec5SDimitry Andric break; 5680b57cec5SDimitry Andric case G_FPTRUNC: 5690b57cec5SDimitry Andric OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 5700b57cec5SDimitry Andric &Mips::ValueMappings[Mips::DPRIdx]}); 5710b57cec5SDimitry Andric break; 5720b57cec5SDimitry Andric case G_FPTOSI: { 5738bcb0991SDimitry Andric assert((Op0Size == 32) && "Unsupported integer size"); 5740b57cec5SDimitry Andric unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 5758bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 5768bcb0991SDimitry Andric {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)}); 5778bcb0991SDimitry Andric break; 5788bcb0991SDimitry Andric } 5798bcb0991SDimitry Andric case G_SITOFP: 5808bcb0991SDimitry Andric assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) && 5810b57cec5SDimitry Andric "Unsupported integer size"); 5828bcb0991SDimitry Andric OperandsMapping = getOperandsMapping( 5838bcb0991SDimitry Andric {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 5840b57cec5SDimitry Andric break; 5850b57cec5SDimitry Andric case G_CONSTANT: 5860b57cec5SDimitry Andric case G_FRAME_INDEX: 5870b57cec5SDimitry Andric case G_GLOBAL_VALUE: 5888bcb0991SDimitry Andric case G_JUMP_TABLE: 5890b57cec5SDimitry Andric case G_BRCOND: 5900b57cec5SDimitry Andric OperandsMapping = 5910b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 5920b57cec5SDimitry Andric break; 5938bcb0991SDimitry Andric case G_BRJT: 5948bcb0991SDimitry Andric OperandsMapping = 5958bcb0991SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 5968bcb0991SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 5978bcb0991SDimitry Andric break; 5980b57cec5SDimitry Andric case G_ICMP: 5990b57cec5SDimitry Andric OperandsMapping = 6000b57cec5SDimitry Andric getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 6010b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx], 6020b57cec5SDimitry Andric &Mips::ValueMappings[Mips::GPRIdx]}); 6030b57cec5SDimitry Andric break; 6040b57cec5SDimitry Andric default: 6050b57cec5SDimitry Andric return getInvalidInstructionMapping(); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 6090b57cec5SDimitry Andric NumOperands); 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric using InstListTy = GISelWorkList<4>; 6130b57cec5SDimitry Andric namespace { 6140b57cec5SDimitry Andric class InstManager : public GISelChangeObserver { 6150b57cec5SDimitry Andric InstListTy &InstList; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric public: 6180b57cec5SDimitry Andric InstManager(InstListTy &Insts) : InstList(Insts) {} 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 6210b57cec5SDimitry Andric void erasingInstr(MachineInstr &MI) override {} 6220b57cec5SDimitry Andric void changingInstr(MachineInstr &MI) override {} 6230b57cec5SDimitry Andric void changedInstr(MachineInstr &MI) override {} 6240b57cec5SDimitry Andric }; 6250b57cec5SDimitry Andric } // end anonymous namespace 6260b57cec5SDimitry Andric 6278bcb0991SDimitry Andric void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, 6288bcb0991SDimitry Andric MachineRegisterInfo &MRI) const { 6298bcb0991SDimitry Andric Register Dest = MI.getOperand(0).getReg(); 6308bcb0991SDimitry Andric switch (MI.getOpcode()) { 6318bcb0991SDimitry Andric case TargetOpcode::G_STORE: 6328bcb0991SDimitry Andric // No def operands, skip this instruction. 6338bcb0991SDimitry Andric break; 6348bcb0991SDimitry Andric case TargetOpcode::G_CONSTANT: 6358bcb0991SDimitry Andric case TargetOpcode::G_LOAD: 6368bcb0991SDimitry Andric case TargetOpcode::G_SELECT: 6378bcb0991SDimitry Andric case TargetOpcode::G_PHI: 6388bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: { 6398bcb0991SDimitry Andric assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type."); 6408bcb0991SDimitry Andric MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 6418bcb0991SDimitry Andric break; 6428bcb0991SDimitry Andric } 643*480093f4SDimitry Andric case TargetOpcode::G_PTR_ADD: { 6448bcb0991SDimitry Andric assert(MRI.getType(Dest).isPointer() && "Unexpected operand type."); 6458bcb0991SDimitry Andric MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 6468bcb0991SDimitry Andric break; 6478bcb0991SDimitry Andric } 6488bcb0991SDimitry Andric default: 6498bcb0991SDimitry Andric llvm_unreachable("Unexpected opcode."); 6508bcb0991SDimitry Andric } 6518bcb0991SDimitry Andric } 6528bcb0991SDimitry Andric 6538bcb0991SDimitry Andric static void 6548bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, 6558bcb0991SDimitry Andric MachineInstr &MI) { 656*480093f4SDimitry Andric SmallVector<Register, 4> UpdatedDefs; 6578bcb0991SDimitry Andric SmallVector<MachineInstr *, 2> DeadInstrs; 658*480093f4SDimitry Andric ArtCombiner.tryCombineMerges(MI, DeadInstrs, UpdatedDefs); 6598bcb0991SDimitry Andric for (MachineInstr *DeadMI : DeadInstrs) 6608bcb0991SDimitry Andric DeadMI->eraseFromParent(); 6618bcb0991SDimitry Andric } 6628bcb0991SDimitry Andric 6630b57cec5SDimitry Andric void MipsRegisterBankInfo::applyMappingImpl( 6640b57cec5SDimitry Andric const OperandsMapper &OpdMapper) const { 6650b57cec5SDimitry Andric MachineInstr &MI = OpdMapper.getMI(); 6660b57cec5SDimitry Andric InstListTy NewInstrs; 6670b57cec5SDimitry Andric MachineIRBuilder B(MI); 6680b57cec5SDimitry Andric MachineFunction *MF = MI.getMF(); 6690b57cec5SDimitry Andric MachineRegisterInfo &MRI = OpdMapper.getMRI(); 6708bcb0991SDimitry Andric const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo(); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric InstManager NewInstrObserver(NewInstrs); 6730b57cec5SDimitry Andric GISelObserverWrapper WrapperObserver(&NewInstrObserver); 6740b57cec5SDimitry Andric LegalizerHelper Helper(*MF, WrapperObserver, B); 6758bcb0991SDimitry Andric LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric switch (MI.getOpcode()) { 6780b57cec5SDimitry Andric case TargetOpcode::G_LOAD: 6790b57cec5SDimitry Andric case TargetOpcode::G_STORE: 6800b57cec5SDimitry Andric case TargetOpcode::G_PHI: 6818bcb0991SDimitry Andric case TargetOpcode::G_SELECT: 6828bcb0991SDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: { 6830b57cec5SDimitry Andric Helper.narrowScalar(MI, 0, LLT::scalar(32)); 6840b57cec5SDimitry Andric // Handle new instructions. 6850b57cec5SDimitry Andric while (!NewInstrs.empty()) { 6860b57cec5SDimitry Andric MachineInstr *NewMI = NewInstrs.pop_back_val(); 6870b57cec5SDimitry Andric // This is new G_UNMERGE that was created during narrowScalar and will 6880b57cec5SDimitry Andric // not be considered for regbank selection. RegBankSelect for mips 6890b57cec5SDimitry Andric // visits/makes corresponding G_MERGE first. Combine them here. 6908bcb0991SDimitry Andric if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) 6918bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI); 6920b57cec5SDimitry Andric // This G_MERGE will be combined away when its corresponding G_UNMERGE 6930b57cec5SDimitry Andric // gets regBankSelected. 6940b57cec5SDimitry Andric else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 6950b57cec5SDimitry Andric continue; 6960b57cec5SDimitry Andric else 6978bcb0991SDimitry Andric // Manually set register banks for def operands to 32 bit gprb. 6988bcb0991SDimitry Andric setRegBank(*NewMI, MRI); 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric return; 7010b57cec5SDimitry Andric } 7028bcb0991SDimitry Andric case TargetOpcode::G_UNMERGE_VALUES: 7038bcb0991SDimitry Andric combineAwayG_UNMERGE_VALUES(ArtCombiner, MI); 7040b57cec5SDimitry Andric return; 7050b57cec5SDimitry Andric default: 7060b57cec5SDimitry Andric break; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric return applyDefaultMapping(OpdMapper); 7100b57cec5SDimitry Andric } 711