• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- AArch64RegisterBankInfo.cpp -------------------------------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements the targeting of the RegisterBankInfo class for
11 /// AArch64.
12 /// \todo This should be generated by TableGen.
13 //===----------------------------------------------------------------------===//
14 
15 #include "AArch64RegisterBankInfo.h"
16 #include "AArch64InstrInfo.h" // For XXXRegClassID.
17 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
18 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
20 #include "llvm/Target/TargetSubtargetInfo.h"
21 
22 using namespace llvm;
23 
24 #ifndef LLVM_BUILD_GLOBAL_ISEL
25 #error "You shouldn't build this"
26 #endif
27 
AArch64RegisterBankInfo(const TargetRegisterInfo & TRI)28 AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
29     : RegisterBankInfo(AArch64::NumRegisterBanks) {
30   // Initialize the GPR bank.
31   createRegisterBank(AArch64::GPRRegBankID, "GPR");
32   // The GPR register bank is fully defined by all the registers in
33   // GR64all + its subclasses.
34   addRegBankCoverage(AArch64::GPRRegBankID, AArch64::GPR64allRegClassID, TRI);
35   const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
36   (void)RBGPR;
37   assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
38          "Subclass not added?");
39   assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
40 
41   // Initialize the FPR bank.
42   createRegisterBank(AArch64::FPRRegBankID, "FPR");
43   // The FPR register bank is fully defined by all the registers in
44   // GR64all + its subclasses.
45   addRegBankCoverage(AArch64::FPRRegBankID, AArch64::QQQQRegClassID, TRI);
46   const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
47   (void)RBFPR;
48   assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
49          "Subclass not added?");
50   assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
51          "Subclass not added?");
52   assert(RBFPR.getSize() == 512 &&
53          "FPRs should hold up to 512-bit via QQQQ sequence");
54 
55   // Initialize the CCR bank.
56   createRegisterBank(AArch64::CCRRegBankID, "CCR");
57   addRegBankCoverage(AArch64::CCRRegBankID, AArch64::CCRRegClassID, TRI);
58   const RegisterBank &RBCCR = getRegBank(AArch64::CCRRegBankID);
59   (void)RBCCR;
60   assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
61          "Class not added?");
62   assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
63 
64   assert(verify(TRI) && "Invalid register bank information");
65 }
66 
copyCost(const RegisterBank & A,const RegisterBank & B,unsigned Size) const67 unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
68                                            const RegisterBank &B,
69                                            unsigned Size) const {
70   // What do we do with different size?
71   // copy are same size.
72   // Will introduce other hooks for different size:
73   // * extract cost.
74   // * build_sequence cost.
75   // TODO: Add more accurate cost for FPR to/from GPR.
76   return RegisterBankInfo::copyCost(A, B, Size);
77 }
78 
getRegBankFromRegClass(const TargetRegisterClass & RC) const79 const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
80     const TargetRegisterClass &RC) const {
81   switch (RC.getID()) {
82   case AArch64::FPR8RegClassID:
83   case AArch64::FPR16RegClassID:
84   case AArch64::FPR32RegClassID:
85   case AArch64::FPR64RegClassID:
86   case AArch64::FPR128RegClassID:
87   case AArch64::FPR128_loRegClassID:
88   case AArch64::DDRegClassID:
89   case AArch64::DDDRegClassID:
90   case AArch64::DDDDRegClassID:
91   case AArch64::QQRegClassID:
92   case AArch64::QQQRegClassID:
93   case AArch64::QQQQRegClassID:
94     return getRegBank(AArch64::FPRRegBankID);
95   case AArch64::GPR32commonRegClassID:
96   case AArch64::GPR32RegClassID:
97   case AArch64::GPR32spRegClassID:
98   case AArch64::GPR32sponlyRegClassID:
99   case AArch64::GPR32allRegClassID:
100   case AArch64::GPR64commonRegClassID:
101   case AArch64::GPR64RegClassID:
102   case AArch64::GPR64spRegClassID:
103   case AArch64::GPR64sponlyRegClassID:
104   case AArch64::GPR64allRegClassID:
105   case AArch64::tcGPR64RegClassID:
106   case AArch64::WSeqPairsClassRegClassID:
107   case AArch64::XSeqPairsClassRegClassID:
108     return getRegBank(AArch64::GPRRegBankID);
109   case AArch64::CCRRegClassID:
110     return getRegBank(AArch64::CCRRegBankID);
111   default:
112     llvm_unreachable("Register class not supported");
113   }
114 }
115 
116 RegisterBankInfo::InstructionMappings
getInstrAlternativeMappings(const MachineInstr & MI) const117 AArch64RegisterBankInfo::getInstrAlternativeMappings(
118     const MachineInstr &MI) const {
119   switch (MI.getOpcode()) {
120   case TargetOpcode::G_OR: {
121     // 32 and 64-bit or can be mapped on either FPR or
122     // GPR for the same cost.
123     const MachineFunction &MF = *MI.getParent()->getParent();
124     const TargetSubtargetInfo &STI = MF.getSubtarget();
125     const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
126     const MachineRegisterInfo &MRI = MF.getRegInfo();
127 
128     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
129     if (Size != 32 && Size != 64)
130       break;
131 
132     // If the instruction has any implicit-defs or uses,
133     // do not mess with it.
134     if (MI.getNumOperands() != 3)
135       break;
136     InstructionMappings AltMappings;
137     InstructionMapping GPRMapping(/*ID*/ 1, /*Cost*/ 1, /*NumOperands*/ 3);
138     InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
139     for (unsigned Idx = 0; Idx != 3; ++Idx) {
140       GPRMapping.setOperandMapping(Idx, Size,
141                                    getRegBank(AArch64::GPRRegBankID));
142       FPRMapping.setOperandMapping(Idx, Size,
143                                    getRegBank(AArch64::FPRRegBankID));
144     }
145     AltMappings.emplace_back(std::move(GPRMapping));
146     AltMappings.emplace_back(std::move(FPRMapping));
147     return AltMappings;
148   }
149   default:
150     break;
151   }
152   return RegisterBankInfo::getInstrAlternativeMappings(MI);
153 }
154 
applyMappingImpl(const OperandsMapper & OpdMapper) const155 void AArch64RegisterBankInfo::applyMappingImpl(
156     const OperandsMapper &OpdMapper) const {
157   switch (OpdMapper.getMI().getOpcode()) {
158   case TargetOpcode::G_OR: {
159     // Those ID must match getInstrAlternativeMappings.
160     assert((OpdMapper.getInstrMapping().getID() == 1 ||
161             OpdMapper.getInstrMapping().getID() == 2) &&
162            "Don't know how to handle that ID");
163     return applyDefaultMapping(OpdMapper);
164   }
165   default:
166     llvm_unreachable("Don't know how to handle that operation");
167   }
168 }
169