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 "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
16 #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
17 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #define GET_TARGET_REGBANK_IMPL
22 #include "MipsGenRegisterBank.inc"
26 enum PartialMappingIdx
{
33 RegisterBankInfo::PartialMapping PartMappings
[]{
39 enum ValueMappingIdx
{
46 RegisterBankInfo::ValueMapping ValueMappings
[] = {
49 // up to 3 operands in GPRs
50 {&PartMappings
[PMI_GPR
- PMI_Min
], 1},
51 {&PartMappings
[PMI_GPR
- PMI_Min
], 1},
52 {&PartMappings
[PMI_GPR
- PMI_Min
], 1},
53 // up to 3 ops operands FPRs - single precission
54 {&PartMappings
[PMI_SPR
- PMI_Min
], 1},
55 {&PartMappings
[PMI_SPR
- PMI_Min
], 1},
56 {&PartMappings
[PMI_SPR
- PMI_Min
], 1},
57 // up to 3 ops operands FPRs - double precission
58 {&PartMappings
[PMI_DPR
- PMI_Min
], 1},
59 {&PartMappings
[PMI_DPR
- PMI_Min
], 1},
60 {&PartMappings
[PMI_DPR
- PMI_Min
], 1}
63 } // end namespace Mips
64 } // end namespace llvm
68 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo
&TRI
)
69 : MipsGenRegisterBankInfo() {}
71 const RegisterBank
&MipsRegisterBankInfo::getRegBankFromRegClass(
72 const TargetRegisterClass
&RC
) const {
76 case Mips::GPR32RegClassID
:
77 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID
:
78 case Mips::GPRMM16MovePPairFirstRegClassID
:
79 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID
:
80 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID
:
81 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID
:
82 case Mips::SP32RegClassID
:
83 case Mips::GP32RegClassID
:
84 return getRegBank(Mips::GPRBRegBankID
);
85 case Mips::FGRCCRegClassID
:
86 case Mips::FGR32RegClassID
:
87 case Mips::FGR64RegClassID
:
88 case Mips::AFGR64RegClassID
:
89 return getRegBank(Mips::FPRBRegBankID
);
91 llvm_unreachable("Register class not supported");
95 // Instructions where all register operands are floating point.
96 static bool isFloatingPointOpcode(unsigned Opc
) {
98 case TargetOpcode::G_FCONSTANT
:
99 case TargetOpcode::G_FADD
:
100 case TargetOpcode::G_FSUB
:
101 case TargetOpcode::G_FMUL
:
102 case TargetOpcode::G_FDIV
:
103 case TargetOpcode::G_FABS
:
104 case TargetOpcode::G_FSQRT
:
105 case TargetOpcode::G_FCEIL
:
106 case TargetOpcode::G_FFLOOR
:
107 case TargetOpcode::G_FPEXT
:
108 case TargetOpcode::G_FPTRUNC
:
115 // Instructions where use operands are floating point registers.
116 // Def operands are general purpose.
117 static bool isFloatingPointOpcodeUse(unsigned Opc
) {
119 case TargetOpcode::G_FPTOSI
:
120 case TargetOpcode::G_FPTOUI
:
121 case TargetOpcode::G_FCMP
:
123 case Mips::ExtractElementF64
:
124 case Mips::ExtractElementF64_64
:
127 return isFloatingPointOpcode(Opc
);
131 // Instructions where def operands are floating point registers.
132 // Use operands are general purpose.
133 static bool isFloatingPointOpcodeDef(unsigned Opc
) {
135 case TargetOpcode::G_SITOFP
:
136 case TargetOpcode::G_UITOFP
:
138 case Mips::BuildPairF64
:
139 case Mips::BuildPairF64_64
:
142 return isFloatingPointOpcode(Opc
);
146 static bool isAmbiguous(unsigned Opc
) {
148 case TargetOpcode::G_LOAD
:
149 case TargetOpcode::G_STORE
:
150 case TargetOpcode::G_PHI
:
151 case TargetOpcode::G_SELECT
:
152 case TargetOpcode::G_IMPLICIT_DEF
:
159 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
160 Register Reg
, const MachineRegisterInfo
&MRI
) {
161 assert(!MRI
.getType(Reg
).isPointer() &&
162 "Pointers are gprb, they should not be considered as ambiguous.\n");
163 for (MachineInstr
&UseMI
: MRI
.use_instructions(Reg
)) {
164 MachineInstr
*NonCopyInstr
= skipCopiesOutgoing(&UseMI
);
165 // Copy with many uses.
166 if (NonCopyInstr
->getOpcode() == TargetOpcode::COPY
&&
167 !Register::isPhysicalRegister(NonCopyInstr
->getOperand(0).getReg()))
168 addDefUses(NonCopyInstr
->getOperand(0).getReg(), MRI
);
170 DefUses
.push_back(skipCopiesOutgoing(&UseMI
));
174 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
175 Register Reg
, const MachineRegisterInfo
&MRI
) {
176 assert(!MRI
.getType(Reg
).isPointer() &&
177 "Pointers are gprb, they should not be considered as ambiguous.\n");
178 MachineInstr
*DefMI
= MRI
.getVRegDef(Reg
);
179 UseDefs
.push_back(skipCopiesIncoming(DefMI
));
183 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
184 MachineInstr
*MI
) const {
185 const MachineFunction
&MF
= *MI
->getParent()->getParent();
186 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
187 MachineInstr
*Ret
= MI
;
188 while (Ret
->getOpcode() == TargetOpcode::COPY
&&
189 !Register::isPhysicalRegister(Ret
->getOperand(0).getReg()) &&
190 MRI
.hasOneUse(Ret
->getOperand(0).getReg())) {
191 Ret
= &(*MRI
.use_instr_begin(Ret
->getOperand(0).getReg()));
197 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
198 MachineInstr
*MI
) const {
199 const MachineFunction
&MF
= *MI
->getParent()->getParent();
200 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
201 MachineInstr
*Ret
= MI
;
202 while (Ret
->getOpcode() == TargetOpcode::COPY
&&
203 !Register::isPhysicalRegister(Ret
->getOperand(1).getReg()))
204 Ret
= MRI
.getVRegDef(Ret
->getOperand(1).getReg());
208 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
209 const MachineInstr
*MI
) {
210 assert(isAmbiguous(MI
->getOpcode()) &&
211 "Not implemented for non Ambiguous opcode.\n");
213 const MachineRegisterInfo
&MRI
= MI
->getMF()->getRegInfo();
215 if (MI
->getOpcode() == TargetOpcode::G_LOAD
)
216 addDefUses(MI
->getOperand(0).getReg(), MRI
);
218 if (MI
->getOpcode() == TargetOpcode::G_STORE
)
219 addUseDef(MI
->getOperand(0).getReg(), MRI
);
221 if (MI
->getOpcode() == TargetOpcode::G_PHI
) {
222 addDefUses(MI
->getOperand(0).getReg(), MRI
);
224 for (unsigned i
= 1; i
< MI
->getNumOperands(); i
+= 2)
225 addUseDef(MI
->getOperand(i
).getReg(), MRI
);
228 if (MI
->getOpcode() == TargetOpcode::G_SELECT
) {
229 addDefUses(MI
->getOperand(0).getReg(), MRI
);
231 addUseDef(MI
->getOperand(2).getReg(), MRI
);
232 addUseDef(MI
->getOperand(3).getReg(), MRI
);
235 if (MI
->getOpcode() == TargetOpcode::G_IMPLICIT_DEF
)
236 addDefUses(MI
->getOperand(0).getReg(), MRI
);
239 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
240 const MachineInstr
*MI
, const MachineInstr
*WaitingForTypeOfMI
) {
241 assert(isAmbiguous(MI
->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
243 return true; // InstType has already been determined for MI.
246 AmbiguousRegDefUseContainer
DefUseContainer(MI
);
248 // Visit instructions where MI's DEF operands are USED.
249 if (visitAdjacentInstrs(MI
, DefUseContainer
.getDefUses(), true))
252 // Visit instructions that DEFINE MI's USE operands.
253 if (visitAdjacentInstrs(MI
, DefUseContainer
.getUseDefs(), false))
256 // All MI's adjacent instructions, are ambiguous.
257 if (!WaitingForTypeOfMI
) {
258 // This is chain of ambiguous instructions.
259 setTypes(MI
, InstType::Ambiguous
);
262 // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
263 // instructions or has no other adjacent instructions. Anyway InstType could
264 // not be determined. There could be unexplored path from some of
265 // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
266 // mapping available.
267 // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
268 // this way when WaitingForTypeOfMI figures out its InstType same InstType
269 // will be assigned to all instructions in this branch.
270 addToWaitingQueue(WaitingForTypeOfMI
, MI
);
274 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
275 const MachineInstr
*MI
, SmallVectorImpl
<MachineInstr
*> &AdjacentInstrs
,
277 while (!AdjacentInstrs
.empty()) {
278 MachineInstr
*AdjMI
= AdjacentInstrs
.pop_back_val();
280 if (isDefUse
? isFloatingPointOpcodeUse(AdjMI
->getOpcode())
281 : isFloatingPointOpcodeDef(AdjMI
->getOpcode())) {
282 setTypes(MI
, InstType::FloatingPoint
);
286 // Determine InstType from register bank of phys register that is
287 // 'isDefUse ? def : use' of this copy.
288 if (AdjMI
->getOpcode() == TargetOpcode::COPY
) {
289 setTypesAccordingToPhysicalRegister(MI
, AdjMI
, isDefUse
? 0 : 1);
293 // Defaults to integer instruction. Includes G_MERGE_VALUES and
295 if (!isAmbiguous(AdjMI
->getOpcode())) {
296 setTypes(MI
, InstType::Integer
);
300 // When AdjMI was visited first, MI has to continue to explore remaining
301 // adjacent instructions and determine InstType without visiting AdjMI.
302 if (!wasVisited(AdjMI
) ||
303 getRecordedTypeForInstr(AdjMI
) != InstType::NotDetermined
) {
304 if (visit(AdjMI
, MI
)) {
305 // InstType is successfully determined and is same as for AdjMI.
306 setTypes(MI
, getRecordedTypeForInstr(AdjMI
));
314 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr
*MI
,
316 changeRecordedTypeForInstr(MI
, InstTy
);
317 for (const MachineInstr
*WaitingInstr
: getWaitingQueueFor(MI
)) {
318 setTypes(WaitingInstr
, InstTy
);
322 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
323 const MachineInstr
*MI
, const MachineInstr
*CopyInst
, unsigned Op
) {
324 assert((Register::isPhysicalRegister(CopyInst
->getOperand(Op
).getReg())) &&
325 "Copies of non physical registers should not be considered here.\n");
327 const MachineFunction
&MF
= *CopyInst
->getMF();
328 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
329 const TargetRegisterInfo
&TRI
= *MF
.getSubtarget().getRegisterInfo();
330 const RegisterBankInfo
&RBI
=
331 *CopyInst
->getMF()->getSubtarget().getRegBankInfo();
332 const RegisterBank
*Bank
=
333 RBI
.getRegBank(CopyInst
->getOperand(Op
).getReg(), MRI
, TRI
);
335 if (Bank
== &Mips::FPRBRegBank
)
336 setTypes(MI
, InstType::FloatingPoint
);
337 else if (Bank
== &Mips::GPRBRegBank
)
338 setTypes(MI
, InstType::Integer
);
340 llvm_unreachable("Unsupported register bank.\n");
343 MipsRegisterBankInfo::InstType
344 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr
*MI
) {
346 return getRecordedTypeForInstr(MI
);
349 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
350 llvm::StringRef FunctionName
) {
351 if (MFName
!= FunctionName
) {
352 MFName
= FunctionName
;
353 WaitingQueues
.clear();
358 const RegisterBankInfo::InstructionMapping
&
359 MipsRegisterBankInfo::getInstrMapping(const MachineInstr
&MI
) const {
361 static TypeInfoForMF TI
;
363 // Reset TI internal data when MF changes.
364 TI
.cleanupIfNewFunction(MI
.getMF()->getName());
366 unsigned Opc
= MI
.getOpcode();
367 const MachineFunction
&MF
= *MI
.getParent()->getParent();
368 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
370 if (MI
.getOpcode() != TargetOpcode::G_PHI
) {
371 const RegisterBankInfo::InstructionMapping
&Mapping
=
372 getInstrMappingImpl(MI
);
373 if (Mapping
.isValid())
377 using namespace TargetOpcode
;
379 unsigned NumOperands
= MI
.getNumOperands();
380 const ValueMapping
*OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
381 unsigned MappingID
= DefaultMappingID
;
382 const unsigned CustomMappingID
= 1;
407 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
410 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
411 InstType InstTy
= InstType::Integer
;
412 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
413 InstTy
= TI
.determineInstType(&MI
);
416 if (InstTy
== InstType::FloatingPoint
||
417 (Size
== 64 && InstTy
== InstType::Ambiguous
)) { // fprb
419 getOperandsMapping({Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
420 : &Mips::ValueMappings
[Mips::DPRIdx
],
421 &Mips::ValueMappings
[Mips::GPRIdx
]});
425 getOperandsMapping({Size
<= 32 ? &Mips::ValueMappings
[Mips::GPRIdx
]
426 : &Mips::ValueMappings
[Mips::DPRIdx
],
427 &Mips::ValueMappings
[Mips::GPRIdx
]});
429 MappingID
= CustomMappingID
;
435 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
436 InstType InstTy
= InstType::Integer
;
437 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
438 InstTy
= TI
.determineInstType(&MI
);
441 if (InstTy
== InstType::FloatingPoint
||
442 (Size
== 64 && InstTy
== InstType::Ambiguous
)) { // fprb
444 getOperandsMapping({Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
445 : &Mips::ValueMappings
[Mips::DPRIdx
],
446 &Mips::ValueMappings
[Mips::GPRIdx
]});
450 getOperandsMapping({Size
<= 32 ? &Mips::ValueMappings
[Mips::GPRIdx
]
451 : &Mips::ValueMappings
[Mips::DPRIdx
],
452 &Mips::ValueMappings
[Mips::GPRIdx
]});
454 MappingID
= CustomMappingID
;
459 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
460 InstType InstTy
= InstType::Integer
;
461 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
462 InstTy
= TI
.determineInstType(&MI
);
465 // PHI is copylike and should have one regbank in mapping for def register.
466 if (InstTy
== InstType::Integer
&& Size
== 64) { // fprb
468 getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
]});
469 return getInstructionMapping(CustomMappingID
, /*Cost=*/1, OperandsMapping
,
472 // Use default handling for PHI, i.e. set reg bank of def operand to match
473 // register banks of use operands.
474 const RegisterBankInfo::InstructionMapping
&Mapping
=
475 getInstrMappingImpl(MI
);
479 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
480 InstType InstTy
= InstType::Integer
;
481 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
482 InstTy
= TI
.determineInstType(&MI
);
485 if (InstTy
== InstType::FloatingPoint
||
486 (Size
== 64 && InstTy
== InstType::Ambiguous
)) { // fprb
487 const RegisterBankInfo::ValueMapping
*Bank
=
488 Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
489 : &Mips::ValueMappings
[Mips::DPRIdx
];
490 OperandsMapping
= getOperandsMapping(
491 {Bank
, &Mips::ValueMappings
[Mips::GPRIdx
], Bank
, Bank
});
494 const RegisterBankInfo::ValueMapping
*Bank
=
495 Size
<= 32 ? &Mips::ValueMappings
[Mips::GPRIdx
]
496 : &Mips::ValueMappings
[Mips::DPRIdx
];
497 OperandsMapping
= getOperandsMapping(
498 {Bank
, &Mips::ValueMappings
[Mips::GPRIdx
], Bank
, Bank
});
500 MappingID
= CustomMappingID
;
504 case G_IMPLICIT_DEF
: {
505 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
506 InstType InstTy
= InstType::Integer
;
507 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
508 InstTy
= TI
.determineInstType(&MI
);
511 if (InstTy
== InstType::FloatingPoint
) { // fprb
512 OperandsMapping
= Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
513 : &Mips::ValueMappings
[Mips::DPRIdx
];
515 OperandsMapping
= Size
== 32 ? &Mips::ValueMappings
[Mips::GPRIdx
]
516 : &Mips::ValueMappings
[Mips::DPRIdx
];
518 MappingID
= CustomMappingID
;
522 case G_UNMERGE_VALUES
: {
523 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
],
524 &Mips::ValueMappings
[Mips::GPRIdx
],
525 &Mips::ValueMappings
[Mips::DPRIdx
]});
526 MappingID
= CustomMappingID
;
529 case G_MERGE_VALUES
: {
530 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
531 &Mips::ValueMappings
[Mips::GPRIdx
],
532 &Mips::ValueMappings
[Mips::GPRIdx
]});
533 MappingID
= CustomMappingID
;
542 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
543 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
544 OperandsMapping
= Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
545 : &Mips::ValueMappings
[Mips::DPRIdx
];
549 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
550 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
551 const RegisterBankInfo::ValueMapping
*FPRValueMapping
=
552 Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
553 : &Mips::ValueMappings
[Mips::DPRIdx
];
554 OperandsMapping
= getOperandsMapping({FPRValueMapping
, nullptr});
558 unsigned Size
= MRI
.getType(MI
.getOperand(2).getReg()).getSizeInBits();
559 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
560 const RegisterBankInfo::ValueMapping
*FPRValueMapping
=
561 Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
562 : &Mips::ValueMappings
[Mips::DPRIdx
];
564 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
565 FPRValueMapping
, FPRValueMapping
});
569 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
570 &Mips::ValueMappings
[Mips::SPRIdx
]});
573 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::SPRIdx
],
574 &Mips::ValueMappings
[Mips::DPRIdx
]});
577 unsigned SizeFP
= MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits();
578 assert((MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits() == 32) &&
579 "Unsupported integer size");
580 assert((SizeFP
== 32 || SizeFP
== 64) && "Unsupported floating point size");
581 OperandsMapping
= getOperandsMapping({
582 &Mips::ValueMappings
[Mips::GPRIdx
],
583 SizeFP
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
584 : &Mips::ValueMappings
[Mips::DPRIdx
],
589 unsigned SizeInt
= MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits();
590 unsigned SizeFP
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
592 assert((SizeInt
== 32) && "Unsupported integer size");
593 assert((SizeFP
== 32 || SizeFP
== 64) && "Unsupported floating point size");
595 getOperandsMapping({SizeFP
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
596 : &Mips::ValueMappings
[Mips::DPRIdx
],
597 &Mips::ValueMappings
[Mips::GPRIdx
]});
606 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr});
610 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
611 &Mips::ValueMappings
[Mips::GPRIdx
]});
615 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
616 &Mips::ValueMappings
[Mips::GPRIdx
],
617 &Mips::ValueMappings
[Mips::GPRIdx
]});
620 return getInvalidInstructionMapping();
623 return getInstructionMapping(MappingID
, /*Cost=*/1, OperandsMapping
,
627 using InstListTy
= GISelWorkList
<4>;
629 class InstManager
: public GISelChangeObserver
{
630 InstListTy
&InstList
;
633 InstManager(InstListTy
&Insts
) : InstList(Insts
) {}
635 void createdInstr(MachineInstr
&MI
) override
{ InstList
.insert(&MI
); }
636 void erasingInstr(MachineInstr
&MI
) override
{}
637 void changingInstr(MachineInstr
&MI
) override
{}
638 void changedInstr(MachineInstr
&MI
) override
{}
640 } // end anonymous namespace
642 /// Here we have to narrowScalar s64 operands to s32, combine away
643 /// G_MERGE/G_UNMERGE and erase instructions that became dead in the process.
644 /// We manually assign 32 bit gprb to register operands of all new instructions
645 /// that got created in the process since they will not end up in RegBankSelect
646 /// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++.
647 void MipsRegisterBankInfo::applyMappingImpl(
648 const OperandsMapper
&OpdMapper
) const {
649 MachineInstr
&MI
= OpdMapper
.getMI();
650 InstListTy NewInstrs
;
651 MachineIRBuilder
B(MI
);
652 MachineFunction
*MF
= MI
.getMF();
653 MachineRegisterInfo
&MRI
= OpdMapper
.getMRI();
655 InstManager
NewInstrObserver(NewInstrs
);
656 GISelObserverWrapper
WrapperObserver(&NewInstrObserver
);
657 LegalizerHelper
Helper(*MF
, WrapperObserver
, B
);
658 LegalizationArtifactCombiner
ArtCombiner(
659 B
, MF
->getRegInfo(), *MF
->getSubtarget().getLegalizerInfo());
661 switch (MI
.getOpcode()) {
662 case TargetOpcode::G_LOAD
:
663 case TargetOpcode::G_STORE
:
664 case TargetOpcode::G_PHI
:
665 case TargetOpcode::G_SELECT
:
666 case TargetOpcode::G_IMPLICIT_DEF
: {
667 Helper
.narrowScalar(MI
, 0, LLT::scalar(32));
668 // Handle new instructions.
669 while (!NewInstrs
.empty()) {
670 MachineInstr
*NewMI
= NewInstrs
.pop_back_val();
671 // This is new G_UNMERGE that was created during narrowScalar and will
672 // not be considered for regbank selection. RegBankSelect for mips
673 // visits/makes corresponding G_MERGE first. Combine them here.
674 if (NewMI
->getOpcode() == TargetOpcode::G_UNMERGE_VALUES
) {
675 SmallVector
<MachineInstr
*, 2> DeadInstrs
;
676 ArtCombiner
.tryCombineMerges(*NewMI
, DeadInstrs
);
677 for (MachineInstr
*DeadMI
: DeadInstrs
)
678 DeadMI
->eraseFromParent();
680 // This G_MERGE will be combined away when its corresponding G_UNMERGE
681 // gets regBankSelected.
682 else if (NewMI
->getOpcode() == TargetOpcode::G_MERGE_VALUES
)
685 // Manually set register banks for all register operands to 32 bit gprb.
686 for (auto Op
: NewMI
->operands()) {
688 assert(MRI
.getType(Op
.getReg()).getSizeInBits() == 32 &&
689 "Only 32 bit gprb is handled here.\n");
690 MRI
.setRegBank(Op
.getReg(), getRegBank(Mips::GPRBRegBankID
));
696 case TargetOpcode::G_UNMERGE_VALUES
: {
697 SmallVector
<MachineInstr
*, 2> DeadInstrs
;
698 ArtCombiner
.tryCombineMerges(MI
, DeadInstrs
);
699 for (MachineInstr
*DeadMI
: DeadInstrs
)
700 DeadMI
->eraseFromParent();
707 return applyDefaultMapping(OpdMapper
);