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