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 def operands are floating point registers.
116 // Use operands are general purpose.
117 static bool isFloatingPointOpcodeDef(unsigned Opc
) {
119 case TargetOpcode::G_SITOFP
:
120 case TargetOpcode::G_UITOFP
:
122 case Mips::BuildPairF64
:
123 case Mips::BuildPairF64_64
:
126 return isFloatingPointOpcode(Opc
);
130 static bool isAmbiguous(unsigned Opc
) {
132 case TargetOpcode::G_LOAD
:
133 case TargetOpcode::G_STORE
:
134 case TargetOpcode::G_PHI
:
135 case TargetOpcode::G_SELECT
:
142 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
143 Register Reg
, const MachineRegisterInfo
&MRI
) {
144 assert(!MRI
.getType(Reg
).isPointer() &&
145 "Pointers are gprb, they should not be considered as ambiguous.\n");
146 MachineInstr
*DefMI
= MRI
.getVRegDef(Reg
);
147 if (DefMI
->getOpcode() == TargetOpcode::COPY
&&
148 !TargetRegisterInfo::isPhysicalRegister(DefMI
->getOperand(1).getReg()))
149 // Copies from non-physical registers are not supported.
152 UseDefs
.push_back(DefMI
);
155 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
156 const MachineInstr
*MI
) {
157 assert(isAmbiguous(MI
->getOpcode()) &&
158 "Not implemented for non Ambiguous opcode.\n");
160 const MachineRegisterInfo
&MRI
= MI
->getMF()->getRegInfo();
162 if (MI
->getOpcode() == TargetOpcode::G_STORE
)
163 addUseDef(MI
->getOperand(0).getReg(), MRI
);
166 bool MipsRegisterBankInfo::TypeInfoForMF::visit(const MachineInstr
*MI
) {
167 assert(isAmbiguous(MI
->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
170 AmbiguousRegDefUseContainer
DefUseContainer(MI
);
172 // Visit instructions that DEFINE MI's USE operands.
173 if (visitAdjacentInstrs(MI
, DefUseContainer
.getUseDefs()))
179 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
180 const MachineInstr
*MI
, SmallVectorImpl
<MachineInstr
*> &AdjacentInstrs
) {
181 while (!AdjacentInstrs
.empty()) {
182 MachineInstr
*AdjMI
= AdjacentInstrs
.pop_back_val();
184 if (isFloatingPointOpcodeDef(AdjMI
->getOpcode())) {
185 setTypes(MI
, InstType::FloatingPoint
);
189 // Determine InstType from register bank of phys register that is
191 if (AdjMI
->getOpcode() == TargetOpcode::COPY
) {
192 setTypesAccordingToPhysicalRegister(MI
, AdjMI
, 1);
196 if (isAmbiguous(AdjMI
->getOpcode())) {
197 // Chains of ambiguous instructions are not supported.
201 // Defaults to integer instruction. Includes G_MERGE_VALUES and
203 setTypes(MI
, InstType::Integer
);
209 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr
*MI
,
211 changeRecordedTypeForInstr(MI
, InstTy
);
214 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
215 const MachineInstr
*MI
, const MachineInstr
*CopyInst
, unsigned Op
) {
216 assert((TargetRegisterInfo::isPhysicalRegister(
217 CopyInst
->getOperand(Op
).getReg())) &&
218 "Copies of non physical registers should not be considered here.\n");
220 const MachineFunction
&MF
= *CopyInst
->getMF();
221 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
222 const TargetRegisterInfo
&TRI
= *MF
.getSubtarget().getRegisterInfo();
223 const RegisterBankInfo
&RBI
=
224 *CopyInst
->getMF()->getSubtarget().getRegBankInfo();
225 const RegisterBank
*Bank
=
226 RBI
.getRegBank(CopyInst
->getOperand(Op
).getReg(), MRI
, TRI
);
228 if (Bank
== &Mips::FPRBRegBank
)
229 setTypes(MI
, InstType::FloatingPoint
);
230 else if (Bank
== &Mips::GPRBRegBank
)
231 setTypes(MI
, InstType::Integer
);
233 llvm_unreachable("Unsupported register bank.\n");
236 MipsRegisterBankInfo::InstType
237 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr
*MI
) {
239 return getRecordedTypeForInstr(MI
);
242 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
243 llvm::StringRef FunctionName
) {
244 if (MFName
!= FunctionName
) {
245 MFName
= FunctionName
;
250 const RegisterBankInfo::InstructionMapping
&
251 MipsRegisterBankInfo::getInstrMapping(const MachineInstr
&MI
) const {
253 static TypeInfoForMF TI
;
255 // Reset TI internal data when MF changes.
256 TI
.cleanupIfNewFunction(MI
.getMF()->getName());
258 unsigned Opc
= MI
.getOpcode();
259 const MachineFunction
&MF
= *MI
.getParent()->getParent();
260 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
262 const RegisterBankInfo::InstructionMapping
&Mapping
= getInstrMappingImpl(MI
);
263 if (Mapping
.isValid())
266 using namespace TargetOpcode
;
268 unsigned NumOperands
= MI
.getNumOperands();
269 const ValueMapping
*OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
270 unsigned MappingID
= DefaultMappingID
;
271 const unsigned CustomMappingID
= 1;
293 OperandsMapping
= &Mips::ValueMappings
[Mips::GPRIdx
];
296 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
297 InstType InstTy
= InstType::Integer
;
298 if (!MRI
.getType(MI
.getOperand(0).getReg()).isPointer()) {
299 InstTy
= TI
.determineInstType(&MI
);
302 if (InstTy
== InstType::FloatingPoint
) { // fprb
304 getOperandsMapping({Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
305 : &Mips::ValueMappings
[Mips::DPRIdx
],
306 &Mips::ValueMappings
[Mips::GPRIdx
]});
310 getOperandsMapping({Size
<= 32 ? &Mips::ValueMappings
[Mips::GPRIdx
]
311 : &Mips::ValueMappings
[Mips::DPRIdx
],
312 &Mips::ValueMappings
[Mips::GPRIdx
]});
314 MappingID
= CustomMappingID
;
318 case G_MERGE_VALUES
: {
319 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
320 &Mips::ValueMappings
[Mips::GPRIdx
],
321 &Mips::ValueMappings
[Mips::GPRIdx
]});
322 MappingID
= CustomMappingID
;
331 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
332 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
333 OperandsMapping
= Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
334 : &Mips::ValueMappings
[Mips::DPRIdx
];
338 unsigned Size
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
339 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
340 const RegisterBankInfo::ValueMapping
*FPRValueMapping
=
341 Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
342 : &Mips::ValueMappings
[Mips::DPRIdx
];
343 OperandsMapping
= getOperandsMapping({FPRValueMapping
, nullptr});
347 unsigned Size
= MRI
.getType(MI
.getOperand(2).getReg()).getSizeInBits();
348 assert((Size
== 32 || Size
== 64) && "Unsupported floating point size");
349 const RegisterBankInfo::ValueMapping
*FPRValueMapping
=
350 Size
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
351 : &Mips::ValueMappings
[Mips::DPRIdx
];
353 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
354 FPRValueMapping
, FPRValueMapping
});
358 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::DPRIdx
],
359 &Mips::ValueMappings
[Mips::SPRIdx
]});
362 OperandsMapping
= getOperandsMapping({&Mips::ValueMappings
[Mips::SPRIdx
],
363 &Mips::ValueMappings
[Mips::DPRIdx
]});
366 unsigned SizeFP
= MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits();
367 assert((MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits() == 32) &&
368 "Unsupported integer size");
369 assert((SizeFP
== 32 || SizeFP
== 64) && "Unsupported floating point size");
370 OperandsMapping
= getOperandsMapping({
371 &Mips::ValueMappings
[Mips::GPRIdx
],
372 SizeFP
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
373 : &Mips::ValueMappings
[Mips::DPRIdx
],
378 unsigned SizeInt
= MRI
.getType(MI
.getOperand(1).getReg()).getSizeInBits();
379 unsigned SizeFP
= MRI
.getType(MI
.getOperand(0).getReg()).getSizeInBits();
381 assert((SizeInt
== 32) && "Unsupported integer size");
382 assert((SizeFP
== 32 || SizeFP
== 64) && "Unsupported floating point size");
384 getOperandsMapping({SizeFP
== 32 ? &Mips::ValueMappings
[Mips::SPRIdx
]
385 : &Mips::ValueMappings
[Mips::DPRIdx
],
386 &Mips::ValueMappings
[Mips::GPRIdx
]});
394 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr});
398 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
], nullptr,
399 &Mips::ValueMappings
[Mips::GPRIdx
],
400 &Mips::ValueMappings
[Mips::GPRIdx
]});
404 getOperandsMapping({&Mips::ValueMappings
[Mips::GPRIdx
],
405 &Mips::ValueMappings
[Mips::GPRIdx
],
406 &Mips::ValueMappings
[Mips::GPRIdx
],
407 &Mips::ValueMappings
[Mips::GPRIdx
]});
410 return getInvalidInstructionMapping();
413 return getInstructionMapping(MappingID
, /*Cost=*/1, OperandsMapping
,
417 using InstListTy
= GISelWorkList
<4>;
419 class InstManager
: public GISelChangeObserver
{
420 InstListTy
&InstList
;
423 InstManager(InstListTy
&Insts
) : InstList(Insts
) {}
425 void createdInstr(MachineInstr
&MI
) override
{ InstList
.insert(&MI
); }
426 void erasingInstr(MachineInstr
&MI
) override
{}
427 void changingInstr(MachineInstr
&MI
) override
{}
428 void changedInstr(MachineInstr
&MI
) override
{}
430 } // end anonymous namespace
432 /// Here we have to narrowScalar s64 operands to s32, combine away
433 /// G_MERGE/G_UNMERGE and erase instructions that became dead in the process.
434 /// We manually assign 32 bit gprb to register operands of all new instructions
435 /// that got created in the process since they will not end up in RegBankSelect
436 /// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++.
437 void MipsRegisterBankInfo::applyMappingImpl(
438 const OperandsMapper
&OpdMapper
) const {
439 MachineInstr
&MI
= OpdMapper
.getMI();
440 InstListTy NewInstrs
;
441 MachineIRBuilder
B(MI
);
442 MachineFunction
*MF
= MI
.getMF();
443 MachineRegisterInfo
&MRI
= OpdMapper
.getMRI();
445 InstManager
NewInstrObserver(NewInstrs
);
446 GISelObserverWrapper
WrapperObserver(&NewInstrObserver
);
447 LegalizerHelper
Helper(*MF
, WrapperObserver
, B
);
448 LegalizationArtifactCombiner
ArtCombiner(
449 B
, MF
->getRegInfo(), *MF
->getSubtarget().getLegalizerInfo());
451 switch (MI
.getOpcode()) {
452 case TargetOpcode::G_STORE
: {
453 Helper
.narrowScalar(MI
, 0, LLT::scalar(32));
454 // Handle new instructions.
455 while (!NewInstrs
.empty()) {
456 MachineInstr
*NewMI
= NewInstrs
.pop_back_val();
457 // This is new G_UNMERGE that was created during narrowScalar and will
458 // not be considered for regbank selection. RegBankSelect for mips
459 // visits/makes corresponding G_MERGE first. Combine them here.
460 if (NewMI
->getOpcode() == TargetOpcode::G_UNMERGE_VALUES
) {
461 SmallVector
<MachineInstr
*, 2> DeadInstrs
;
462 ArtCombiner
.tryCombineMerges(*NewMI
, DeadInstrs
);
463 for (MachineInstr
*DeadMI
: DeadInstrs
)
464 DeadMI
->eraseFromParent();
466 // Manually set register banks for all register operands to 32 bit gprb.
467 for (auto Op
: NewMI
->operands()) {
469 assert(MRI
.getType(Op
.getReg()).getSizeInBits() == 32 &&
470 "Only 32 bit gprb is handled here.\n");
471 MRI
.setRegBank(Op
.getReg(), getRegBank(Mips::GPRBRegBankID
));
481 return applyDefaultMapping(OpdMapper
);