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