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