25 #include "AArch64GenRegisterBankInfo.def"
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "You shouldn't build this"
35 static bool AlreadyInit =
false;
48 "The order in RegBanks is messed up");
53 "The order in RegBanks is messed up");
58 "The order in RegBanks is messed up");
63 "Subclass not added?");
64 assert(RBGPR.
getSize() == 64 &&
"GPRs should hold up to 64-bit");
69 "Subclass not added?");
71 "Subclass not added?");
73 "FPRs should hold up to 512-bit via QQQQ sequence");
77 assert(RBCCR.
getSize() == 32 &&
"CCR should hold up to 32-bit");
81 assert(AArch64::PartialMappingIdx::PMI_GPR32 ==
82 AArch64::PartialMappingIdx::PMI_FirstGPR &&
83 "GPR32 index not first in the GPR list");
84 assert(AArch64::PartialMappingIdx::PMI_GPR64 ==
85 AArch64::PartialMappingIdx::PMI_LastGPR &&
86 "GPR64 index not last in the GPR list");
87 assert(AArch64::PartialMappingIdx::PMI_FirstGPR <=
88 AArch64::PartialMappingIdx::PMI_LastGPR &&
89 "GPR list is backward");
90 assert(AArch64::PartialMappingIdx::PMI_FPR32 ==
91 AArch64::PartialMappingIdx::PMI_FirstFPR &&
92 "FPR32 index not first in the FPR list");
93 assert(AArch64::PartialMappingIdx::PMI_FPR512 ==
94 AArch64::PartialMappingIdx::PMI_LastFPR &&
95 "FPR512 index not last in the FPR list");
96 assert(AArch64::PartialMappingIdx::PMI_FirstFPR <=
97 AArch64::PartialMappingIdx::PMI_LastFPR &&
98 "FPR list is backward");
99 assert(AArch64::PartialMappingIdx::PMI_FPR32 + 1 ==
100 AArch64::PartialMappingIdx::PMI_FPR64 &&
101 AArch64::PartialMappingIdx::PMI_FPR64 + 1 ==
102 AArch64::PartialMappingIdx::PMI_FPR128 &&
103 AArch64::PartialMappingIdx::PMI_FPR128 + 1 ==
104 AArch64::PartialMappingIdx::PMI_FPR256 &&
105 AArch64::PartialMappingIdx::PMI_FPR256 + 1 ==
106 AArch64::PartialMappingIdx::PMI_FPR512 &&
107 "FPR indices not properly ordered");
110 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \
112 const PartialMapping &Map = \
113 AArch64::PartMappings[AArch64::PartialMappingIdx::Idx - \
114 AArch64::PartialMappingIdx::PMI_Min]; \
116 assert(Map.StartIdx == ValStartIdx && Map.Length == ValLength && \
117 Map.RegBank == &RB && #Idx " is incorrectly initialized"); \
129 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \
131 unsigned PartialMapBaseIdx = \
132 AArch64::PartialMappingIdx::PMI_##RBName##Size - \
133 AArch64::PartialMappingIdx::PMI_Min; \
134 (void)PartialMapBaseIdx; \
135 const ValueMapping &Map = AArch64::getValueMapping( \
136 AArch64::PartialMappingIdx::PMI_First##RBName, Size)[Offset]; \
138 assert(Map.BreakDown == &AArch64::PartMappings[PartialMapBaseIdx] && \
139 Map.NumBreakDowns == 1 && #RBName #Size \
140 " " #Offset " is incorrectly initialized"); \
143 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
155 #define CHECK_VALUEMAP_3OPS(RBName, Size) \
157 CHECK_VALUEMAP_IMPL(RBName, Size, 0); \
158 CHECK_VALUEMAP_IMPL(RBName, Size, 1); \
159 CHECK_VALUEMAP_IMPL(RBName, Size, 2); \
170 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \
172 unsigned PartialMapDstIdx = \
173 AArch64::PMI_##RBNameDst##Size - AArch64::PMI_Min; \
174 unsigned PartialMapSrcIdx = \
175 AArch64::PMI_##RBNameSrc##Size - AArch64::PMI_Min; \
176 (void) PartialMapDstIdx; \
177 (void) PartialMapSrcIdx; \
178 const ValueMapping *Map = AArch64::getCopyMapping( \
179 AArch64::PMI_First##RBNameDst == AArch64::PMI_FirstGPR, \
180 AArch64::PMI_First##RBNameSrc == AArch64::PMI_FirstGPR, Size); \
182 assert(Map[0].BreakDown == &AArch64::PartMappings[PartialMapDstIdx] && \
183 Map[0].NumBreakDowns == 1 && #RBNameDst #Size \
184 " Dst is incorrectly initialized"); \
185 assert(Map[1].BreakDown == &AArch64::PartMappings[PartialMapSrcIdx] && \
186 Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \
187 " Src is incorrectly initialized"); \
200 assert(
verify(TRI) &&
"Invalid register bank information");
205 unsigned Size)
const {
226 switch (RC.
getID()) {
227 case AArch64::FPR8RegClassID:
228 case AArch64::FPR16RegClassID:
229 case AArch64::FPR32RegClassID:
230 case AArch64::FPR64RegClassID:
231 case AArch64::FPR128RegClassID:
232 case AArch64::FPR128_loRegClassID:
233 case AArch64::DDRegClassID:
234 case AArch64::DDDRegClassID:
235 case AArch64::DDDDRegClassID:
236 case AArch64::QQRegClassID:
237 case AArch64::QQQRegClassID:
238 case AArch64::QQQQRegClassID:
240 case AArch64::GPR32commonRegClassID:
241 case AArch64::GPR32RegClassID:
242 case AArch64::GPR32spRegClassID:
243 case AArch64::GPR32sponlyRegClassID:
244 case AArch64::GPR32allRegClassID:
245 case AArch64::GPR64commonRegClassID:
246 case AArch64::GPR64RegClassID:
247 case AArch64::GPR64spRegClassID:
248 case AArch64::GPR64sponlyRegClassID:
249 case AArch64::GPR64allRegClassID:
250 case AArch64::tcGPR64RegClassID:
251 case AArch64::WSeqPairsClassRegClassID:
252 case AArch64::XSeqPairsClassRegClassID:
254 case AArch64::CCRRegClassID:
270 case TargetOpcode::G_OR: {
274 if (Size != 32 && Size != 64)
295 case TargetOpcode::G_BITCAST: {
297 if (Size != 32 && Size != 64)
308 AArch64::getCopyMapping(
true,
true, Size),
312 AArch64::getCopyMapping(
false,
false, Size),
317 AArch64::getCopyMapping(
false,
true, Size),
322 AArch64::getCopyMapping(
true,
false, Size),
331 case TargetOpcode::G_LOAD: {
367 void AArch64RegisterBankInfo::applyMappingImpl(
370 case TargetOpcode::G_OR:
371 case TargetOpcode::G_BITCAST:
372 case TargetOpcode::G_LOAD: {
376 "Don't know how to handle that ID");
388 case TargetOpcode::G_FADD:
389 case TargetOpcode::G_FSUB:
390 case TargetOpcode::G_FMUL:
391 case TargetOpcode::G_FDIV:
392 case TargetOpcode::G_FCONSTANT:
393 case TargetOpcode::G_FPEXT:
394 case TargetOpcode::G_FPTRUNC:
401 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
const MachineInstr &
MI) {
407 assert(NumOperands <= 3 &&
408 "This code is for instructions with 3 or less operands");
423 for (
unsigned Idx = 1; Idx != NumOperands; ++Idx) {
426 AArch64::getRegBankBaseIdxOffset(Size) &&
427 "Operand has incompatible size");
430 assert(IsFPR == OpIsFPR &&
"Operand has incompatible type");
432 #endif // End NDEBUG.
434 AArch64::PartialMappingIdx RBIdx =
435 IsFPR ? AArch64::PMI_FirstFPR : AArch64::PMI_FirstGPR;
458 case TargetOpcode::G_ADD:
459 case TargetOpcode::G_SUB:
460 case TargetOpcode::G_GEP:
461 case TargetOpcode::G_MUL:
462 case TargetOpcode::G_SDIV:
463 case TargetOpcode::G_UDIV:
465 case TargetOpcode::G_AND:
466 case TargetOpcode::G_OR:
467 case TargetOpcode::G_XOR:
469 case TargetOpcode::G_SHL:
470 case TargetOpcode::G_LSHR:
471 case TargetOpcode::G_ASHR:
473 case TargetOpcode::G_FADD:
474 case TargetOpcode::G_FSUB:
475 case TargetOpcode::G_FMUL:
476 case TargetOpcode::G_FDIV:
477 return getSameKindOfOperandsMapping(MI);
478 case TargetOpcode::G_BITCAST: {
489 AArch64::getCopyMapping(DstIsGPR, SrcIsGPR, Size),
492 case TargetOpcode::G_SEQUENCE:
505 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
516 OpRegBankIdx[Idx] = AArch64::PMI_FirstFPR;
518 OpRegBankIdx[Idx] = AArch64::PMI_FirstGPR;
525 case TargetOpcode::G_SITOFP:
526 case TargetOpcode::G_UITOFP: {
527 OpRegBankIdx = {AArch64::PMI_FirstFPR, AArch64::PMI_FirstGPR};
530 case TargetOpcode::G_FPTOSI:
531 case TargetOpcode::G_FPTOUI: {
532 OpRegBankIdx = {AArch64::PMI_FirstGPR, AArch64::PMI_FirstFPR};
535 case TargetOpcode::G_FCMP: {
536 OpRegBankIdx = {AArch64::PMI_FirstGPR,
537 AArch64::PMI_None, AArch64::PMI_FirstFPR,
538 AArch64::PMI_FirstFPR};
541 case TargetOpcode::G_BITCAST: {
543 if (OpRegBankIdx[0] != OpRegBankIdx[1])
545 copyCost(*AArch64::PartMappings[OpRegBankIdx[0]].RegBank,
546 *AArch64::PartMappings[OpRegBankIdx[1]].RegBank, OpSize[0]);
549 case TargetOpcode::G_LOAD: {
556 if (OpRegBankIdx[0] >= AArch64::PMI_FirstFPR)
565 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx)
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
void setOperandsMapping(const ValueMapping *OpdsMapping)
Set the mapping for all the operands.
RegisterBank ** RegBanks
Hold the set of supported register banks.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
const ValueMapping & getValueMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const
Methods to get a uniquely generated ValueMapping.
class llvm::RegisterBankInfo GPR
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getID() const
Return the register class ID number.
#define CHECK_VALUEMAP(RBName, Size)
This file declares the targeting of the RegisterBankInfo class for AArch64.
Holds all the information related to register banks.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
#define CHECK_VALUEMAP_3OPS(RBName, Size)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments, on Darwin.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Methods to get a uniquely generated array of ValueMapping.
InstructionMapping getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
unsigned const MachineRegisterInfo * MRI
static unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
Get the size in bits of Reg.
const MachineOperand & getOperand(unsigned i) const
Conditional register: NZCV.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const override
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)
This class implements the register bank concept.
static bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel...
const InstructionMapping & getInstrMapping() const
The final mapping of the instruction.
bool isValid() const
Check whether this object is valid.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
void emplace_back(ArgTypes &&...Args)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getSize() const
Get the maximal size in bits that fits in this register bank.
unsigned getID() const
Get the ID.
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
unsigned getReg() const
getReg - Returns the register number.
Floating Point/Vector Registers: B, H, S, D, Q.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)
General Purpose Registers: W, X.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override
Get a register bank that covers RC.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
MachineInstr & getMI() const
Getters.