1 //===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
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
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "AArch64RegisterBankInfo.h"
15 #include "AArch64InstrInfo.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
18 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
19 #include "llvm/CodeGen/LowLevelType.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/CodeGen/MachineOperand.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/TargetOpcodes.h"
25 #include "llvm/CodeGen/TargetRegisterInfo.h"
26 #include "llvm/CodeGen/TargetSubtargetInfo.h"
27 #include "llvm/Support/ErrorHandling.h"
31 #define GET_TARGET_REGBANK_IMPL
32 #include "AArch64GenRegisterBank.inc"
34 // This file will be TableGen'ed at some point.
35 #include "AArch64GenRegisterBankInfo.def"
39 AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
40 : AArch64GenRegisterBankInfo() {
41 static llvm::once_flag InitializeRegisterBankFlag;
43 static auto InitializeRegisterBankOnce = [&]() {
44 // We have only one set of register banks, whatever the subtarget
45 // is. Therefore, the initialization of the RegBanks table should be
46 // done only once. Indeed the table of all register banks
47 // (AArch64::RegBanks) is unique in the compiler. At some point, it
48 // will get tablegen'ed and the whole constructor becomes empty.
50 const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
52 assert(&AArch64::GPRRegBank == &RBGPR &&
53 "The order in RegBanks is messed up");
55 const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
57 assert(&AArch64::FPRRegBank == &RBFPR &&
58 "The order in RegBanks is messed up");
60 const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
62 assert(&AArch64::CCRegBank == &RBCCR &&
63 "The order in RegBanks is messed up");
65 // The GPR register bank is fully defined by all the registers in
66 // GR64all + its subclasses.
67 assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
68 "Subclass not added?");
69 assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
71 // The FPR register bank is fully defined by all the registers in
72 // GR64all + its subclasses.
73 assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
74 "Subclass not added?");
75 assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
76 "Subclass not added?");
77 assert(RBFPR.getSize() == 512 &&
78 "FPRs should hold up to 512-bit via QQQQ sequence");
80 assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
82 assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
84 // Check that the TableGen'ed like file is in sync we our expectations.
86 assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
87 {PMI_GPR32, PMI_GPR64}) &&
88 "PartialMappingIdx's are incorrectly ordered");
89 assert(checkPartialMappingIdx(PMI_FirstFPR, PMI_LastFPR,
90 {PMI_FPR16, PMI_FPR32, PMI_FPR64, PMI_FPR128,
91 PMI_FPR256, PMI_FPR512}) &&
92 "PartialMappingIdx's are incorrectly ordered");
94 // Check partial mapping.
95 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \
98 checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
99 #Idx " is incorrectly initialized"); \
102 CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
103 CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
104 CHECK_PARTIALMAP(PMI_FPR16, 0, 16, RBFPR);
105 CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
106 CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
107 CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
108 CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
109 CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
111 // Check value mapping.
112 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \
114 assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size, \
115 PartialMappingIdx::PMI_First##RBName, Size, \
117 #RBName #Size " " #Offset " is incorrectly initialized"); \
120 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
122 CHECK_VALUEMAP(GPR, 32);
123 CHECK_VALUEMAP(GPR, 64);
124 CHECK_VALUEMAP(FPR, 16);
125 CHECK_VALUEMAP(FPR, 32);
126 CHECK_VALUEMAP(FPR, 64);
127 CHECK_VALUEMAP(FPR, 128);
128 CHECK_VALUEMAP(FPR, 256);
129 CHECK_VALUEMAP(FPR, 512);
131 // Check the value mapping for 3-operands instructions where all the operands
132 // map to the same value mapping.
133 #define CHECK_VALUEMAP_3OPS(RBName, Size) \
135 CHECK_VALUEMAP_IMPL(RBName, Size, 0); \
136 CHECK_VALUEMAP_IMPL(RBName, Size, 1); \
137 CHECK_VALUEMAP_IMPL(RBName, Size, 2); \
140 CHECK_VALUEMAP_3OPS(GPR, 32);
141 CHECK_VALUEMAP_3OPS(GPR, 64);
142 CHECK_VALUEMAP_3OPS(FPR, 32);
143 CHECK_VALUEMAP_3OPS(FPR, 64);
144 CHECK_VALUEMAP_3OPS(FPR, 128);
145 CHECK_VALUEMAP_3OPS(FPR, 256);
146 CHECK_VALUEMAP_3OPS(FPR, 512);
148 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \
150 unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min; \
151 unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min; \
152 (void)PartialMapDstIdx; \
153 (void)PartialMapSrcIdx; \
154 const ValueMapping *Map = getCopyMapping( \
155 AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size); \
157 assert(Map[0].BreakDown == \
158 &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
159 Map[0].NumBreakDowns == 1 && #RBNameDst #Size \
160 " Dst is incorrectly initialized"); \
161 assert(Map[1].BreakDown == \
162 &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
163 Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \
164 " Src is incorrectly initialized"); \
168 CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32);
169 CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32);
170 CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
171 CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64);
172 CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32);
173 CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32);
174 CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
175 CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64);
177 #define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize) \
179 unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min; \
180 unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min; \
181 (void)PartialMapDstIdx; \
182 (void)PartialMapSrcIdx; \
183 const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize); \
185 assert(Map[0].BreakDown == \
186 &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
187 Map[0].NumBreakDowns == 1 && "FPR" #DstSize \
188 " Dst is incorrectly initialized"); \
189 assert(Map[1].BreakDown == \
190 &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
191 Map[1].NumBreakDowns == 1 && "FPR" #SrcSize \
192 " Src is incorrectly initialized"); \
196 CHECK_VALUEMAP_FPEXT(32, 16);
197 CHECK_VALUEMAP_FPEXT(64, 16);
198 CHECK_VALUEMAP_FPEXT(64, 32);
199 CHECK_VALUEMAP_FPEXT(128, 64);
201 assert(verify(TRI) && "Invalid register bank information");
204 llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce);
207 unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
208 const RegisterBank &B,
209 unsigned Size) const {
210 // What do we do with different size?
211 // copy are same size.
212 // Will introduce other hooks for different size:
214 // * build_sequence cost.
216 // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
217 // FIXME: This should be deduced from the scheduling model.
218 if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
219 // FMOVXDr or FMOVWSr.
221 if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
222 // FMOVDXr or FMOVSWr.
225 return RegisterBankInfo::copyCost(A, B, Size);
229 AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
231 switch (RC.getID()) {
232 case AArch64::FPR8RegClassID:
233 case AArch64::FPR16RegClassID:
234 case AArch64::FPR16_loRegClassID:
235 case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID:
236 case AArch64::FPR32RegClassID:
237 case AArch64::FPR64RegClassID:
238 case AArch64::FPR64_loRegClassID:
239 case AArch64::FPR128RegClassID:
240 case AArch64::FPR128_loRegClassID:
241 case AArch64::DDRegClassID:
242 case AArch64::DDDRegClassID:
243 case AArch64::DDDDRegClassID:
244 case AArch64::QQRegClassID:
245 case AArch64::QQQRegClassID:
246 case AArch64::QQQQRegClassID:
247 return getRegBank(AArch64::FPRRegBankID);
248 case AArch64::GPR32commonRegClassID:
249 case AArch64::GPR32RegClassID:
250 case AArch64::GPR32spRegClassID:
251 case AArch64::GPR32sponlyRegClassID:
252 case AArch64::GPR32argRegClassID:
253 case AArch64::GPR32allRegClassID:
254 case AArch64::GPR64commonRegClassID:
255 case AArch64::GPR64RegClassID:
256 case AArch64::GPR64spRegClassID:
257 case AArch64::GPR64sponlyRegClassID:
258 case AArch64::GPR64argRegClassID:
259 case AArch64::GPR64allRegClassID:
260 case AArch64::GPR64noipRegClassID:
261 case AArch64::GPR64common_and_GPR64noipRegClassID:
262 case AArch64::GPR64noip_and_tcGPR64RegClassID:
263 case AArch64::tcGPR64RegClassID:
264 case AArch64::WSeqPairsClassRegClassID:
265 case AArch64::XSeqPairsClassRegClassID:
266 return getRegBank(AArch64::GPRRegBankID);
267 case AArch64::CCRRegClassID:
268 return getRegBank(AArch64::CCRegBankID);
270 llvm_unreachable("Register class not supported");
274 RegisterBankInfo::InstructionMappings
275 AArch64RegisterBankInfo::getInstrAlternativeMappings(
276 const MachineInstr &MI) const {
277 const MachineFunction &MF = *MI.getParent()->getParent();
278 const TargetSubtargetInfo &STI = MF.getSubtarget();
279 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
280 const MachineRegisterInfo &MRI = MF.getRegInfo();
282 switch (MI.getOpcode()) {
283 case TargetOpcode::G_OR: {
284 // 32 and 64-bit or can be mapped on either FPR or
285 // GPR for the same cost.
286 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
287 if (Size != 32 && Size != 64)
290 // If the instruction has any implicit-defs or uses,
291 // do not mess with it.
292 if (MI.getNumOperands() != 3)
294 InstructionMappings AltMappings;
295 const InstructionMapping &GPRMapping = getInstructionMapping(
296 /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
298 const InstructionMapping &FPRMapping = getInstructionMapping(
299 /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
302 AltMappings.push_back(&GPRMapping);
303 AltMappings.push_back(&FPRMapping);
306 case TargetOpcode::G_BITCAST: {
307 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
308 if (Size != 32 && Size != 64)
311 // If the instruction has any implicit-defs or uses,
312 // do not mess with it.
313 if (MI.getNumOperands() != 2)
316 InstructionMappings AltMappings;
317 const InstructionMapping &GPRMapping = getInstructionMapping(
318 /*ID*/ 1, /*Cost*/ 1,
319 getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
321 const InstructionMapping &FPRMapping = getInstructionMapping(
322 /*ID*/ 2, /*Cost*/ 1,
323 getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
325 const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
327 /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
328 getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
330 const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
332 /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
333 getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
336 AltMappings.push_back(&GPRMapping);
337 AltMappings.push_back(&FPRMapping);
338 AltMappings.push_back(&GPRToFPRMapping);
339 AltMappings.push_back(&FPRToGPRMapping);
342 case TargetOpcode::G_LOAD: {
343 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
347 // If the instruction has any implicit-defs or uses,
348 // do not mess with it.
349 if (MI.getNumOperands() != 2)
352 InstructionMappings AltMappings;
353 const InstructionMapping &GPRMapping = getInstructionMapping(
354 /*ID*/ 1, /*Cost*/ 1,
355 getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
356 // Addresses are GPR 64-bit.
357 getValueMapping(PMI_FirstGPR, 64)}),
359 const InstructionMapping &FPRMapping = getInstructionMapping(
360 /*ID*/ 2, /*Cost*/ 1,
361 getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
362 // Addresses are GPR 64-bit.
363 getValueMapping(PMI_FirstGPR, 64)}),
366 AltMappings.push_back(&GPRMapping);
367 AltMappings.push_back(&FPRMapping);
373 return RegisterBankInfo::getInstrAlternativeMappings(MI);
376 void AArch64RegisterBankInfo::applyMappingImpl(
377 const OperandsMapper &OpdMapper) const {
378 switch (OpdMapper.getMI().getOpcode()) {
379 case TargetOpcode::G_OR:
380 case TargetOpcode::G_BITCAST:
381 case TargetOpcode::G_LOAD:
382 // Those ID must match getInstrAlternativeMappings.
383 assert((OpdMapper.getInstrMapping().getID() >= 1 &&
384 OpdMapper.getInstrMapping().getID() <= 4) &&
385 "Don't know how to handle that ID");
386 return applyDefaultMapping(OpdMapper);
388 llvm_unreachable("Don't know how to handle that operation");
392 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
393 /// having only floating-point operands.
394 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
396 case TargetOpcode::G_FADD:
397 case TargetOpcode::G_FSUB:
398 case TargetOpcode::G_FMUL:
399 case TargetOpcode::G_FMA:
400 case TargetOpcode::G_FDIV:
401 case TargetOpcode::G_FCONSTANT:
402 case TargetOpcode::G_FPEXT:
403 case TargetOpcode::G_FPTRUNC:
404 case TargetOpcode::G_FCEIL:
405 case TargetOpcode::G_FFLOOR:
406 case TargetOpcode::G_FNEARBYINT:
407 case TargetOpcode::G_FNEG:
408 case TargetOpcode::G_FCOS:
409 case TargetOpcode::G_FSIN:
410 case TargetOpcode::G_FLOG10:
411 case TargetOpcode::G_FLOG:
412 case TargetOpcode::G_FLOG2:
413 case TargetOpcode::G_FSQRT:
414 case TargetOpcode::G_FABS:
415 case TargetOpcode::G_FEXP:
416 case TargetOpcode::G_FRINT:
417 case TargetOpcode::G_INTRINSIC_TRUNC:
418 case TargetOpcode::G_INTRINSIC_ROUND:
424 const RegisterBankInfo::InstructionMapping &
425 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
426 const MachineInstr &MI) const {
427 const unsigned Opc = MI.getOpcode();
428 const MachineFunction &MF = *MI.getParent()->getParent();
429 const MachineRegisterInfo &MRI = MF.getRegInfo();
431 unsigned NumOperands = MI.getNumOperands();
432 assert(NumOperands <= 3 &&
433 "This code is for instructions with 3 or less operands");
435 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
436 unsigned Size = Ty.getSizeInBits();
437 bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
439 PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
442 // Make sure all the operands are using similar size and type.
443 // Should probably be checked by the machine verifier.
444 // This code won't catch cases where the number of lanes is
445 // different between the operands.
446 // If we want to go to that level of details, it is probably
447 // best to check that the types are the same, period.
448 // Currently, we just check that the register banks are the same
450 for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
451 LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
453 AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
454 RBIdx, OpTy.getSizeInBits()) ==
455 AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
456 "Operand has incompatible size");
457 bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
459 assert(IsFPR == OpIsFPR && "Operand has incompatible type");
461 #endif // End NDEBUG.
463 return getInstructionMapping(DefaultMappingID, 1,
464 getValueMapping(RBIdx, Size), NumOperands);
467 bool AArch64RegisterBankInfo::hasFPConstraints(
468 const MachineInstr &MI, const MachineRegisterInfo &MRI,
469 const TargetRegisterInfo &TRI) const {
470 unsigned Op = MI.getOpcode();
472 // Do we have an explicit floating point instruction?
473 if (isPreISelGenericFloatingPointOpcode(Op))
476 // No. Check if we have a copy-like instruction. If we do, then we could
477 // still be fed by floating point instructions.
478 if (Op != TargetOpcode::COPY && !MI.isPHI())
481 // MI is copy-like. Return true if it outputs an FPR.
482 return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) ==
483 &AArch64::FPRRegBank;
486 bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
487 const MachineRegisterInfo &MRI,
488 const TargetRegisterInfo &TRI) const {
489 switch (MI.getOpcode()) {
490 case TargetOpcode::G_FPTOSI:
491 case TargetOpcode::G_FPTOUI:
492 case TargetOpcode::G_FCMP:
497 return hasFPConstraints(MI, MRI, TRI);
500 bool AArch64RegisterBankInfo::onlyDefinesFP(
501 const MachineInstr &MI, const MachineRegisterInfo &MRI,
502 const TargetRegisterInfo &TRI) const {
503 switch (MI.getOpcode()) {
505 case TargetOpcode::G_SITOFP:
506 case TargetOpcode::G_UITOFP:
507 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
508 case TargetOpcode::G_INSERT_VECTOR_ELT:
513 return hasFPConstraints(MI, MRI, TRI);
516 const RegisterBankInfo::InstructionMapping &
517 AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
518 const unsigned Opc = MI.getOpcode();
520 // Try the default logic for non-generic instructions that are either copies
521 // or already have some operands assigned to banks.
522 if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
523 Opc == TargetOpcode::G_PHI) {
524 const RegisterBankInfo::InstructionMapping &Mapping =
525 getInstrMappingImpl(MI);
526 if (Mapping.isValid())
530 const MachineFunction &MF = *MI.getParent()->getParent();
531 const MachineRegisterInfo &MRI = MF.getRegInfo();
532 const TargetSubtargetInfo &STI = MF.getSubtarget();
533 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
536 // G_{F|S|U}REM are not listed because they are not legal.
538 case TargetOpcode::G_ADD:
539 case TargetOpcode::G_SUB:
540 case TargetOpcode::G_PTR_ADD:
541 case TargetOpcode::G_MUL:
542 case TargetOpcode::G_SDIV:
543 case TargetOpcode::G_UDIV:
545 case TargetOpcode::G_AND:
546 case TargetOpcode::G_OR:
547 case TargetOpcode::G_XOR:
548 // Floating point ops.
549 case TargetOpcode::G_FADD:
550 case TargetOpcode::G_FSUB:
551 case TargetOpcode::G_FMUL:
552 case TargetOpcode::G_FDIV:
553 return getSameKindOfOperandsMapping(MI);
554 case TargetOpcode::G_FPEXT: {
555 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
556 LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
557 return getInstructionMapping(
558 DefaultMappingID, /*Cost*/ 1,
559 getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
563 case TargetOpcode::G_SHL:
564 case TargetOpcode::G_LSHR:
565 case TargetOpcode::G_ASHR: {
566 LLT ShiftAmtTy = MRI.getType(MI.getOperand(2).getReg());
567 LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
568 if (ShiftAmtTy.getSizeInBits() == 64 && SrcTy.getSizeInBits() == 32)
569 return getInstructionMapping(DefaultMappingID, 1,
570 &ValMappings[Shift64Imm], 3);
571 return getSameKindOfOperandsMapping(MI);
573 case TargetOpcode::COPY: {
574 Register DstReg = MI.getOperand(0).getReg();
575 Register SrcReg = MI.getOperand(1).getReg();
576 // Check if one of the register is not a generic register.
577 if ((Register::isPhysicalRegister(DstReg) ||
578 !MRI.getType(DstReg).isValid()) ||
579 (Register::isPhysicalRegister(SrcReg) ||
580 !MRI.getType(SrcReg).isValid())) {
581 const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
582 const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
587 // If both RB are null that means both registers are generic.
588 // We shouldn't be here.
589 assert(DstRB && SrcRB && "Both RegBank were nullptr");
590 unsigned Size = getSizeInBits(DstReg, MRI, TRI);
591 return getInstructionMapping(
592 DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
593 getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
594 // We only care about the mapping of the destination.
597 // Both registers are generic, use G_BITCAST.
600 case TargetOpcode::G_BITCAST: {
601 LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
602 LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
603 unsigned Size = DstTy.getSizeInBits();
604 bool DstIsGPR = !DstTy.isVector() && DstTy.getSizeInBits() <= 64;
605 bool SrcIsGPR = !SrcTy.isVector() && SrcTy.getSizeInBits() <= 64;
606 const RegisterBank &DstRB =
607 DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
608 const RegisterBank &SrcRB =
609 SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
610 return getInstructionMapping(
611 DefaultMappingID, copyCost(DstRB, SrcRB, Size),
612 getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
613 // We only care about the mapping of the destination for COPY.
614 /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 2 : 1);
620 unsigned NumOperands = MI.getNumOperands();
622 // Track the size and bank of each register. We don't do partial mappings.
623 SmallVector<unsigned, 4> OpSize(NumOperands);
624 SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
625 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
626 auto &MO = MI.getOperand(Idx);
627 if (!MO.isReg() || !MO.getReg())
630 LLT Ty = MRI.getType(MO.getReg());
631 OpSize[Idx] = Ty.getSizeInBits();
633 // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
634 // For floating-point instructions, scalars go in FPRs.
635 if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc) ||
636 Ty.getSizeInBits() > 64)
637 OpRegBankIdx[Idx] = PMI_FirstFPR;
639 OpRegBankIdx[Idx] = PMI_FirstGPR;
643 // Some of the floating-point instructions have mixed GPR and FPR operands:
644 // fine-tune the computed mapping.
646 case AArch64::G_DUP: {
647 Register ScalarReg = MI.getOperand(1).getReg();
648 auto ScalarDef = MRI.getVRegDef(ScalarReg);
649 if (getRegBank(ScalarReg, MRI, TRI) == &AArch64::FPRRegBank ||
650 onlyDefinesFP(*ScalarDef, MRI, TRI))
651 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
653 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
656 case TargetOpcode::G_TRUNC: {
657 LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
658 if (!SrcTy.isVector() && SrcTy.getSizeInBits() == 128)
659 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
662 case TargetOpcode::G_SITOFP:
663 case TargetOpcode::G_UITOFP:
664 if (MRI.getType(MI.getOperand(0).getReg()).isVector())
666 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
668 case TargetOpcode::G_FPTOSI:
669 case TargetOpcode::G_FPTOUI:
670 if (MRI.getType(MI.getOperand(0).getReg()).isVector())
672 OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
674 case TargetOpcode::G_FCMP:
675 OpRegBankIdx = {PMI_FirstGPR,
676 /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
678 case TargetOpcode::G_BITCAST:
679 // This is going to be a cross register bank copy and this is expensive.
680 if (OpRegBankIdx[0] != OpRegBankIdx[1])
682 *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
683 *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
686 case TargetOpcode::G_LOAD:
687 // Loading in vector unit is slightly more expensive.
688 // This is actually only true for the LD1R and co instructions,
689 // but anyway for the fast mode this number does not matter and
690 // for the greedy mode the cost of the cross bank copy will
691 // offset this number.
692 // FIXME: Should be derived from the scheduling model.
693 if (OpRegBankIdx[0] != PMI_FirstGPR)
696 // Check if that load feeds fp instructions.
697 // In that case, we want the default mapping to be on FPR
698 // instead of blind map every scalar to GPR.
699 for (const MachineInstr &UseMI :
700 MRI.use_nodbg_instructions(MI.getOperand(0).getReg())) {
701 // If we have at least one direct use in a FP instruction,
702 // assume this was a floating point load in the IR.
703 // If it was not, we would have had a bitcast before
704 // reaching that instruction.
705 if (onlyUsesFP(UseMI, MRI, TRI)) {
706 OpRegBankIdx[0] = PMI_FirstFPR;
711 case TargetOpcode::G_STORE:
712 // Check if that store is fed by fp instructions.
713 if (OpRegBankIdx[0] == PMI_FirstGPR) {
714 Register VReg = MI.getOperand(0).getReg();
717 MachineInstr *DefMI = MRI.getVRegDef(VReg);
718 if (onlyDefinesFP(*DefMI, MRI, TRI))
719 OpRegBankIdx[0] = PMI_FirstFPR;
723 case TargetOpcode::G_SELECT: {
724 // If the destination is FPR, preserve that.
725 if (OpRegBankIdx[0] != PMI_FirstGPR)
728 // If we're taking in vectors, we have no choice but to put everything on
729 // FPRs, except for the condition. The condition must always be on a GPR.
730 LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
731 if (SrcTy.isVector()) {
732 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
736 // Try to minimize the number of copies. If we have more floating point
737 // constrained values than not, then we'll put everything on FPR. Otherwise,
738 // everything has to be on GPR.
741 // Check if the uses of the result always produce floating point values.
745 // %z = G_SELECT %cond %x %y
746 // fpr = G_FOO %z ...
747 if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
748 [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); }))
751 // Check if the defs of the source values always produce floating point
756 // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
757 // %z = G_SELECT %cond %x %y
759 // Also check whether or not the sources have already been decided to be
760 // FPR. Keep track of this.
762 // This doesn't check the condition, since it's just whatever is in NZCV.
763 // This isn't passed explicitly in a register to fcsel/csel.
764 for (unsigned Idx = 2; Idx < 4; ++Idx) {
765 Register VReg = MI.getOperand(Idx).getReg();
766 MachineInstr *DefMI = MRI.getVRegDef(VReg);
767 if (getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
768 onlyDefinesFP(*DefMI, MRI, TRI))
772 // If we have more FP constraints than not, then move everything over to
775 OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
779 case TargetOpcode::G_UNMERGE_VALUES: {
780 // If the first operand belongs to a FPR register bank, then make sure that
782 if (OpRegBankIdx[0] != PMI_FirstGPR)
785 LLT SrcTy = MRI.getType(MI.getOperand(MI.getNumOperands()-1).getReg());
786 // UNMERGE into scalars from a vector should always use FPR.
787 // Likewise if any of the uses are FP instructions.
788 if (SrcTy.isVector() || SrcTy == LLT::scalar(128) ||
789 any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
790 [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); })) {
791 // Set the register bank of every operand to FPR.
792 for (unsigned Idx = 0, NumOperands = MI.getNumOperands();
793 Idx < NumOperands; ++Idx)
794 OpRegBankIdx[Idx] = PMI_FirstFPR;
798 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
799 // Destination and source need to be FPRs.
800 OpRegBankIdx[0] = PMI_FirstFPR;
801 OpRegBankIdx[1] = PMI_FirstFPR;
803 // Index needs to be a GPR.
804 OpRegBankIdx[2] = PMI_FirstGPR;
806 case TargetOpcode::G_INSERT_VECTOR_ELT:
807 OpRegBankIdx[0] = PMI_FirstFPR;
808 OpRegBankIdx[1] = PMI_FirstFPR;
810 // The element may be either a GPR or FPR. Preserve that behaviour.
811 if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
812 OpRegBankIdx[2] = PMI_FirstFPR;
814 OpRegBankIdx[2] = PMI_FirstGPR;
816 // Index needs to be a GPR.
817 OpRegBankIdx[3] = PMI_FirstGPR;
819 case TargetOpcode::G_EXTRACT: {
820 // For s128 sources we have to use fpr.
821 LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
822 if (SrcTy.getSizeInBits() == 128) {
823 OpRegBankIdx[0] = PMI_FirstFPR;
824 OpRegBankIdx[1] = PMI_FirstFPR;
828 case TargetOpcode::G_BUILD_VECTOR:
829 // If the first source operand belongs to a FPR register bank, then make
830 // sure that we preserve that.
831 if (OpRegBankIdx[1] != PMI_FirstGPR)
833 Register VReg = MI.getOperand(1).getReg();
837 // Get the instruction that defined the source operand reg, and check if
838 // it's a floating point operation. Or, if it's a type like s16 which
839 // doesn't have a exact size gpr register class.
840 MachineInstr *DefMI = MRI.getVRegDef(VReg);
841 unsigned DefOpc = DefMI->getOpcode();
842 const LLT SrcTy = MRI.getType(VReg);
843 if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
844 SrcTy.getSizeInBits() < 32) {
845 // Have a floating point op.
846 // Make sure every operand gets mapped to a FPR register class.
847 unsigned NumOperands = MI.getNumOperands();
848 for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
849 OpRegBankIdx[Idx] = PMI_FirstFPR;
854 // Finally construct the computed mapping.
855 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
856 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
857 if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
858 auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
859 if (!Mapping->isValid())
860 return getInvalidInstructionMapping();
862 OpdsMapping[Idx] = Mapping;
866 return getInstructionMapping(DefaultMappingID, Cost,
867 getOperandsMapping(OpdsMapping), NumOperands);