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 const RegisterBankInfo::PartialMapping PartMappings
[]{
42 enum ValueMappingIdx
{
50 const 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
) {}
78 // Instructions where use operands are floating point registers.
79 // Def operands are general purpose.
80 static bool isFloatingPointOpcodeUse(unsigned Opc
) {
82 case TargetOpcode::G_FPTOSI
:
83 case TargetOpcode::G_FPTOUI
:
84 case TargetOpcode::G_FCMP
:
87 return isPreISelGenericFloatingPointOpcode(Opc
);
91 // Instructions where def operands are floating point registers.
92 // Use operands are general purpose.
93 static bool isFloatingPointOpcodeDef(unsigned Opc
) {
95 case TargetOpcode::G_SITOFP
:
96 case TargetOpcode::G_UITOFP
:
99 return isPreISelGenericFloatingPointOpcode(Opc
);
103 static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr
*MI
) {
104 if (MI
->getOpcode() == TargetOpcode::G_LOAD
||
105 MI
->getOpcode() == TargetOpcode::G_STORE
) {
106 auto MMO
= *MI
->memoperands_begin();
107 const MipsSubtarget
&STI
= MI
->getMF()->getSubtarget
<MipsSubtarget
>();
108 if (MMO
->getSize() == 4 && (!STI
.systemSupportsUnalignedAccess() &&
109 (!MMO
->getSize().hasValue() ||
110 MMO
->getAlign() < MMO
->getSize().getValue())))
116 static bool isAmbiguous(unsigned Opc
) {
118 case TargetOpcode::G_LOAD
:
119 case TargetOpcode::G_STORE
:
120 case TargetOpcode::G_PHI
:
121 case TargetOpcode::G_SELECT
:
122 case TargetOpcode::G_IMPLICIT_DEF
:
123 case TargetOpcode::G_UNMERGE_VALUES
:
124 case TargetOpcode::G_MERGE_VALUES
:
131 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
132 Register Reg
, const MachineRegisterInfo
&MRI
) {
133 assert(!MRI
.getType(Reg
).isPointer() &&
134 "Pointers are gprb, they should not be considered as ambiguous.\n");
135 for (MachineInstr
&UseMI
: MRI
.use_instructions(Reg
)) {
136 MachineInstr
*NonCopyInstr
= skipCopiesOutgoing(&UseMI
);
137 // Copy with many uses.
138 if (NonCopyInstr
->getOpcode() == TargetOpcode::COPY
&&
139 !NonCopyInstr
->getOperand(0).getReg().isPhysical())
140 addDefUses(NonCopyInstr
->getOperand(0).getReg(), MRI
);
142 DefUses
.push_back(skipCopiesOutgoing(&UseMI
));
146 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
147 Register Reg
, const MachineRegisterInfo
&MRI
) {
148 assert(!MRI
.getType(Reg
).isPointer() &&
149 "Pointers are gprb, they should not be considered as ambiguous.\n");
150 MachineInstr
*DefMI
= MRI
.getVRegDef(Reg
);
151 UseDefs
.push_back(skipCopiesIncoming(DefMI
));
155 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
156 MachineInstr
*MI
) const {
157 const MachineFunction
&MF
= *MI
->getParent()->getParent();
158 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
159 MachineInstr
*Ret
= MI
;
160 while (Ret
->getOpcode() == TargetOpcode::COPY
&&
161 !Ret
->getOperand(0).getReg().isPhysical() &&
162 MRI
.hasOneUse(Ret
->getOperand(0).getReg())) {
163 Ret
= &(*MRI
.use_instr_begin(Ret
->getOperand(0).getReg()));
169 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
170 MachineInstr
*MI
) const {
171 const MachineFunction
&MF
= *MI
->getParent()->getParent();
172 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
173 MachineInstr
*Ret
= MI
;
174 while (Ret
->getOpcode() == TargetOpcode::COPY
&&
175 !Ret
->getOperand(1).getReg().isPhysical())
176 Ret
= MRI
.getVRegDef(Ret
->getOperand(1).getReg());
180 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
181 const MachineInstr
*MI
) {
182 assert(isAmbiguous(MI
->getOpcode()) &&
183 "Not implemented for non Ambiguous opcode.\n");
185 const MachineRegisterInfo
&MRI
= MI
->getMF()->getRegInfo();
187 if (MI
->getOpcode() == TargetOpcode::G_LOAD
)
188 addDefUses(MI
->getOperand(0).getReg(), MRI
);
190 if (MI
->getOpcode() == TargetOpcode::G_STORE
)
191 addUseDef(MI
->getOperand(0).getReg(), MRI
);
193 if (auto *PHI
= dyn_cast
<GPhi
>(MI
)) {
194 addDefUses(PHI
->getReg(0), MRI
);
196 for (unsigned I
= 1; I
< PHI
->getNumIncomingValues(); ++I
)
197 addUseDef(PHI
->getIncomingValue(I
), MRI
);
200 if (MI
->getOpcode() == TargetOpcode::G_SELECT
) {
201 addDefUses(MI
->getOperand(0).getReg(), MRI
);
203 addUseDef(MI
->getOperand(2).getReg(), MRI
);
204 addUseDef(MI
->getOperand(3).getReg(), MRI
);
207 if (MI
->getOpcode() == TargetOpcode::G_IMPLICIT_DEF
)
208 addDefUses(MI
->getOperand(0).getReg(), MRI
);
210 if (MI
->getOpcode() == TargetOpcode::G_UNMERGE_VALUES
)
211 addUseDef(MI
->getOperand(MI
->getNumOperands() - 1).getReg(), MRI
);
213 if (MI
->getOpcode() == TargetOpcode::G_MERGE_VALUES
)
214 addDefUses(MI
->getOperand(0).getReg(), MRI
);
217 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
218 const MachineInstr
*MI
, const MachineInstr
*WaitingForTypeOfMI
,
219 InstType
&AmbiguousTy
) {
220 assert(isAmbiguous(MI
->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
222 return true; // InstType has already been determined for MI.
225 AmbiguousRegDefUseContainer
DefUseContainer(MI
);
227 if (isGprbTwoInstrUnalignedLoadOrStore(MI
)) {
228 setTypes(MI
, Integer
);
232 if (AmbiguousTy
== InstType::Ambiguous
&&
233 (MI
->getOpcode() == TargetOpcode::G_MERGE_VALUES
||
234 MI
->getOpcode() == TargetOpcode::G_UNMERGE_VALUES
))
235 AmbiguousTy
= InstType::AmbiguousWithMergeOrUnmerge
;
237 // Visit instructions where MI's DEF operands are USED.
238 if (visitAdjacentInstrs(MI
, DefUseContainer
.getDefUses(), true, AmbiguousTy
))
241 // Visit instructions that DEFINE MI's USE operands.
242 if (visitAdjacentInstrs(MI
, DefUseContainer
.getUseDefs(), false, AmbiguousTy
))
245 // All MI's adjacent instructions, are ambiguous.
246 if (!WaitingForTypeOfMI
) {
247 // This is chain of ambiguous instructions.
248 setTypes(MI
, AmbiguousTy
);
251 // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
252 // instructions or has no other adjacent instructions. Anyway InstType could
253 // not be determined. There could be unexplored path from some of
254 // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
255 // mapping available.
256 // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
257 // this way when WaitingForTypeOfMI figures out its InstType same InstType
258 // will be assigned to all instructions in this branch.
259 addToWaitingQueue(WaitingForTypeOfMI
, MI
);
263 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
264 const MachineInstr
*MI
, SmallVectorImpl
<MachineInstr
*> &AdjacentInstrs
,
265 bool isDefUse
, InstType
&AmbiguousTy
) {
266 while (!AdjacentInstrs
.empty()) {
267 MachineInstr
*AdjMI
= AdjacentInstrs
.pop_back_val();
269 if (isDefUse
? isFloatingPointOpcodeUse(AdjMI
->getOpcode())
270 : isFloatingPointOpcodeDef(AdjMI
->getOpcode())) {
271 setTypes(MI
, InstType::FloatingPoint
);
275 // Determine InstType from register bank of phys register that is
276 // 'isDefUse ? def : use' of this copy.
277 if (AdjMI
->getOpcode() == TargetOpcode::COPY
) {
278 setTypesAccordingToPhysicalRegister(MI
, AdjMI
, isDefUse
? 0 : 1);
282 // Defaults to integer instruction. Small registers in G_MERGE (uses) and
283 // G_UNMERGE (defs) will always be gprb.
284 if ((!isDefUse
&& AdjMI
->getOpcode() == TargetOpcode::G_UNMERGE_VALUES
) ||
285 (isDefUse
&& AdjMI
->getOpcode() == TargetOpcode::G_MERGE_VALUES
) ||
286 !isAmbiguous(AdjMI
->getOpcode())) {
287 setTypes(MI
, InstType::Integer
);
291 // When AdjMI was visited first, MI has to continue to explore remaining
292 // adjacent instructions and determine InstType without visiting AdjMI.
293 if (!wasVisited(AdjMI
) ||
294 getRecordedTypeForInstr(AdjMI
) != InstType::NotDetermined
) {
295 if (visit(AdjMI
, MI
, AmbiguousTy
)) {
296 // InstType is successfully determined and is same as for AdjMI.
297 setTypes(MI
, getRecordedTypeForInstr(AdjMI
));
305 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr
*MI
,
307 changeRecordedTypeForInstr(MI
, InstTy
);
308 for (const MachineInstr
*WaitingInstr
: getWaitingQueueFor(MI
)) {
309 setTypes(WaitingInstr
, InstTy
);
313 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
314 const MachineInstr
*MI
, const MachineInstr
*CopyInst
, unsigned Op
) {
315 assert((CopyInst
->getOperand(Op
).getReg().isPhysical()) &&
316 "Copies of non physical registers should not be considered here.\n");
318 const MachineFunction
&MF
= *CopyInst
->getMF();
319 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
320 const TargetRegisterInfo
&TRI
= *MF
.getSubtarget().getRegisterInfo();
321 const RegisterBankInfo
&RBI
=
322 *CopyInst
->getMF()->getSubtarget().getRegBankInfo();
323 const RegisterBank
*Bank
=
324 RBI
.getRegBank(CopyInst
->getOperand(Op
).getReg(), MRI
, TRI
);
326 if (Bank
== &Mips::FPRBRegBank
)
327 setTypes(MI
, InstType::FloatingPoint
);
328 else if (Bank
== &Mips::GPRBRegBank
)
329 setTypes(MI
, InstType::Integer
);
331 llvm_unreachable("Unsupported register bank.\n");
334 MipsRegisterBankInfo::InstType
335 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr
*MI
) {
336 InstType DefaultAmbiguousType
= InstType::Ambiguous
;
337 visit(MI
, nullptr, DefaultAmbiguousType
);
338 return getRecordedTypeForInstr(MI
);
341 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
342 llvm::StringRef FunctionName
) {
343 if (MFName
!= FunctionName
) {
344 MFName
= std::string(FunctionName
);
345 WaitingQueues
.clear();
350 static const MipsRegisterBankInfo::ValueMapping
*
351 getMSAMapping(const MachineFunction
&MF
) {
352 assert(MF
.getSubtarget
<MipsSubtarget
>().hasMSA() &&
353 "MSA mapping not available on target without MSA.");
354 return &Mips::ValueMappings
[Mips::MSAIdx
];
357 static const MipsRegisterBankInfo::ValueMapping
*getFprbMapping(unsigned Size
) {
358 return Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
359 : &Mips::ValueMappings
[Mips::DPRIdx
];
362 static const unsigned CustomMappingID
= 1;
364 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
365 // will be split into two 32 bit registers in gprb.
366 static const MipsRegisterBankInfo::ValueMapping
*
367 getGprbOrCustomMapping(unsigned Size
, unsigned &MappingID
) {
369 return &Mips::ValueMappings
[Mips::GPRIdx
];
371 MappingID
= CustomMappingID
;
372 return &Mips::ValueMappings
[Mips::DPRIdx
];
375 const RegisterBankInfo::InstructionMapping
&
376 MipsRegisterBankInfo::getInstrMapping(const MachineInstr
&MI
) const {
378 static TypeInfoForMF TI
;
380 // Reset TI internal data when MF changes.
381 TI
.cleanupIfNewFunction(MI
.getMF()->getName());
383 unsigned Opc
= MI
.getOpcode();
384 const MachineFunction
&MF
= *MI
.getParent()->getParent();
385 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
387 if (MI
.getOpcode() != TargetOpcode::G_PHI
) {
388 const RegisterBankInfo::InstructionMapping
&Mapping
=
389 getInstrMappingImpl(MI
);
390 if (Mapping
.isValid())
394 using namespace TargetOpcode
;
396 unsigned NumOperands
= MI
.getNumOperands();
397 const ValueMapping
*OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
398 unsigned MappingID
= DefaultMappingID
;
400 // Check if LLT sizes match sizes of available register banks.
401 for (const MachineOperand
&Op
: MI
.operands()) {
403 LLT RegTy
= MRI
.getType(Op
.getReg());
405 if (RegTy
.isScalar() &&
406 (RegTy
.getSizeInBits() != 32 && RegTy
.getSizeInBits() != 64))
407 return getInvalidInstructionMapping();
409 if (RegTy
.isVector() && RegTy
.getSizeInBits() != 128)
410 return getInvalidInstructionMapping();
414 const LLT Op0Ty
= MRI
.getType(MI
.getOperand(0).getReg());
415 unsigned Op0Size
= Op0Ty
.getSizeInBits();
416 InstType InstTy
= InstType::Integer
;
436 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
445 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
447 OperandsMapping
= getMSAMapping(MF
);
451 if (Op0Size
== 128) {
452 OperandsMapping
= getOperandsMapping(
453 {getMSAMapping(MF
), &Mips::ValueMappings
[Mips::GPRIdx
]});
457 if (!Op0Ty
.isPointer())
458 InstTy
= TI
.determineInstType(&MI
);
460 if (isFloatingPoint_32or64(InstTy
, Op0Size
) ||
461 isAmbiguous_64(InstTy
, Op0Size
)) {
462 OperandsMapping
= getOperandsMapping(
463 {getFprbMapping(Op0Size
), &Mips::ValueMappings
[Mips::GPRIdx
]});
465 assert((isInteger_32(InstTy
, Op0Size
) ||
466 isAmbiguous_32(InstTy
, Op0Size
) ||
467 isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) &&
468 "Unexpected Inst type");
470 getOperandsMapping({getGprbOrCustomMapping(Op0Size
, MappingID
),
471 &Mips::ValueMappings
[Mips::GPRIdx
]});
477 if (!Op0Ty
.isPointer())
478 InstTy
= TI
.determineInstType(&MI
);
480 // PHI is copylike and should have one regbank in mapping for def register.
481 if (isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) {
483 getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
]});
484 TI
.clearTypeInfoData(&MI
);
485 return getInstructionMapping(CustomMappingID
, /*Cost=*/1, OperandsMapping
,
488 assert((isInteger_32(InstTy
, Op0Size
) ||
489 isFloatingPoint_32or64(InstTy
, Op0Size
) ||
490 isAmbiguous_32or64(InstTy
, Op0Size
)) &&
491 "Unexpected Inst type");
492 // Use default handling for PHI, i.e. set reg bank of def operand to match
493 // register banks of use operands.
494 return getInstrMappingImpl(MI
);
497 if (!Op0Ty
.isPointer())
498 InstTy
= TI
.determineInstType(&MI
);
499 if (isFloatingPoint_32or64(InstTy
, Op0Size
) ||
500 isAmbiguous_64(InstTy
, Op0Size
)) {
501 const RegisterBankInfo::ValueMapping
*Bank
= getFprbMapping(Op0Size
);
502 OperandsMapping
= getOperandsMapping(
503 {Bank
, &Mips::ValueMappings
[Mips::GPRIdx
], Bank
, Bank
});
506 assert((isInteger_32(InstTy
, Op0Size
) ||
507 isAmbiguous_32(InstTy
, Op0Size
) ||
508 isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) &&
509 "Unexpected Inst type");
510 const RegisterBankInfo::ValueMapping
*Bank
=
511 getGprbOrCustomMapping(Op0Size
, MappingID
);
512 OperandsMapping
= getOperandsMapping(
513 {Bank
, &Mips::ValueMappings
[Mips::GPRIdx
], Bank
, Bank
});
517 case G_IMPLICIT_DEF
: {
518 if (!Op0Ty
.isPointer())
519 InstTy
= TI
.determineInstType(&MI
);
521 if (isFloatingPoint_32or64(InstTy
, Op0Size
))
522 OperandsMapping
= getFprbMapping(Op0Size
);
524 assert((isInteger_32(InstTy
, Op0Size
) ||
525 isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
)) &&
526 "Unexpected Inst type");
527 OperandsMapping
= getGprbOrCustomMapping(Op0Size
, MappingID
);
530 case G_UNMERGE_VALUES
: {
531 assert(MI
.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES");
532 unsigned Op3Size
= MRI
.getType(MI
.getOperand(2).getReg()).getSizeInBits();
533 InstTy
= TI
.determineInstType(&MI
);
534 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op3Size
) ||
535 isFloatingPoint_64(InstTy
, Op3Size
)) &&
536 "Unexpected Inst type");
537 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
],
538 &Mips::ValueMappings
[Mips::GPRIdx
],
539 &Mips::ValueMappings
[Mips::DPRIdx
]});
540 if (isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op3Size
))
541 MappingID
= CustomMappingID
;
544 case G_MERGE_VALUES
: {
545 InstTy
= TI
.determineInstType(&MI
);
546 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
) ||
547 isFloatingPoint_64(InstTy
, Op0Size
)) &&
548 "Unexpected Inst type");
549 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
550 &Mips::ValueMappings
[Mips::GPRIdx
],
551 &Mips::ValueMappings
[Mips::GPRIdx
]});
552 if (isAmbiguousWithMergeOrUnmerge_64(InstTy
, Op0Size
))
553 MappingID
= CustomMappingID
;
562 OperandsMapping
= getFprbMapping(Op0Size
);
564 OperandsMapping
= getMSAMapping(MF
);
567 OperandsMapping
= getOperandsMapping({getFprbMapping(Op0Size
), nullptr});
570 unsigned Op2Size
= MRI
.getType(MI
.getOperand(2).getReg()).getSizeInBits();
572 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
573 getFprbMapping(Op2Size
), getFprbMapping(Op2Size
)});
577 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
578 &Mips::ValueMappings
[Mips::SPRIdx
]});
581 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::SPRIdx
],
582 &Mips::ValueMappings
[Mips::DPRIdx
]});
585 assert((Op0Size
== 32) && "Unsupported integer size");
586 unsigned SizeFP
= MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits();
587 OperandsMapping
= getOperandsMapping(
588 {&Mips::ValueMappings
[Mips::GPRIdx
], getFprbMapping(SizeFP
)});
592 assert((MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits() == 32) &&
593 "Unsupported integer size");
594 OperandsMapping
= getOperandsMapping(
595 {getFprbMapping(Op0Size
), &Mips::ValueMappings
[Mips::GPRIdx
]});
603 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr});
607 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
608 &Mips::ValueMappings
[Mips::GPRIdx
]});
612 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
613 &Mips::ValueMappings
[Mips::GPRIdx
],
614 &Mips::ValueMappings
[Mips::GPRIdx
]});
617 return getInvalidInstructionMapping();
620 if (MappingID
== CustomMappingID
)
621 TI
.clearTypeInfoData(&MI
);
622 return getInstructionMapping(MappingID
, /*Cost=*/1, OperandsMapping
,
626 using InstListTy
= GISelWorkList
<4>;
628 class InstManager
: public GISelChangeObserver
{
629 InstListTy
&InstList
;
633 InstManager(MachineIRBuilder
&B
, InstListTy
&Insts
) : InstList(Insts
), B(B
) {
634 assert(!B
.isObservingChanges());
635 B
.setChangeObserver(*this);
638 ~InstManager() { B
.stopObservingChanges(); }
640 void createdInstr(MachineInstr
&MI
) override
{ InstList
.insert(&MI
); }
641 void erasingInstr(MachineInstr
&MI
) override
{}
642 void changingInstr(MachineInstr
&MI
) override
{}
643 void changedInstr(MachineInstr
&MI
) override
{}
645 } // end anonymous namespace
647 void MipsRegisterBankInfo::setRegBank(MachineInstr
&MI
,
648 MachineRegisterInfo
&MRI
) const {
649 Register Dest
= MI
.getOperand(0).getReg();
650 switch (MI
.getOpcode()) {
651 case TargetOpcode::G_STORE
:
652 // No def operands, skip this instruction.
654 case TargetOpcode::G_CONSTANT
:
655 case TargetOpcode::G_LOAD
:
656 case TargetOpcode::G_SELECT
:
657 case TargetOpcode::G_PHI
:
658 case TargetOpcode::G_IMPLICIT_DEF
: {
659 assert(MRI
.getType(Dest
) == LLT::scalar(32) && "Unexpected operand type.");
660 MRI
.setRegBank(Dest
, getRegBank(Mips::GPRBRegBankID
));
663 case TargetOpcode::G_PTR_ADD
: {
664 assert(MRI
.getType(Dest
).isPointer() && "Unexpected operand type.");
665 MRI
.setRegBank(Dest
, getRegBank(Mips::GPRBRegBankID
));
669 llvm_unreachable("Unexpected opcode.");
674 combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner
&ArtCombiner
,
675 GUnmerge
&MI
, GISelChangeObserver
&Observer
) {
676 SmallVector
<Register
, 4> UpdatedDefs
;
677 SmallVector
<MachineInstr
*, 2> DeadInstrs
;
678 ArtCombiner
.tryCombineUnmergeValues(MI
, DeadInstrs
,
679 UpdatedDefs
, Observer
);
680 for (MachineInstr
*DeadMI
: DeadInstrs
)
681 DeadMI
->eraseFromParent();
684 void MipsRegisterBankInfo::applyMappingImpl(
685 MachineIRBuilder
&Builder
, const OperandsMapper
&OpdMapper
) const {
686 MachineInstr
&MI
= OpdMapper
.getMI();
687 Builder
.setInstrAndDebugLoc(MI
);
689 InstListTy NewInstrs
;
690 MachineFunction
*MF
= MI
.getMF();
691 MachineRegisterInfo
&MRI
= OpdMapper
.getMRI();
692 const LegalizerInfo
&LegInfo
= *MF
->getSubtarget().getLegalizerInfo();
694 InstManager
NewInstrObserver(Builder
, NewInstrs
);
695 LegalizerHelper
Helper(*MF
, NewInstrObserver
, Builder
);
696 LegalizationArtifactCombiner
ArtCombiner(Builder
, MF
->getRegInfo(), LegInfo
);
698 switch (MI
.getOpcode()) {
699 case TargetOpcode::G_LOAD
:
700 case TargetOpcode::G_STORE
:
701 case TargetOpcode::G_PHI
:
702 case TargetOpcode::G_SELECT
:
703 case TargetOpcode::G_IMPLICIT_DEF
: {
704 Helper
.narrowScalar(MI
, 0, LLT::scalar(32));
705 // Handle new instructions.
706 while (!NewInstrs
.empty()) {
707 MachineInstr
*NewMI
= NewInstrs
.pop_back_val();
708 // This is new G_UNMERGE that was created during narrowScalar and will
709 // not be considered for regbank selection. RegBankSelect for mips
710 // visits/makes corresponding G_MERGE first. Combine them here.
711 if (auto *Unmerge
= dyn_cast
<GUnmerge
>(NewMI
))
712 combineAwayG_UNMERGE_VALUES(ArtCombiner
, *Unmerge
, NewInstrObserver
);
713 // This G_MERGE will be combined away when its corresponding G_UNMERGE
714 // gets regBankSelected.
715 else if (NewMI
->getOpcode() == TargetOpcode::G_MERGE_VALUES
)
718 // Manually set register banks for def operands to 32 bit gprb.
719 setRegBank(*NewMI
, MRI
);
723 case TargetOpcode::G_UNMERGE_VALUES
:
724 combineAwayG_UNMERGE_VALUES(ArtCombiner
, cast
<GUnmerge
>(MI
),
731 return applyDefaultMapping(OpdMapper
);