[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:
Daniel Sanders
2017-01-13 10:53:57 +00:00
parent 34315eec58
commit 438a1ecc2c
3 changed files with 217 additions and 180 deletions

View File

@@ -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.

View File

@@ -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;
}
}

View File

@@ -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;