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