[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / Mips / MipsRegisterBankInfo.cpp
blob04b69c66bc0d1ae5ab71380828ff5c904648394a
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 //===----------------------------------------------------------------------===//
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"
21 #define GET_TARGET_REGBANK_IMPL
23 #include "MipsGenRegisterBank.inc"
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,
35 RegisterBankInfo::PartialMapping PartMappings[]{
36 {0, 32, GPRBRegBank},
37 {0, 32, FPRBRegBank},
38 {0, 64, FPRBRegBank},
39 {0, 128, FPRBRegBank}
42 enum ValueMappingIdx {
43 InvalidIdx = 0,
44 GPRIdx = 1,
45 SPRIdx = 4,
46 DPRIdx = 7,
47 MSAIdx = 10
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}
71 } // end namespace Mips
72 } // end namespace llvm
74 using namespace llvm;
76 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
77 : MipsGenRegisterBankInfo() {}
79 const RegisterBank &
80 MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
81 LLT) const {
82 using namespace Mips;
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");
108 // Instructions where all register operands are floating point.
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;
128 // Instructions where use operands are floating point registers.
129 // Def operands are general purpose.
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);
141 // Instructions where def operands are floating point registers.
142 // Use operands are general purpose.
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);
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;
163 return false;
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;
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));
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));
204 MachineInstr *
205 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()));
215 return Ret;
218 MachineInstr *
219 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;
230 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
231 const MachineInstr *MI) {
232 assert(isAmbiguous(MI->getOpcode()) &&
233 "Not implemented for non Ambiguous opcode.\n");
235 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
237 if (MI->getOpcode() == TargetOpcode::G_LOAD)
238 addDefUses(MI->getOperand(0).getReg(), MRI);
240 if (MI->getOpcode() == TargetOpcode::G_STORE)
241 addUseDef(MI->getOperand(0).getReg(), MRI);
243 if (MI->getOpcode() == TargetOpcode::G_PHI) {
244 addDefUses(MI->getOperand(0).getReg(), MRI);
246 for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
247 addUseDef(MI->getOperand(i).getReg(), MRI);
250 if (MI->getOpcode() == TargetOpcode::G_SELECT) {
251 addDefUses(MI->getOperand(0).getReg(), MRI);
253 addUseDef(MI->getOperand(2).getReg(), MRI);
254 addUseDef(MI->getOperand(3).getReg(), MRI);
257 if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
258 addDefUses(MI->getOperand(0).getReg(), MRI);
260 if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
261 addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);
263 if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
264 addDefUses(MI->getOperand(0).getReg(), MRI);
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.
274 startVisit(MI);
275 AmbiguousRegDefUseContainer DefUseContainer(MI);
277 if (isGprbTwoInstrUnalignedLoadOrStore(MI)) {
278 setTypes(MI, Integer);
279 return true;
282 if (AmbiguousTy == InstType::Ambiguous &&
283 (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
284 MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
285 AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
287 // Visit instructions where MI's DEF operands are USED.
288 if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
289 return true;
291 // Visit instructions that DEFINE MI's USE operands.
292 if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
293 return true;
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;
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;
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();
319 if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
320 : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
321 setTypes(MI, InstType::FloatingPoint);
322 return true;
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;
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;
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;
352 return false;
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);
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");
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);
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");
384 MipsRegisterBankInfo::InstType
385 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
386 InstType DefaultAmbiguousType = InstType::Ambiguous;
387 visit(MI, nullptr, DefaultAmbiguousType);
388 return getRecordedTypeForInstr(MI);
391 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
392 llvm::StringRef FunctionName) {
393 if (MFName != FunctionName) {
394 MFName = std::string(FunctionName);
395 WaitingQueues.clear();
396 Types.clear();
400 static const MipsRegisterBankInfo::ValueMapping *
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];
407 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
408 return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
409 : &Mips::ValueMappings[Mips::DPRIdx];
412 static const unsigned CustomMappingID = 1;
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 *
417 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
418 if (Size == 32)
419 return &Mips::ValueMappings[Mips::GPRIdx];
421 MappingID = CustomMappingID;
422 return &Mips::ValueMappings[Mips::DPRIdx];
425 const RegisterBankInfo::InstructionMapping &
426 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
428 static TypeInfoForMF TI;
430 // Reset TI internal data when MF changes.
431 TI.cleanupIfNewFunction(MI.getMF()->getName());
433 unsigned Opc = MI.getOpcode();
434 const MachineFunction &MF = *MI.getParent()->getParent();
435 const MachineRegisterInfo &MRI = MF.getRegInfo();
437 if (MI.getOpcode() != TargetOpcode::G_PHI) {
438 const RegisterBankInfo::InstructionMapping &Mapping =
439 getInstrMappingImpl(MI);
440 if (Mapping.isValid())
441 return Mapping;
444 using namespace TargetOpcode;
446 unsigned NumOperands = MI.getNumOperands();
447 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
448 unsigned MappingID = DefaultMappingID;
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());
455 if (RegTy.isScalar() &&
456 (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
457 return getInvalidInstructionMapping();
459 if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
460 return getInvalidInstructionMapping();
464 const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
465 unsigned Op0Size = Op0Ty.getSizeInBits();
466 InstType InstTy = InstType::Integer;
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;
507 if (!Op0Ty.isPointer())
508 InstTy = TI.determineInstType(&MI);
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]});
524 break;
526 case G_PHI: {
527 if (!Op0Ty.isPointer())
528 InstTy = TI.determineInstType(&MI);
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);
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);
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});
565 break;
567 case G_IMPLICIT_DEF: {
568 if (!Op0Ty.isPointer())
569 InstTy = TI.determineInstType(&MI);
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);
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;
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;
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;
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;
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();
670 if (MappingID == CustomMappingID)
671 TI.clearTypeInfoData(&MI);
672 return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
673 NumOperands);
676 using InstListTy = GISelWorkList<4>;
677 namespace {
678 class InstManager : public GISelChangeObserver {
679 InstListTy &InstList;
681 public:
682 InstManager(InstListTy &Insts) : InstList(Insts) {}
684 void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
685 void erasingInstr(MachineInstr &MI) override {}
686 void changingInstr(MachineInstr &MI) override {}
687 void changedInstr(MachineInstr &MI) override {}
689 } // end anonymous namespace
691 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;
707 case TargetOpcode::G_PTR_ADD: {
708 assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
709 MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
710 break;
712 default:
713 llvm_unreachable("Unexpected opcode.");
717 static void
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();
728 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();
736 InstManager NewInstrObserver(NewInstrs);
737 MachineIRBuilder B(MI, NewInstrObserver);
738 LegalizerHelper Helper(*MF, NewInstrObserver, B);
739 LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo);
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);
764 return;
766 case TargetOpcode::G_UNMERGE_VALUES:
767 combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI),
768 NewInstrObserver);
769 return;
770 default:
771 break;
774 return applyDefaultMapping(OpdMapper);