]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AArch64 / AArch64RegisterBankInfo.cpp
1 //===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the RegisterBankInfo class for
10 /// AArch64.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
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"
28 #include <algorithm>
29 #include <cassert>
30
31 #define GET_TARGET_REGBANK_IMPL
32 #include "AArch64GenRegisterBank.inc"
33
34 // This file will be TableGen'ed at some point.
35 #include "AArch64GenRegisterBankInfo.def"
36
37 using namespace llvm;
38
39 AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
40     : AArch64GenRegisterBankInfo() {
41   static bool AlreadyInit = false;
42   // We have only one set of register banks, whatever the subtarget
43   // is. Therefore, the initialization of the RegBanks table should be
44   // done only once. Indeed the table of all register banks
45   // (AArch64::RegBanks) is unique in the compiler. At some point, it
46   // will get tablegen'ed and the whole constructor becomes empty.
47   if (AlreadyInit)
48     return;
49   AlreadyInit = true;
50
51   const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
52   (void)RBGPR;
53   assert(&AArch64::GPRRegBank == &RBGPR &&
54          "The order in RegBanks is messed up");
55
56   const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
57   (void)RBFPR;
58   assert(&AArch64::FPRRegBank == &RBFPR &&
59          "The order in RegBanks is messed up");
60
61   const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
62   (void)RBCCR;
63   assert(&AArch64::CCRegBank == &RBCCR && "The order in RegBanks is messed up");
64
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");
70
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");
79
80   assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
81          "Class not added?");
82   assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
83
84   // Check that the TableGen'ed like file is in sync we our expectations.
85   // First, the Idx.
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");
93 // Now, the content.
94 // Check partial mapping.
95 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)                      \
96   do {                                                                         \
97     assert(                                                                    \
98         checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
99         #Idx " is incorrectly initialized");                                   \
100   } while (false)
101
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);
110
111 // Check value mapping.
112 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset)                              \
113   do {                                                                         \
114     assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size,            \
115                              PartialMappingIdx::PMI_First##RBName, Size,       \
116                              Offset) &&                                        \
117            #RBName #Size " " #Offset " is incorrectly initialized");           \
118   } while (false)
119
120 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
121
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);
130
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)                                      \
134   do {                                                                         \
135     CHECK_VALUEMAP_IMPL(RBName, Size, 0);                                      \
136     CHECK_VALUEMAP_IMPL(RBName, Size, 1);                                      \
137     CHECK_VALUEMAP_IMPL(RBName, Size, 2);                                      \
138   } while (false)
139
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);
147
148 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)                 \
149   do {                                                                         \
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);  \
156     (void)Map;                                                                 \
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");                                 \
165                                                                                \
166   } while (false)
167
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);
176
177 #define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize)                                 \
178   do {                                                                         \
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);               \
184     (void)Map;                                                                 \
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");    \
193                                                                                \
194   } while (false)
195
196   CHECK_VALUEMAP_FPEXT(32, 16);
197   CHECK_VALUEMAP_FPEXT(64, 16);
198   CHECK_VALUEMAP_FPEXT(64, 32);
199   CHECK_VALUEMAP_FPEXT(128, 64);
200
201   assert(verify(TRI) && "Invalid register bank information");
202 }
203
204 unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
205                                            const RegisterBank &B,
206                                            unsigned Size) const {
207   // What do we do with different size?
208   // copy are same size.
209   // Will introduce other hooks for different size:
210   // * extract cost.
211   // * build_sequence cost.
212
213   // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
214   // FIXME: This should be deduced from the scheduling model.
215   if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
216     // FMOVXDr or FMOVWSr.
217     return 5;
218   if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
219     // FMOVDXr or FMOVSWr.
220     return 4;
221
222   return RegisterBankInfo::copyCost(A, B, Size);
223 }
224
225 const RegisterBank &
226 AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
227                                                 LLT) const {
228   switch (RC.getID()) {
229   case AArch64::FPR8RegClassID:
230   case AArch64::FPR16RegClassID:
231   case AArch64::FPR32RegClassID:
232   case AArch64::FPR64RegClassID:
233   case AArch64::FPR128RegClassID:
234   case AArch64::FPR128_loRegClassID:
235   case AArch64::DDRegClassID:
236   case AArch64::DDDRegClassID:
237   case AArch64::DDDDRegClassID:
238   case AArch64::QQRegClassID:
239   case AArch64::QQQRegClassID:
240   case AArch64::QQQQRegClassID:
241     return getRegBank(AArch64::FPRRegBankID);
242   case AArch64::GPR32commonRegClassID:
243   case AArch64::GPR32RegClassID:
244   case AArch64::GPR32spRegClassID:
245   case AArch64::GPR32sponlyRegClassID:
246   case AArch64::GPR32argRegClassID:
247   case AArch64::GPR32allRegClassID:
248   case AArch64::GPR64commonRegClassID:
249   case AArch64::GPR64RegClassID:
250   case AArch64::GPR64spRegClassID:
251   case AArch64::GPR64sponlyRegClassID:
252   case AArch64::GPR64argRegClassID:
253   case AArch64::GPR64allRegClassID:
254   case AArch64::GPR64noipRegClassID:
255   case AArch64::GPR64common_and_GPR64noipRegClassID:
256   case AArch64::GPR64noip_and_tcGPR64RegClassID:
257   case AArch64::tcGPR64RegClassID:
258   case AArch64::WSeqPairsClassRegClassID:
259   case AArch64::XSeqPairsClassRegClassID:
260     return getRegBank(AArch64::GPRRegBankID);
261   case AArch64::CCRRegClassID:
262     return getRegBank(AArch64::CCRegBankID);
263   default:
264     llvm_unreachable("Register class not supported");
265   }
266 }
267
268 RegisterBankInfo::InstructionMappings
269 AArch64RegisterBankInfo::getInstrAlternativeMappings(
270     const MachineInstr &MI) const {
271   const MachineFunction &MF = *MI.getParent()->getParent();
272   const TargetSubtargetInfo &STI = MF.getSubtarget();
273   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
274   const MachineRegisterInfo &MRI = MF.getRegInfo();
275
276   switch (MI.getOpcode()) {
277   case TargetOpcode::G_OR: {
278     // 32 and 64-bit or can be mapped on either FPR or
279     // GPR for the same cost.
280     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
281     if (Size != 32 && Size != 64)
282       break;
283
284     // If the instruction has any implicit-defs or uses,
285     // do not mess with it.
286     if (MI.getNumOperands() != 3)
287       break;
288     InstructionMappings AltMappings;
289     const InstructionMapping &GPRMapping = getInstructionMapping(
290         /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
291         /*NumOperands*/ 3);
292     const InstructionMapping &FPRMapping = getInstructionMapping(
293         /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
294         /*NumOperands*/ 3);
295
296     AltMappings.push_back(&GPRMapping);
297     AltMappings.push_back(&FPRMapping);
298     return AltMappings;
299   }
300   case TargetOpcode::G_BITCAST: {
301     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
302     if (Size != 32 && Size != 64)
303       break;
304
305     // If the instruction has any implicit-defs or uses,
306     // do not mess with it.
307     if (MI.getNumOperands() != 2)
308       break;
309
310     InstructionMappings AltMappings;
311     const InstructionMapping &GPRMapping = getInstructionMapping(
312         /*ID*/ 1, /*Cost*/ 1,
313         getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
314         /*NumOperands*/ 2);
315     const InstructionMapping &FPRMapping = getInstructionMapping(
316         /*ID*/ 2, /*Cost*/ 1,
317         getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
318         /*NumOperands*/ 2);
319     const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
320         /*ID*/ 3,
321         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
322         getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
323         /*NumOperands*/ 2);
324     const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
325         /*ID*/ 3,
326         /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
327         getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
328         /*NumOperands*/ 2);
329
330     AltMappings.push_back(&GPRMapping);
331     AltMappings.push_back(&FPRMapping);
332     AltMappings.push_back(&GPRToFPRMapping);
333     AltMappings.push_back(&FPRToGPRMapping);
334     return AltMappings;
335   }
336   case TargetOpcode::G_LOAD: {
337     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
338     if (Size != 64)
339       break;
340
341     // If the instruction has any implicit-defs or uses,
342     // do not mess with it.
343     if (MI.getNumOperands() != 2)
344       break;
345
346     InstructionMappings AltMappings;
347     const InstructionMapping &GPRMapping = getInstructionMapping(
348         /*ID*/ 1, /*Cost*/ 1,
349         getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
350                             // Addresses are GPR 64-bit.
351                             getValueMapping(PMI_FirstGPR, 64)}),
352         /*NumOperands*/ 2);
353     const InstructionMapping &FPRMapping = getInstructionMapping(
354         /*ID*/ 2, /*Cost*/ 1,
355         getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
356                             // Addresses are GPR 64-bit.
357                             getValueMapping(PMI_FirstGPR, 64)}),
358         /*NumOperands*/ 2);
359
360     AltMappings.push_back(&GPRMapping);
361     AltMappings.push_back(&FPRMapping);
362     return AltMappings;
363   }
364   default:
365     break;
366   }
367   return RegisterBankInfo::getInstrAlternativeMappings(MI);
368 }
369
370 void AArch64RegisterBankInfo::applyMappingImpl(
371     const OperandsMapper &OpdMapper) const {
372   switch (OpdMapper.getMI().getOpcode()) {
373   case TargetOpcode::G_OR:
374   case TargetOpcode::G_BITCAST:
375   case TargetOpcode::G_LOAD:
376     // Those ID must match getInstrAlternativeMappings.
377     assert((OpdMapper.getInstrMapping().getID() >= 1 &&
378             OpdMapper.getInstrMapping().getID() <= 4) &&
379            "Don't know how to handle that ID");
380     return applyDefaultMapping(OpdMapper);
381   default:
382     llvm_unreachable("Don't know how to handle that operation");
383   }
384 }
385
386 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
387 /// having only floating-point operands.
388 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
389   switch (Opc) {
390   case TargetOpcode::G_FADD:
391   case TargetOpcode::G_FSUB:
392   case TargetOpcode::G_FMUL:
393   case TargetOpcode::G_FMA:
394   case TargetOpcode::G_FDIV:
395   case TargetOpcode::G_FCONSTANT:
396   case TargetOpcode::G_FPEXT:
397   case TargetOpcode::G_FPTRUNC:
398   case TargetOpcode::G_FCEIL:
399   case TargetOpcode::G_FFLOOR:
400   case TargetOpcode::G_FNEARBYINT:
401   case TargetOpcode::G_FNEG:
402   case TargetOpcode::G_FCOS:
403   case TargetOpcode::G_FSIN:
404   case TargetOpcode::G_FLOG10:
405   case TargetOpcode::G_FLOG:
406   case TargetOpcode::G_FLOG2:
407   case TargetOpcode::G_FSQRT:
408   case TargetOpcode::G_FABS:
409   case TargetOpcode::G_FEXP:
410   case TargetOpcode::G_FRINT:
411   case TargetOpcode::G_INTRINSIC_TRUNC:
412   case TargetOpcode::G_INTRINSIC_ROUND:
413     return true;
414   }
415   return false;
416 }
417
418 const RegisterBankInfo::InstructionMapping &
419 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
420     const MachineInstr &MI) const {
421   const unsigned Opc = MI.getOpcode();
422   const MachineFunction &MF = *MI.getParent()->getParent();
423   const MachineRegisterInfo &MRI = MF.getRegInfo();
424
425   unsigned NumOperands = MI.getNumOperands();
426   assert(NumOperands <= 3 &&
427          "This code is for instructions with 3 or less operands");
428
429   LLT Ty = MRI.getType(MI.getOperand(0).getReg());
430   unsigned Size = Ty.getSizeInBits();
431   bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
432
433   PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
434
435 #ifndef NDEBUG
436   // Make sure all the operands are using similar size and type.
437   // Should probably be checked by the machine verifier.
438   // This code won't catch cases where the number of lanes is
439   // different between the operands.
440   // If we want to go to that level of details, it is probably
441   // best to check that the types are the same, period.
442   // Currently, we just check that the register banks are the same
443   // for each types.
444   for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
445     LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
446     assert(
447         AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
448             RBIdx, OpTy.getSizeInBits()) ==
449             AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
450         "Operand has incompatible size");
451     bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
452     (void)OpIsFPR;
453     assert(IsFPR == OpIsFPR && "Operand has incompatible type");
454   }
455 #endif // End NDEBUG.
456
457   return getInstructionMapping(DefaultMappingID, 1,
458                                getValueMapping(RBIdx, Size), NumOperands);
459 }
460
461 bool AArch64RegisterBankInfo::hasFPConstraints(
462     const MachineInstr &MI, const MachineRegisterInfo &MRI,
463     const TargetRegisterInfo &TRI) const {
464   unsigned Op = MI.getOpcode();
465
466   // Do we have an explicit floating point instruction?
467   if (isPreISelGenericFloatingPointOpcode(Op))
468     return true;
469
470   // No. Check if we have a copy-like instruction. If we do, then we could
471   // still be fed by floating point instructions.
472   if (Op != TargetOpcode::COPY && !MI.isPHI())
473     return false;
474
475   // MI is copy-like. Return true if it outputs an FPR.
476   return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) ==
477          &AArch64::FPRRegBank;
478 }
479
480 bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
481                                          const MachineRegisterInfo &MRI,
482                                          const TargetRegisterInfo &TRI) const {
483   switch (MI.getOpcode()) {
484   case TargetOpcode::G_FPTOSI:
485   case TargetOpcode::G_FPTOUI:
486   case TargetOpcode::G_FCMP:
487     return true;
488   default:
489     break;
490   }
491   return hasFPConstraints(MI, MRI, TRI);
492 }
493
494 bool AArch64RegisterBankInfo::onlyDefinesFP(
495     const MachineInstr &MI, const MachineRegisterInfo &MRI,
496     const TargetRegisterInfo &TRI) const {
497   switch (MI.getOpcode()) {
498   case TargetOpcode::G_SITOFP:
499   case TargetOpcode::G_UITOFP:
500   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
501   case TargetOpcode::G_INSERT_VECTOR_ELT:
502     return true;
503   default:
504     break;
505   }
506   return hasFPConstraints(MI, MRI, TRI);
507 }
508
509 const RegisterBankInfo::InstructionMapping &
510 AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
511   const unsigned Opc = MI.getOpcode();
512
513   // Try the default logic for non-generic instructions that are either copies
514   // or already have some operands assigned to banks.
515   if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
516       Opc == TargetOpcode::G_PHI) {
517     const RegisterBankInfo::InstructionMapping &Mapping =
518         getInstrMappingImpl(MI);
519     if (Mapping.isValid())
520       return Mapping;
521   }
522
523   const MachineFunction &MF = *MI.getParent()->getParent();
524   const MachineRegisterInfo &MRI = MF.getRegInfo();
525   const TargetSubtargetInfo &STI = MF.getSubtarget();
526   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
527
528   switch (Opc) {
529     // G_{F|S|U}REM are not listed because they are not legal.
530     // Arithmetic ops.
531   case TargetOpcode::G_ADD:
532   case TargetOpcode::G_SUB:
533   case TargetOpcode::G_PTR_ADD:
534   case TargetOpcode::G_MUL:
535   case TargetOpcode::G_SDIV:
536   case TargetOpcode::G_UDIV:
537     // Bitwise ops.
538   case TargetOpcode::G_AND:
539   case TargetOpcode::G_OR:
540   case TargetOpcode::G_XOR:
541     // Floating point ops.
542   case TargetOpcode::G_FADD:
543   case TargetOpcode::G_FSUB:
544   case TargetOpcode::G_FMUL:
545   case TargetOpcode::G_FDIV:
546     return getSameKindOfOperandsMapping(MI);
547   case TargetOpcode::G_FPEXT: {
548     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
549     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
550     return getInstructionMapping(
551         DefaultMappingID, /*Cost*/ 1,
552         getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
553         /*NumOperands*/ 2);
554   }
555     // Shifts.
556   case TargetOpcode::G_SHL:
557   case TargetOpcode::G_LSHR:
558   case TargetOpcode::G_ASHR: {
559     LLT ShiftAmtTy = MRI.getType(MI.getOperand(2).getReg());
560     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
561     if (ShiftAmtTy.getSizeInBits() == 64 && SrcTy.getSizeInBits() == 32)
562       return getInstructionMapping(DefaultMappingID, 1,
563                                    &ValMappings[Shift64Imm], 3);
564     return getSameKindOfOperandsMapping(MI);
565   }
566   case TargetOpcode::COPY: {
567     Register DstReg = MI.getOperand(0).getReg();
568     Register SrcReg = MI.getOperand(1).getReg();
569     // Check if one of the register is not a generic register.
570     if ((Register::isPhysicalRegister(DstReg) ||
571          !MRI.getType(DstReg).isValid()) ||
572         (Register::isPhysicalRegister(SrcReg) ||
573          !MRI.getType(SrcReg).isValid())) {
574       const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
575       const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
576       if (!DstRB)
577         DstRB = SrcRB;
578       else if (!SrcRB)
579         SrcRB = DstRB;
580       // If both RB are null that means both registers are generic.
581       // We shouldn't be here.
582       assert(DstRB && SrcRB && "Both RegBank were nullptr");
583       unsigned Size = getSizeInBits(DstReg, MRI, TRI);
584       return getInstructionMapping(
585           DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
586           getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
587           // We only care about the mapping of the destination.
588           /*NumOperands*/ 1);
589     }
590     // Both registers are generic, use G_BITCAST.
591     LLVM_FALLTHROUGH;
592   }
593   case TargetOpcode::G_BITCAST: {
594     LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
595     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
596     unsigned Size = DstTy.getSizeInBits();
597     bool DstIsGPR = !DstTy.isVector() && DstTy.getSizeInBits() <= 64;
598     bool SrcIsGPR = !SrcTy.isVector() && SrcTy.getSizeInBits() <= 64;
599     const RegisterBank &DstRB =
600         DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
601     const RegisterBank &SrcRB =
602         SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
603     return getInstructionMapping(
604         DefaultMappingID, copyCost(DstRB, SrcRB, Size),
605         getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
606         // We only care about the mapping of the destination for COPY.
607         /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 2 : 1);
608   }
609   default:
610     break;
611   }
612
613   unsigned NumOperands = MI.getNumOperands();
614
615   // Track the size and bank of each register.  We don't do partial mappings.
616   SmallVector<unsigned, 4> OpSize(NumOperands);
617   SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
618   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
619     auto &MO = MI.getOperand(Idx);
620     if (!MO.isReg() || !MO.getReg())
621       continue;
622
623     LLT Ty = MRI.getType(MO.getReg());
624     OpSize[Idx] = Ty.getSizeInBits();
625
626     // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
627     // For floating-point instructions, scalars go in FPRs.
628     if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc) ||
629         Ty.getSizeInBits() > 64)
630       OpRegBankIdx[Idx] = PMI_FirstFPR;
631     else
632       OpRegBankIdx[Idx] = PMI_FirstGPR;
633   }
634
635   unsigned Cost = 1;
636   // Some of the floating-point instructions have mixed GPR and FPR operands:
637   // fine-tune the computed mapping.
638   switch (Opc) {
639   case TargetOpcode::G_TRUNC: {
640     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
641     if (!SrcTy.isVector() && SrcTy.getSizeInBits() == 128)
642       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
643     break;
644   }
645   case TargetOpcode::G_SITOFP:
646   case TargetOpcode::G_UITOFP:
647     if (MRI.getType(MI.getOperand(0).getReg()).isVector())
648       break;
649     OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
650     break;
651   case TargetOpcode::G_FPTOSI:
652   case TargetOpcode::G_FPTOUI:
653     if (MRI.getType(MI.getOperand(0).getReg()).isVector())
654       break;
655     OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
656     break;
657   case TargetOpcode::G_FCMP:
658     OpRegBankIdx = {PMI_FirstGPR,
659                     /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
660     break;
661   case TargetOpcode::G_BITCAST:
662     // This is going to be a cross register bank copy and this is expensive.
663     if (OpRegBankIdx[0] != OpRegBankIdx[1])
664       Cost = copyCost(
665           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
666           *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
667           OpSize[0]);
668     break;
669   case TargetOpcode::G_LOAD:
670     // Loading in vector unit is slightly more expensive.
671     // This is actually only true for the LD1R and co instructions,
672     // but anyway for the fast mode this number does not matter and
673     // for the greedy mode the cost of the cross bank copy will
674     // offset this number.
675     // FIXME: Should be derived from the scheduling model.
676     if (OpRegBankIdx[0] != PMI_FirstGPR)
677       Cost = 2;
678     else
679       // Check if that load feeds fp instructions.
680       // In that case, we want the default mapping to be on FPR
681       // instead of blind map every scalar to GPR.
682       for (const MachineInstr &UseMI :
683            MRI.use_instructions(MI.getOperand(0).getReg())) {
684         // If we have at least one direct use in a FP instruction,
685         // assume this was a floating point load in the IR.
686         // If it was not, we would have had a bitcast before
687         // reaching that instruction.
688         if (onlyUsesFP(UseMI, MRI, TRI)) {
689           OpRegBankIdx[0] = PMI_FirstFPR;
690           break;
691         }
692       }
693     break;
694   case TargetOpcode::G_STORE:
695     // Check if that store is fed by fp instructions.
696     if (OpRegBankIdx[0] == PMI_FirstGPR) {
697       Register VReg = MI.getOperand(0).getReg();
698       if (!VReg)
699         break;
700       MachineInstr *DefMI = MRI.getVRegDef(VReg);
701       if (onlyDefinesFP(*DefMI, MRI, TRI))
702         OpRegBankIdx[0] = PMI_FirstFPR;
703       break;
704     }
705     break;
706   case TargetOpcode::G_SELECT: {
707     // If the destination is FPR, preserve that.
708     if (OpRegBankIdx[0] != PMI_FirstGPR)
709       break;
710
711     // If we're taking in vectors, we have no choice but to put everything on
712     // FPRs, except for the condition. The condition must always be on a GPR.
713     LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
714     if (SrcTy.isVector()) {
715       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
716       break;
717     }
718
719     // Try to minimize the number of copies. If we have more floating point
720     // constrained values than not, then we'll put everything on FPR. Otherwise,
721     // everything has to be on GPR.
722     unsigned NumFP = 0;
723
724     // Check if the uses of the result always produce floating point values.
725     //
726     // For example:
727     //
728     // %z = G_SELECT %cond %x %y
729     // fpr = G_FOO %z ...
730     if (any_of(
731             MRI.use_instructions(MI.getOperand(0).getReg()),
732             [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); }))
733       ++NumFP;
734
735     // Check if the defs of the source values always produce floating point
736     // values.
737     //
738     // For example:
739     //
740     // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
741     // %z = G_SELECT %cond %x %y
742     //
743     // Also check whether or not the sources have already been decided to be
744     // FPR. Keep track of this.
745     //
746     // This doesn't check the condition, since it's just whatever is in NZCV.
747     // This isn't passed explicitly in a register to fcsel/csel.
748     for (unsigned Idx = 2; Idx < 4; ++Idx) {
749       Register VReg = MI.getOperand(Idx).getReg();
750       MachineInstr *DefMI = MRI.getVRegDef(VReg);
751       if (getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
752           onlyDefinesFP(*DefMI, MRI, TRI))
753         ++NumFP;
754     }
755
756     // If we have more FP constraints than not, then move everything over to
757     // FPR.
758     if (NumFP >= 2)
759       OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
760
761     break;
762   }
763   case TargetOpcode::G_UNMERGE_VALUES: {
764     // If the first operand belongs to a FPR register bank, then make sure that
765     // we preserve that.
766     if (OpRegBankIdx[0] != PMI_FirstGPR)
767       break;
768
769     LLT SrcTy = MRI.getType(MI.getOperand(MI.getNumOperands()-1).getReg());
770     // UNMERGE into scalars from a vector should always use FPR.
771     // Likewise if any of the uses are FP instructions.
772     if (SrcTy.isVector() || SrcTy == LLT::scalar(128) ||
773         any_of(MRI.use_instructions(MI.getOperand(0).getReg()),
774                [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); })) {
775       // Set the register bank of every operand to FPR.
776       for (unsigned Idx = 0, NumOperands = MI.getNumOperands();
777            Idx < NumOperands; ++Idx)
778         OpRegBankIdx[Idx] = PMI_FirstFPR;
779     }
780     break;
781   }
782   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
783     // Destination and source need to be FPRs.
784     OpRegBankIdx[0] = PMI_FirstFPR;
785     OpRegBankIdx[1] = PMI_FirstFPR;
786
787     // Index needs to be a GPR.
788     OpRegBankIdx[2] = PMI_FirstGPR;
789     break;
790   case TargetOpcode::G_INSERT_VECTOR_ELT:
791     OpRegBankIdx[0] = PMI_FirstFPR;
792     OpRegBankIdx[1] = PMI_FirstFPR;
793
794     // The element may be either a GPR or FPR. Preserve that behaviour.
795     if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
796       OpRegBankIdx[2] = PMI_FirstFPR;
797     else
798       OpRegBankIdx[2] = PMI_FirstGPR;
799
800     // Index needs to be a GPR.
801     OpRegBankIdx[3] = PMI_FirstGPR;
802     break;
803   case TargetOpcode::G_EXTRACT: {
804     // For s128 sources we have to use fpr.
805     LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
806     if (SrcTy.getSizeInBits() == 128) {
807       OpRegBankIdx[0] = PMI_FirstFPR;
808       OpRegBankIdx[1] = PMI_FirstFPR;
809     }
810     break;
811   }
812   case TargetOpcode::G_BUILD_VECTOR:
813     // If the first source operand belongs to a FPR register bank, then make
814     // sure that we preserve that.
815     if (OpRegBankIdx[1] != PMI_FirstGPR)
816       break;
817     Register VReg = MI.getOperand(1).getReg();
818     if (!VReg)
819       break;
820
821     // Get the instruction that defined the source operand reg, and check if
822     // it's a floating point operation. Or, if it's a type like s16 which
823     // doesn't have a exact size gpr register class.
824     MachineInstr *DefMI = MRI.getVRegDef(VReg);
825     unsigned DefOpc = DefMI->getOpcode();
826     const LLT SrcTy = MRI.getType(VReg);
827     if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
828         SrcTy.getSizeInBits() < 32) {
829       // Have a floating point op.
830       // Make sure every operand gets mapped to a FPR register class.
831       unsigned NumOperands = MI.getNumOperands();
832       for (unsigned Idx = 0; Idx < NumOperands; ++Idx)
833         OpRegBankIdx[Idx] = PMI_FirstFPR;
834     }
835     break;
836   }
837
838   // Finally construct the computed mapping.
839   SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
840   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
841     if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
842       auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
843       if (!Mapping->isValid())
844         return getInvalidInstructionMapping();
845
846       OpdsMapping[Idx] = Mapping;
847     }
848   }
849
850   return getInstructionMapping(DefaultMappingID, Cost,
851                                getOperandsMapping(OpdsMapping), NumOperands);
852 }