mirror of
https://github.com/intel/llvm.git
synced 2026-02-02 10:08:59 +08:00
[aarch64][globalisel] Move data into <Target>GenRegisterBankInfo. NFC.
Summary: Depends on D27809 Reviewers: t.p.northover, rovka, qcolombet, ab Subscribers: aditya_nandakumar, aemerson, rengolin, vkalintiris, dberris, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D27976 llvm-svn: 291897
This commit is contained in:
@@ -144,26 +144,12 @@ const uint32_t CCRCoverageData[] = {
|
||||
RegisterBank GPRRegBank(AArch64::GPRRegBankID, "GPR", 64, GPRCoverageData);
|
||||
RegisterBank FPRRegBank(AArch64::FPRRegBankID, "FPR", 512, FPRCoverageData);
|
||||
RegisterBank CCRRegBank(AArch64::CCRRegBankID, "CCR", 32, CCRCoverageData);
|
||||
} // end namespace AArch64
|
||||
|
||||
RegisterBank *RegBanks[] = {&GPRRegBank, &FPRRegBank, &CCRRegBank};
|
||||
|
||||
// PartialMappings.
|
||||
enum PartialMappingIdx {
|
||||
PMI_None = -1,
|
||||
PMI_GPR32 = 1,
|
||||
PMI_GPR64,
|
||||
PMI_FPR32,
|
||||
PMI_FPR64,
|
||||
PMI_FPR128,
|
||||
PMI_FPR256,
|
||||
PMI_FPR512,
|
||||
PMI_FirstGPR = PMI_GPR32,
|
||||
PMI_LastGPR = PMI_GPR64,
|
||||
PMI_FirstFPR = PMI_FPR32,
|
||||
PMI_LastFPR = PMI_FPR512,
|
||||
PMI_Min = PMI_FirstGPR,
|
||||
};
|
||||
RegisterBank *AArch64GenRegisterBankInfo::RegBanks[] = {
|
||||
&AArch64::GPRRegBank, &AArch64::FPRRegBank, &AArch64::CCRRegBank};
|
||||
|
||||
namespace AArch64 {
|
||||
static unsigned getRegBankBaseIdxOffset(unsigned Size) {
|
||||
assert(Size && "0-sized type!!");
|
||||
// Make anything smaller than 32 gets 32
|
||||
@@ -171,84 +157,76 @@ static unsigned getRegBankBaseIdxOffset(unsigned Size) {
|
||||
// 32 is 0, 64 is 1, 128 is 2, and so on.
|
||||
return Log2_32(Size) - /*Log2_32(32)=*/ 5;
|
||||
}
|
||||
}
|
||||
|
||||
RegisterBankInfo::PartialMapping PartMappings[] {
|
||||
/* StartIdx, Length, RegBank */
|
||||
// 0: GPR 32-bit value.
|
||||
{0, 32, GPRRegBank},
|
||||
// 1: GPR 64-bit value.
|
||||
{0, 64, GPRRegBank},
|
||||
// 2: FPR 32-bit value.
|
||||
{0, 32, FPRRegBank},
|
||||
// 3: FPR 64-bit value.
|
||||
{0, 64, FPRRegBank},
|
||||
// 4: FPR 128-bit value.
|
||||
{0, 128, FPRRegBank},
|
||||
// 5: FPR 256-bit value.
|
||||
{0, 256, FPRRegBank},
|
||||
// 6: FPR 512-bit value.
|
||||
{0, 512, FPRRegBank}
|
||||
};
|
||||
|
||||
enum ValueMappingIdx {
|
||||
First3OpsIdx = 0,
|
||||
Last3OpsIdx = 18,
|
||||
DistanceBetweenRegBanks = 3,
|
||||
FirstCrossRegCpyIdx = 21,
|
||||
LastCrossRegCpyIdx = 27,
|
||||
DistanceBetweenCrossRegCpy = 2
|
||||
};
|
||||
RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
|
||||
/* StartIdx, Length, RegBank */
|
||||
// 0: GPR 32-bit value.
|
||||
{0, 32, AArch64::GPRRegBank},
|
||||
// 1: GPR 64-bit value.
|
||||
{0, 64, AArch64::GPRRegBank},
|
||||
// 2: FPR 32-bit value.
|
||||
{0, 32, AArch64::FPRRegBank},
|
||||
// 3: FPR 64-bit value.
|
||||
{0, 64, AArch64::FPRRegBank},
|
||||
// 4: FPR 128-bit value.
|
||||
{0, 128, AArch64::FPRRegBank},
|
||||
// 5: FPR 256-bit value.
|
||||
{0, 256, AArch64::FPRRegBank},
|
||||
// 6: FPR 512-bit value.
|
||||
{0, 512, AArch64::FPRRegBank}};
|
||||
|
||||
// ValueMappings.
|
||||
RegisterBankInfo::ValueMapping ValMappings[]{
|
||||
RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
|
||||
/* BreakDown, NumBreakDowns */
|
||||
// 3-operands instructions (all binary operations should end up with one of
|
||||
// those mapping).
|
||||
// 0: GPR 32-bit value. <-- This must match First3OpsIdx.
|
||||
{&PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
// 3: GPR 64-bit value.
|
||||
{&PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
// 6: FPR 32-bit value.
|
||||
{&PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
// 9: FPR 64-bit value.
|
||||
{&PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
// 12: FPR 128-bit value.
|
||||
{&PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
|
||||
// 15: FPR 256-bit value.
|
||||
{&PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
|
||||
// 18: FPR 512-bit value. <-- This must match Last3OpsIdx.
|
||||
{&PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
|
||||
// Cross register bank copies.
|
||||
// 21: GPR 32-bit value to FPR 32-bit value. <-- This must match
|
||||
// FirstCrossRegCpyIdx.
|
||||
{&PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
// 23: GPR 64-bit value to FPR 64-bit value.
|
||||
{&PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
// 25: FPR 32-bit value to GPR 32-bit value.
|
||||
{&PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||
// 27: FPR 64-bit value to GPR 64-bit value. <-- This must match
|
||||
// LastCrossRegCpyIdx.
|
||||
{&PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&PartMappings[PMI_GPR64 - PMI_Min], 1}
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}
|
||||
};
|
||||
|
||||
namespace AArch64 {
|
||||
/// Get the pointer to the ValueMapping representing the RegisterBank
|
||||
/// at \p RBIdx with a size of \p Size.
|
||||
///
|
||||
@@ -257,16 +235,20 @@ RegisterBankInfo::ValueMapping ValMappings[]{
|
||||
///
|
||||
/// \pre \p RBIdx != PartialMappingIdx::None
|
||||
const RegisterBankInfo::ValueMapping *
|
||||
getValueMapping(PartialMappingIdx RBIdx, unsigned Size) {
|
||||
assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
|
||||
unsigned ValMappingIdx = First3OpsIdx +
|
||||
(RBIdx - AArch64::PartialMappingIdx::PMI_Min +
|
||||
getRegBankBaseIdxOffset(Size)) *
|
||||
ValueMappingIdx::DistanceBetweenRegBanks;
|
||||
assert(ValMappingIdx >= AArch64::First3OpsIdx &&
|
||||
ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
|
||||
getValueMapping(AArch64GenRegisterBankInfo::PartialMappingIdx RBIdx,
|
||||
unsigned Size) {
|
||||
assert(RBIdx != AArch64GenRegisterBankInfo::PartialMappingIdx::PMI_None &&
|
||||
"No mapping needed for that");
|
||||
unsigned ValMappingIdx =
|
||||
AArch64GenRegisterBankInfo::First3OpsIdx +
|
||||
(RBIdx - AArch64GenRegisterBankInfo::PartialMappingIdx::PMI_Min +
|
||||
getRegBankBaseIdxOffset(Size)) *
|
||||
AArch64GenRegisterBankInfo::ValueMappingIdx::DistanceBetweenRegBanks;
|
||||
assert(ValMappingIdx >= AArch64GenRegisterBankInfo::First3OpsIdx &&
|
||||
ValMappingIdx <= AArch64GenRegisterBankInfo::Last3OpsIdx &&
|
||||
"Mapping out of bound");
|
||||
|
||||
return &ValMappings[ValMappingIdx];
|
||||
return &AArch64GenRegisterBankInfo::ValMappings[ValMappingIdx];
|
||||
}
|
||||
|
||||
/// Get the pointer to the ValueMapping of the operands of a copy
|
||||
@@ -277,20 +259,45 @@ getValueMapping(PartialMappingIdx RBIdx, unsigned Size) {
|
||||
/// otherwise it is on FPR. Same thing for \p SrcIsGPR.
|
||||
const RegisterBankInfo::ValueMapping *
|
||||
getCopyMapping(bool DstIsGPR, bool SrcIsGPR, unsigned Size) {
|
||||
PartialMappingIdx DstRBIdx = DstIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
|
||||
PartialMappingIdx SrcRBIdx = SrcIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
|
||||
AArch64GenRegisterBankInfo::PartialMappingIdx DstRBIdx =
|
||||
DstIsGPR ? AArch64GenRegisterBankInfo::PMI_FirstGPR
|
||||
: AArch64GenRegisterBankInfo::PMI_FirstFPR;
|
||||
AArch64GenRegisterBankInfo::PartialMappingIdx SrcRBIdx =
|
||||
SrcIsGPR ? AArch64GenRegisterBankInfo::PMI_FirstGPR
|
||||
: AArch64GenRegisterBankInfo::PMI_FirstFPR;
|
||||
if (DstRBIdx == SrcRBIdx)
|
||||
return getValueMapping(DstRBIdx, Size);
|
||||
assert(Size <= 64 && "GPR cannot handle that size");
|
||||
unsigned ValMappingIdx =
|
||||
FirstCrossRegCpyIdx +
|
||||
(DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(Size)) *
|
||||
ValueMappingIdx::DistanceBetweenCrossRegCpy;
|
||||
assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx &&
|
||||
ValMappingIdx <= AArch64::LastCrossRegCpyIdx &&
|
||||
unsigned ValMappingIdx = AArch64GenRegisterBankInfo::FirstCrossRegCpyIdx +
|
||||
(DstRBIdx - AArch64GenRegisterBankInfo::PMI_Min +
|
||||
getRegBankBaseIdxOffset(Size)) *
|
||||
AArch64GenRegisterBankInfo::ValueMappingIdx::
|
||||
DistanceBetweenCrossRegCpy;
|
||||
assert(ValMappingIdx >= AArch64GenRegisterBankInfo::FirstCrossRegCpyIdx &&
|
||||
ValMappingIdx <= AArch64GenRegisterBankInfo::LastCrossRegCpyIdx &&
|
||||
"Mapping out of bound");
|
||||
return &ValMappings[ValMappingIdx];
|
||||
return &AArch64GenRegisterBankInfo::ValMappings[ValMappingIdx];
|
||||
}
|
||||
} // End AArch64 namespace.
|
||||
|
||||
bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
|
||||
unsigned ValStartIdx,
|
||||
unsigned ValLength,
|
||||
const RegisterBank &RB) {
|
||||
const PartialMapping &Map = PartMappings[Idx - PartialMappingIdx::PMI_Min];
|
||||
return Map.StartIdx == ValStartIdx && Map.Length == ValLength &&
|
||||
Map.RegBank == &RB;
|
||||
}
|
||||
|
||||
bool AArch64GenRegisterBankInfo::checkValueMapImpl(unsigned Idx,
|
||||
unsigned FirstInBank,
|
||||
unsigned Size,
|
||||
unsigned Offset) {
|
||||
unsigned PartialMapBaseIdx = Idx - PartialMappingIdx::PMI_Min;
|
||||
const ValueMapping &Map =
|
||||
AArch64::getValueMapping((PartialMappingIdx)FirstInBank, Size)[Offset];
|
||||
return Map.BreakDown == &PartMappings[PartialMapBaseIdx] &&
|
||||
Map.NumBreakDowns == 1;
|
||||
}
|
||||
|
||||
} // End AArch64 namespace.
|
||||
} // End llvm namespace.
|
||||
|
||||
@@ -30,8 +30,11 @@ using namespace llvm;
|
||||
#error "You shouldn't build this"
|
||||
#endif
|
||||
|
||||
AArch64GenRegisterBankInfo::AArch64GenRegisterBankInfo()
|
||||
: RegisterBankInfo(RegBanks, AArch64::NumRegisterBanks) {}
|
||||
|
||||
AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||
: RegisterBankInfo(AArch64::RegBanks, AArch64::NumRegisterBanks) {
|
||||
: AArch64GenRegisterBankInfo() {
|
||||
static bool AlreadyInit = false;
|
||||
// We have only one set of register banks, whatever the subtarget
|
||||
// is. Therefore, the initialization of the RegBanks table should be
|
||||
@@ -78,43 +81,20 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||
|
||||
// Check that the TableGen'ed like file is in sync we our expectations.
|
||||
// First, the Idx.
|
||||
assert(AArch64::PartialMappingIdx::PMI_GPR32 ==
|
||||
AArch64::PartialMappingIdx::PMI_FirstGPR &&
|
||||
"GPR32 index not first in the GPR list");
|
||||
assert(AArch64::PartialMappingIdx::PMI_GPR64 ==
|
||||
AArch64::PartialMappingIdx::PMI_LastGPR &&
|
||||
"GPR64 index not last in the GPR list");
|
||||
assert(AArch64::PartialMappingIdx::PMI_FirstGPR <=
|
||||
AArch64::PartialMappingIdx::PMI_LastGPR &&
|
||||
"GPR list is backward");
|
||||
assert(AArch64::PartialMappingIdx::PMI_FPR32 ==
|
||||
AArch64::PartialMappingIdx::PMI_FirstFPR &&
|
||||
"FPR32 index not first in the FPR list");
|
||||
assert(AArch64::PartialMappingIdx::PMI_FPR512 ==
|
||||
AArch64::PartialMappingIdx::PMI_LastFPR &&
|
||||
"FPR512 index not last in the FPR list");
|
||||
assert(AArch64::PartialMappingIdx::PMI_FirstFPR <=
|
||||
AArch64::PartialMappingIdx::PMI_LastFPR &&
|
||||
"FPR list is backward");
|
||||
assert(AArch64::PartialMappingIdx::PMI_FPR32 + 1 ==
|
||||
AArch64::PartialMappingIdx::PMI_FPR64 &&
|
||||
AArch64::PartialMappingIdx::PMI_FPR64 + 1 ==
|
||||
AArch64::PartialMappingIdx::PMI_FPR128 &&
|
||||
AArch64::PartialMappingIdx::PMI_FPR128 + 1 ==
|
||||
AArch64::PartialMappingIdx::PMI_FPR256 &&
|
||||
AArch64::PartialMappingIdx::PMI_FPR256 + 1 ==
|
||||
AArch64::PartialMappingIdx::PMI_FPR512 &&
|
||||
"FPR indices not properly ordered");
|
||||
assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
|
||||
{PMI_GPR32, PMI_GPR64}) &&
|
||||
"PartialMappingIdx's are incorrectly ordered");
|
||||
assert(checkPartialMappingIdx(
|
||||
PMI_FirstFPR, PMI_LastFPR,
|
||||
{PMI_FPR32, PMI_FPR64, PMI_FPR128, PMI_FPR256, PMI_FPR512}) &&
|
||||
"PartialMappingIdx's are incorrectly ordered");
|
||||
// Now, the content.
|
||||
// Check partial mapping.
|
||||
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \
|
||||
do { \
|
||||
const PartialMapping &Map = \
|
||||
AArch64::PartMappings[AArch64::PartialMappingIdx::Idx - \
|
||||
AArch64::PartialMappingIdx::PMI_Min]; \
|
||||
(void)Map; \
|
||||
assert(Map.StartIdx == ValStartIdx && Map.Length == ValLength && \
|
||||
Map.RegBank == &RB && #Idx " is incorrectly initialized"); \
|
||||
assert( \
|
||||
checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
|
||||
#Idx " is incorrectly initialized"); \
|
||||
} while (0)
|
||||
|
||||
CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
|
||||
@@ -128,16 +108,10 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||
// Check value mapping.
|
||||
#define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \
|
||||
do { \
|
||||
unsigned PartialMapBaseIdx = \
|
||||
AArch64::PartialMappingIdx::PMI_##RBName##Size - \
|
||||
AArch64::PartialMappingIdx::PMI_Min; \
|
||||
(void)PartialMapBaseIdx; \
|
||||
const ValueMapping &Map = AArch64::getValueMapping( \
|
||||
AArch64::PartialMappingIdx::PMI_First##RBName, Size)[Offset]; \
|
||||
(void)Map; \
|
||||
assert(Map.BreakDown == &AArch64::PartMappings[PartialMapBaseIdx] && \
|
||||
Map.NumBreakDowns == 1 && #RBName #Size \
|
||||
" " #Offset " is incorrectly initialized"); \
|
||||
assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size, \
|
||||
PartialMappingIdx::PMI_First##RBName, Size, \
|
||||
Offset) && \
|
||||
#RBName #Size " " #Offset " is incorrectly initialized"); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
|
||||
@@ -169,20 +143,20 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||
|
||||
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \
|
||||
do { \
|
||||
unsigned PartialMapDstIdx = \
|
||||
AArch64::PMI_##RBNameDst##Size - AArch64::PMI_Min; \
|
||||
unsigned PartialMapSrcIdx = \
|
||||
AArch64::PMI_##RBNameSrc##Size - AArch64::PMI_Min; \
|
||||
(void) PartialMapDstIdx; \
|
||||
(void) PartialMapSrcIdx; \
|
||||
const ValueMapping *Map = AArch64::getCopyMapping( \
|
||||
AArch64::PMI_First##RBNameDst == AArch64::PMI_FirstGPR, \
|
||||
AArch64::PMI_First##RBNameSrc == AArch64::PMI_FirstGPR, Size); \
|
||||
(void) Map; \
|
||||
assert(Map[0].BreakDown == &AArch64::PartMappings[PartialMapDstIdx] && \
|
||||
unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min; \
|
||||
unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min; \
|
||||
(void)PartialMapDstIdx; \
|
||||
(void)PartialMapSrcIdx; \
|
||||
const ValueMapping *Map = \
|
||||
AArch64::getCopyMapping(PMI_First##RBNameDst == PMI_FirstGPR, \
|
||||
PMI_First##RBNameSrc == PMI_FirstGPR, Size); \
|
||||
(void)Map; \
|
||||
assert(Map[0].BreakDown == \
|
||||
&AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \
|
||||
Map[0].NumBreakDowns == 1 && #RBNameDst #Size \
|
||||
" Dst is incorrectly initialized"); \
|
||||
assert(Map[1].BreakDown == &AArch64::PartMappings[PartialMapSrcIdx] && \
|
||||
assert(Map[1].BreakDown == \
|
||||
&AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \
|
||||
Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \
|
||||
" Src is incorrectly initialized"); \
|
||||
\
|
||||
@@ -280,12 +254,10 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
||||
break;
|
||||
InstructionMappings AltMappings;
|
||||
InstructionMapping GPRMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1,
|
||||
AArch64::getValueMapping(AArch64::PMI_FirstGPR, Size),
|
||||
/*ID*/ 1, /*Cost*/ 1, AArch64::getValueMapping(PMI_FirstGPR, Size),
|
||||
/*NumOperands*/ 3);
|
||||
InstructionMapping FPRMapping(
|
||||
/*ID*/ 2, /*Cost*/ 1,
|
||||
AArch64::getValueMapping(AArch64::PMI_FirstFPR, Size),
|
||||
/*ID*/ 2, /*Cost*/ 1, AArch64::getValueMapping(PMI_FirstFPR, Size),
|
||||
/*NumOperands*/ 3);
|
||||
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
@@ -341,17 +313,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
||||
InstructionMappings AltMappings;
|
||||
InstructionMapping GPRMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1,
|
||||
getOperandsMapping(
|
||||
{AArch64::getValueMapping(AArch64::PMI_FirstGPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
AArch64::getValueMapping(AArch64::PMI_FirstGPR, 64)}),
|
||||
getOperandsMapping({AArch64::getValueMapping(PMI_FirstGPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
AArch64::getValueMapping(PMI_FirstGPR, 64)}),
|
||||
/*NumOperands*/ 2);
|
||||
InstructionMapping FPRMapping(
|
||||
/*ID*/ 2, /*Cost*/ 1,
|
||||
getOperandsMapping(
|
||||
{AArch64::getValueMapping(AArch64::PMI_FirstFPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
AArch64::getValueMapping(AArch64::PMI_FirstGPR, 64)}),
|
||||
getOperandsMapping({AArch64::getValueMapping(PMI_FirstFPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
AArch64::getValueMapping(PMI_FirstGPR, 64)}),
|
||||
/*NumOperands*/ 2);
|
||||
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
@@ -431,8 +401,7 @@ AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) {
|
||||
}
|
||||
#endif // End NDEBUG.
|
||||
|
||||
AArch64::PartialMappingIdx RBIdx =
|
||||
IsFPR ? AArch64::PMI_FirstFPR : AArch64::PMI_FirstGPR;
|
||||
PartialMappingIdx RBIdx = IsFPR ? PMI_FirstFPR : PMI_FirstGPR;
|
||||
|
||||
return InstructionMapping{DefaultMappingID, 1,
|
||||
AArch64::getValueMapping(RBIdx, Size), NumOperands};
|
||||
@@ -501,7 +470,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
|
||||
// Track the size and bank of each register. We don't do partial mappings.
|
||||
SmallVector<unsigned, 4> OpSize(NumOperands);
|
||||
SmallVector<AArch64::PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
|
||||
SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
|
||||
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
|
||||
auto &MO = MI.getOperand(Idx);
|
||||
if (!MO.isReg())
|
||||
@@ -513,9 +482,9 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
|
||||
// For floating-point instructions, scalars go in FPRs.
|
||||
if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc))
|
||||
OpRegBankIdx[Idx] = AArch64::PMI_FirstFPR;
|
||||
OpRegBankIdx[Idx] = PMI_FirstFPR;
|
||||
else
|
||||
OpRegBankIdx[Idx] = AArch64::PMI_FirstGPR;
|
||||
OpRegBankIdx[Idx] = PMI_FirstGPR;
|
||||
}
|
||||
|
||||
unsigned Cost = 1;
|
||||
@@ -524,26 +493,26 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
switch (Opc) {
|
||||
case TargetOpcode::G_SITOFP:
|
||||
case TargetOpcode::G_UITOFP: {
|
||||
OpRegBankIdx = {AArch64::PMI_FirstFPR, AArch64::PMI_FirstGPR};
|
||||
OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_FPTOSI:
|
||||
case TargetOpcode::G_FPTOUI: {
|
||||
OpRegBankIdx = {AArch64::PMI_FirstGPR, AArch64::PMI_FirstFPR};
|
||||
OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_FCMP: {
|
||||
OpRegBankIdx = {AArch64::PMI_FirstGPR,
|
||||
/* Predicate */ AArch64::PMI_None, AArch64::PMI_FirstFPR,
|
||||
AArch64::PMI_FirstFPR};
|
||||
OpRegBankIdx = {PMI_FirstGPR,
|
||||
/* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_BITCAST: {
|
||||
// This is going to be a cross register bank copy and this is expensive.
|
||||
if (OpRegBankIdx[0] != OpRegBankIdx[1])
|
||||
Cost =
|
||||
copyCost(*AArch64::PartMappings[OpRegBankIdx[0]].RegBank,
|
||||
*AArch64::PartMappings[OpRegBankIdx[1]].RegBank, OpSize[0]);
|
||||
Cost = copyCost(
|
||||
*AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
|
||||
*AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
|
||||
OpSize[0]);
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_LOAD: {
|
||||
@@ -553,7 +522,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// for the greedy mode the cost of the cross bank copy will
|
||||
// offset this number.
|
||||
// FIXME: Should be derived from the scheduling model.
|
||||
if (OpRegBankIdx[0] >= AArch64::PMI_FirstFPR)
|
||||
if (OpRegBankIdx[0] >= PMI_FirstFPR)
|
||||
Cost = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,75 @@ enum {
|
||||
CCRRegBankID = 2, /// Conditional register: NZCV.
|
||||
NumRegisterBanks
|
||||
};
|
||||
|
||||
extern RegisterBank GPRRegBank;
|
||||
extern RegisterBank FPRRegBank;
|
||||
extern RegisterBank CCRRegBank;
|
||||
} // End AArch64 namespace.
|
||||
|
||||
class AArch64GenRegisterBankInfo : public RegisterBankInfo {
|
||||
private:
|
||||
static RegisterBank *RegBanks[];
|
||||
|
||||
protected:
|
||||
AArch64GenRegisterBankInfo();
|
||||
|
||||
public:
|
||||
static RegisterBankInfo::PartialMapping PartMappings[];
|
||||
static RegisterBankInfo::ValueMapping ValMappings[];
|
||||
static bool checkPartialMap(unsigned Idx, unsigned ValStartIdx,
|
||||
unsigned ValLength, const RegisterBank &RB);
|
||||
static bool checkValueMapImpl(unsigned Idx, unsigned FirstInBank,
|
||||
unsigned Size, unsigned Offset);
|
||||
enum PartialMappingIdx {
|
||||
PMI_None = -1,
|
||||
PMI_GPR32 = 1,
|
||||
PMI_GPR64,
|
||||
PMI_FPR32,
|
||||
PMI_FPR64,
|
||||
PMI_FPR128,
|
||||
PMI_FPR256,
|
||||
PMI_FPR512,
|
||||
PMI_FirstGPR = PMI_GPR32,
|
||||
PMI_LastGPR = PMI_GPR64,
|
||||
PMI_FirstFPR = PMI_FPR32,
|
||||
PMI_LastFPR = PMI_FPR512,
|
||||
PMI_Min = PMI_FirstGPR,
|
||||
};
|
||||
|
||||
enum ValueMappingIdx {
|
||||
First3OpsIdx = 0,
|
||||
Last3OpsIdx = 18,
|
||||
DistanceBetweenRegBanks = 3,
|
||||
FirstCrossRegCpyIdx = 21,
|
||||
LastCrossRegCpyIdx = 27,
|
||||
DistanceBetweenCrossRegCpy = 2
|
||||
};
|
||||
|
||||
static bool checkPartialMappingIdx(PartialMappingIdx FirstAlias,
|
||||
PartialMappingIdx LastAlias,
|
||||
ArrayRef<PartialMappingIdx> Order) {
|
||||
if (Order.front() != FirstAlias)
|
||||
return false;
|
||||
if (Order.back() != LastAlias)
|
||||
return false;
|
||||
if (Order.front() > Order.back())
|
||||
return false;
|
||||
|
||||
PartialMappingIdx Previous = Order.front();
|
||||
bool First = true;
|
||||
for (const auto &Current : Order) {
|
||||
if (First) {
|
||||
First = false;
|
||||
continue;
|
||||
}
|
||||
if (Previous + 1 != Current)
|
||||
return false;
|
||||
Previous = Current;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// This class provides the information for the target register banks.
|
||||
class AArch64RegisterBankInfo final : public RegisterBankInfo {
|
||||
class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo {
|
||||
/// See RegisterBankInfo::applyMapping.
|
||||
void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user