brintos

brintos / llvm-project-archived public Read only

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