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