From 5b16d931dc25d6318d4751ce4f4c0b346c86a562 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Fri, 23 Sep 2016 00:14:36 +0000 Subject: [PATCH] [AArch64][RegisterBankInfo] Switch to TableGen'ed like PartialMapping. Statically instanciate the most common PartialMappings. This should be closer to what the code would look like when TableGen support is added for GlobalISel. As a side effect, this should improve compile time. llvm-svn: 282215 --- .../Target/AArch64/AArch64GenRegisterBankInfo.def | 41 ++++++++++++++++++ .../lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 49 +++++++++++++--------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def b/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def index c9bd62b..558a521 100644 --- a/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def +++ b/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def @@ -24,5 +24,46 @@ RegisterBank CCRRegBank; RegisterBank *RegBanks[] = {&GPRRegBank, &FPRRegBank, &CCRRegBank}; +// PartialMappings. +enum PartialMappingIdx { + GPR32, + GPR64, + FPR32, + FPR64, + FPR128, + FPR256, + FPR512, + FirstGPR = GPR32, + LastGPR = GPR64, + FirstFPR = FPR32, + LastFPR = FPR512 +}; + +static unsigned getRegBankBaseIdx(unsigned Size) { + assert(Size && "0-sized type!!"); + // Make anything smaller than 32 gets 32 + Size = ((Size + 31) / 32) * 32; + // 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 64-bit value. + {0, 128, FPRRegBank}, + // 5: FPR 64-bit value. + {0, 256, FPRRegBank}, + // 6: FPR 64-bit value. + {0, 512, FPRRegBank} +}; + } // End AArch64 namespace. } // End llvm namespace. diff --git a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index b17fbb6..9e4c0fc 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -158,13 +158,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings( InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3); for (unsigned Idx = 0; Idx != 3; ++Idx) { GPRMapping.setOperandMapping( - Idx, ValueMapping{&getPartialMapping( - 0, Size, getRegBank(AArch64::GPRRegBankID)), - 1}); + Idx, + ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + + AArch64::FirstGPR], + 1}); FPRMapping.setOperandMapping( - Idx, ValueMapping{&getPartialMapping( - 0, Size, getRegBank(AArch64::FPRRegBankID)), - 1}); + Idx, + ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + + AArch64::FirstFPR], + 1}); } AltMappings.emplace_back(std::move(GPRMapping)); AltMappings.emplace_back(std::move(FPRMapping)); @@ -225,22 +227,28 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()}; // Track the size and bank of each register. We don't do partial mappings. - SmallVector OpSizes(MI.getNumOperands()); - SmallVector OpBanks(MI.getNumOperands()); + SmallVector OpBaseIdx(MI.getNumOperands()); + SmallVector OpFinalIdx(MI.getNumOperands()); for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) { auto &MO = MI.getOperand(Idx); if (!MO.isReg()) continue; LLT Ty = MRI.getType(MO.getReg()); - OpSizes[Idx] = Ty.getSizeInBits(); + unsigned RBIdx = AArch64::getRegBankBaseIdx(Ty.getSizeInBits()); + OpBaseIdx[Idx] = RBIdx; // 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)) - OpBanks[Idx] = AArch64::FPRRegBankID; - else - OpBanks[Idx] = AArch64::GPRRegBankID; + if (Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc)) { + assert(RBIdx < (AArch64::LastFPR - AArch64::FirstFPR) + 1 && + "Index out of bound"); + OpFinalIdx[Idx] = AArch64::FirstFPR + RBIdx; + } else { + assert(RBIdx < (AArch64::LastGPR - AArch64::FirstGPR) + 1 && + "Index out of bound"); + OpFinalIdx[Idx] = AArch64::FirstGPR + RBIdx; + } } // Some of the floating-point instructions have mixed GPR and FPR operands: @@ -248,17 +256,20 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { switch (Opc) { case TargetOpcode::G_SITOFP: case TargetOpcode::G_UITOFP: { - OpBanks = {AArch64::FPRRegBankID, AArch64::GPRRegBankID}; + OpFinalIdx = {OpBaseIdx[0] + AArch64::FirstFPR, + OpBaseIdx[1] + AArch64::FirstGPR}; break; } case TargetOpcode::G_FPTOSI: case TargetOpcode::G_FPTOUI: { - OpBanks = {AArch64::GPRRegBankID, AArch64::FPRRegBankID}; + OpFinalIdx = {OpBaseIdx[0] + AArch64::FirstGPR, + OpBaseIdx[1] + AArch64::FirstFPR}; break; } case TargetOpcode::G_FCMP: { - OpBanks = {AArch64::GPRRegBankID, /* Predicate */ 0, AArch64::FPRRegBankID, - AArch64::FPRRegBankID}; + OpFinalIdx = {OpBaseIdx[0] + AArch64::FirstGPR, /* Predicate */ 0, + OpBaseIdx[2] + AArch64::FirstFPR, + OpBaseIdx[3] + AArch64::FirstFPR}; break; } } @@ -267,9 +278,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) if (MI.getOperand(Idx).isReg()) Mapping.setOperandMapping( - Idx, ValueMapping{&getPartialMapping(0, OpSizes[Idx], - getRegBank(OpBanks[Idx])), - 1}); + Idx, ValueMapping{&AArch64::PartMappings[OpFinalIdx[Idx]], 1}); return Mapping; } -- 2.7.4