1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
27 enum PartialMappingIdx
{
35 RegisterBankInfo::PartialMapping PartMappings
[]{
42 enum ValueMappingIdx
{
50 RegisterBankInfo::ValueMapping ValueMappings
[] = {
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
76 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo
&TRI
)
77 : MipsGenRegisterBankInfo() {}
80 MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass
&RC
,
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
);
104 llvm_unreachable("Register class not supported");
108 // Instructions where all register operands are floating point.
109 static bool isFloatingPointOpcode(unsigned 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
:
128 // Instructions where use operands are floating point registers.
129 // Def operands are general purpose.
130 static bool isFloatingPointOpcodeUse(unsigned Opc
) {
132 case TargetOpcode::G_FPTOSI
:
133 case TargetOpcode::G_FPTOUI
:
134 case TargetOpcode::G_FCMP
:
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
) {
145 case TargetOpcode::G_SITOFP
:
146 case TargetOpcode::G_UITOFP
:
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()))
166 static bool isAmbiguous(unsigned 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
:
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
);
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
));
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()));
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());
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");
272 return true; // InstType has already been determined for MI.
275 AmbiguousRegDefUseContainer
DefUseContainer(MI
);
277 if (isGprbTwoInstrUnalignedLoadOrStore(MI
)) {
278 setTypes(MI
, Integer
);
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
))
291 // Visit instructions that DEFINE MI's USE operands.
292 if (visitAdjacentInstrs(MI
, DefUseContainer
.getUseDefs(), false, AmbiguousTy
))
295 // All MI's adjacent instructions, are ambiguous.
296 if (!WaitingForTypeOfMI
) {
297 // This is chain of ambiguous instructions.
298 setTypes(MI
, AmbiguousTy
);
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
);
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
);
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);
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
);
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
));
355 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr
*MI
,
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
);
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();
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
) {
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())
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()) {
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
;
486 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
495 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
497 OperandsMapping
= getMSAMapping(MF
);
501 if (Op0Size
== 128) {
502 OperandsMapping
= getOperandsMapping(
503 {getMSAMapping(MF
), &Mips::ValueMappings
[Mips::GPRIdx
]});
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
]});
515 assert((isInteger_32(InstTy
, Op0Size
) ||
516 isAmbiguous_32(InstTy
, Op0Size
) ||
517 isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) &&
518 "Unexpected Inst type");
520 getOperandsMapping({getGprbOrCustomMapping(Op0Size
, MappingID
),
521 &Mips::ValueMappings
[Mips::GPRIdx
]});
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
)) {
533 getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
]});
534 TI
.clearTypeInfoData(&MI
);
535 return getInstructionMapping(CustomMappingID
, /*Cost=*/1, OperandsMapping
,
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
);
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
});
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
});
567 case G_IMPLICIT_DEF
: {
568 if (!Op0Ty
.isPointer())
569 InstTy
= TI
.determineInstType(&MI
);
571 if (isFloatingPoint_32or64(InstTy
, Op0Size
))
572 OperandsMapping
= getFprbMapping(Op0Size
);
574 assert((isInteger_32(InstTy
, Op0Size
) ||
575 isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) &&
576 "Unexpected Inst type");
577 OperandsMapping
= getGprbOrCustomMapping(Op0Size
, MappingID
);
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
;
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
;
612 OperandsMapping
= getFprbMapping(Op0Size
);
614 OperandsMapping
= getMSAMapping(MF
);
617 OperandsMapping
= getOperandsMapping({getFprbMapping(Op0Size
), nullptr});
620 unsigned Op2Size
= MRI
.getType(MI
.getOperand(2).getReg()).getSizeInBits();
622 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
623 getFprbMapping(Op2Size
), getFprbMapping(Op2Size
)});
627 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
628 &Mips::ValueMappings
[Mips::SPRIdx
]});
631 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::SPRIdx
],
632 &Mips::ValueMappings
[Mips::DPRIdx
]});
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
)});
642 assert((MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits() == 32) &&
643 "Unsupported integer size");
644 OperandsMapping
= getOperandsMapping(
645 {getFprbMapping(Op0Size
), &Mips::ValueMappings
[Mips::GPRIdx
]});
653 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr});
657 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
658 &Mips::ValueMappings
[Mips::GPRIdx
]});
662 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
663 &Mips::ValueMappings
[Mips::GPRIdx
],
664 &Mips::ValueMappings
[Mips::GPRIdx
]});
667 return getInvalidInstructionMapping();
670 if (MappingID
== CustomMappingID
)
671 TI
.clearTypeInfoData(&MI
);
672 return getInstructionMapping(MappingID
, /*Cost=*/1, OperandsMapping
,
676 using InstListTy
= GISelWorkList
<4>;
678 class InstManager
: public GISelChangeObserver
{
679 InstListTy
&InstList
;
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.
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
));
707 case TargetOpcode::G_PTR_ADD
: {
708 assert(MRI
.getType(Dest
).isPointer() && "Unexpected operand type.");
709 MRI
.setRegBank(Dest
, getRegBank(Mips::GPRBRegBankID
));
713 llvm_unreachable("Unexpected opcode.");
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
)
761 // Manually set register banks for def operands to 32 bit gprb.
762 setRegBank(*NewMI
, MRI
);
766 case TargetOpcode::G_UNMERGE_VALUES
:
767 combineAwayG_UNMERGE_VALUES(ArtCombiner
, cast
<GUnmerge
>(MI
),
774 return applyDefaultMapping(OpdMapper
);