[AArch64][RegisterBankInfo] Compress the ValueMapping table a bit.

We don't need to have singleton ValueMapping on their own, we can just
reuse one of the elements of the 3-ops mapping.
This allows even more code sharing.

NFC.

llvm-svn: 282959
This commit is contained in:
Quentin Colombet 2016-09-30 21:46:17 +00:00
parent 138aafd3ba
commit 66021ca5d5
2 changed files with 38 additions and 46 deletions

View File

@ -67,51 +67,49 @@ RegisterBankInfo::PartialMapping PartMappings[] {
};
enum ValueMappingIdx {
First3OpsIdx = 7,
Last3OpsIdx = 25
First3OpsIdx = 0,
Last3OpsIdx = 18,
DistanceBetweenRegBanks = 3
};
// ValueMappings.
RegisterBankInfo::ValueMapping ValMappings[] {
/* BreakDown, NumBreakDowns */
// 0: GPR 32-bit value.
{&PartMappings[0], 1},
// 1: GPR 64-bit value.
{&PartMappings[1], 1},
// 2: FPR 32-bit value.
{&PartMappings[2], 1},
// 3: FPR 64-bit value.
{&PartMappings[3], 1},
// 4: FPR 128-bit value.
{&PartMappings[4], 1},
// 5: FPR 256-bit value.
{&PartMappings[5], 1},
// 6: FPR 512-bit value.
{&PartMappings[6], 1},
// 3-operands instructions (all binary operations should end up with one of
// those mapping).
// 7: GPR 32-bit value. <-- This must match First3OpsIdx.
// 0: GPR 32-bit value. <-- This must match First3OpsIdx.
{&PartMappings[0], 1}, {&PartMappings[0], 1}, {&PartMappings[0], 1},
// 10: GPR 64-bit value.
// 3: GPR 64-bit value.
{&PartMappings[1], 1}, {&PartMappings[1], 1}, {&PartMappings[1], 1},
// 13: FPR 32-bit value.
// 6: FPR 32-bit value.
{&PartMappings[2], 1}, {&PartMappings[2], 1}, {&PartMappings[2], 1},
// 16: FPR 64-bit value.
// 9: FPR 64-bit value.
{&PartMappings[3], 1}, {&PartMappings[3], 1}, {&PartMappings[3], 1},
// 19: FPR 128-bit value.
// 12: FPR 128-bit value.
{&PartMappings[4], 1}, {&PartMappings[4], 1}, {&PartMappings[4], 1},
// 22: FPR 256-bit value.
// 15: FPR 256-bit value.
{&PartMappings[5], 1}, {&PartMappings[5], 1}, {&PartMappings[5], 1},
// 25: FPR 512-bit value. <-- This must match Last3OpsIdx.
// 18: FPR 512-bit value. <-- This must match Last3OpsIdx.
{&PartMappings[6], 1}, {&PartMappings[6], 1}, {&PartMappings[6], 1}
};
/// Get the pointer to the ValueMapping representing the RegisterBank
/// at \p RBIdx with a size of \p Size.
///
/// The returned mapping works for instructions with the same kind of
/// operands for up to 3 operands.
///
/// \pre \p RBIdx != PartialMappingIdx::None
const RegisterBankInfo::ValueMapping *getValueMappingIdx(PartialMappingIdx RBIdx, unsigned Size) {
const RegisterBankInfo::ValueMapping *
getValueMappingIdx(PartialMappingIdx RBIdx, unsigned Size) {
assert(RBIdx != PartialMappingIdx::None && "No mapping needed for that");
return &ValMappings[(RBIdx + getRegBankBaseIdxOffset(Size))];
unsigned ValMappingIdx = First3OpsIdx +
(RBIdx + getRegBankBaseIdxOffset(Size)) *
ValueMappingIdx::DistanceBetweenRegBanks;
assert(ValMappingIdx >= AArch64::First3OpsIdx &&
ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
return &ValMappings[ValMappingIdx];
}
} // End AArch64 namespace.

View File

@ -142,7 +142,9 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
} while (0)
#define CHECK_VALUEMAP(Idx) \
CHECK_VALUEMAP_IMPL(AArch64::PartialMappingIdx::Idx, Idx)
CHECK_VALUEMAP_IMPL((AArch64::PartialMappingIdx::Idx * \
AArch64::ValueMappingIdx::DistanceBetweenRegBanks), \
Idx)
CHECK_VALUEMAP(GPR32);
CHECK_VALUEMAP(GPR64);
@ -244,17 +246,13 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
if (MI.getNumOperands() != 3)
break;
InstructionMappings AltMappings;
InstructionMapping GPRMapping(/*ID*/ 1, /*Cost*/ 1, nullptr,
InstructionMapping GPRMapping(/*ID*/ 1, /*Cost*/ 1,
getValueMappingIdx(AArch64::FirstGPR, Size),
/*NumOperands*/ 3);
InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, nullptr,
InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1,
getValueMappingIdx(AArch64::FirstFPR, Size),
/*NumOperands*/ 3);
unsigned RBIdxOffset = AArch64::getRegBankBaseIdxOffset(Size);
GPRMapping.setOperandsMapping(
&AArch64::ValMappings[AArch64::First3OpsIdx +
(RBIdxOffset + AArch64::FirstGPR) * 3]);
FPRMapping.setOperandsMapping(
&AArch64::ValMappings[AArch64::First3OpsIdx +
(RBIdxOffset + AArch64::FirstFPR) * 3]);
AltMappings.emplace_back(std::move(GPRMapping));
AltMappings.emplace_back(std::move(FPRMapping));
return AltMappings;
@ -336,29 +334,25 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
assert(NumOperands == 3 && "This code is for 3-operands instructions");
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
unsigned RBIdxOffset = AArch64::getRegBankBaseIdxOffset(Ty.getSizeInBits());
unsigned Size = Ty.getSizeInBits();
// Make sure all the operands are using similar size.
// Should probably be checked by the machine verifier.
assert(AArch64::getRegBankBaseIdxOffset(
MRI.getType(MI.getOperand(1).getReg()).getSizeInBits()) ==
RBIdxOffset &&
AArch64::getRegBankBaseIdxOffset(Size) &&
"Operand 1 has incompatible size");
assert(AArch64::getRegBankBaseIdxOffset(
MRI.getType(MI.getOperand(2).getReg()).getSizeInBits()) ==
RBIdxOffset &&
AArch64::getRegBankBaseIdxOffset(Size) &&
"Operand 2 has incompatible size");
bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
unsigned RBIdx =
(IsFPR ? AArch64::FirstFPR : AArch64::FirstGPR) + RBIdxOffset;
unsigned ValMappingIdx = AArch64::First3OpsIdx + RBIdx * 3;
AArch64::PartialMappingIdx RBIdx =
IsFPR ? AArch64::FirstFPR : AArch64::FirstGPR;
assert(ValMappingIdx >= AArch64::First3OpsIdx &&
ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
return InstructionMapping{
DefaultMappingID, 1, &AArch64::ValMappings[ValMappingIdx], NumOperands};
return InstructionMapping{DefaultMappingID, 1,
getValueMappingIdx(RBIdx, Size), NumOperands};
}
default:
break;