Index: lib/Target/AArch64/AArch64GenRegisterBankInfo.def =================================================================== --- lib/Target/AArch64/AArch64GenRegisterBankInfo.def +++ lib/Target/AArch64/AArch64GenRegisterBankInfo.def @@ -18,23 +18,6 @@ namespace llvm { namespace AArch64 { -// 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, -}; - static unsigned getRegBankBaseIdxOffset(unsigned Size) { assert(Size && "0-sized type!!"); // Make anything smaller than 32 gets 32 @@ -43,82 +26,7 @@ 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 -}; - -// ValueMappings. -RegisterBankInfo::ValueMapping 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}, - // 3: GPR 64-bit value. - {&PartMappings[PMI_GPR64 - PMI_Min], 1}, - {&PartMappings[PMI_GPR64 - PMI_Min], 1}, - {&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}, - // 9: FPR 64-bit value. - {&PartMappings[PMI_FPR64 - PMI_Min], 1}, - {&PartMappings[PMI_FPR64 - PMI_Min], 1}, - {&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}, - // 15: FPR 256-bit value. - {&PartMappings[PMI_FPR256 - PMI_Min], 1}, - {&PartMappings[PMI_FPR256 - PMI_Min], 1}, - {&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}, - // 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}, - // 23: GPR 64-bit value to FPR 64-bit value. - {&PartMappings[PMI_GPR64 - PMI_Min], 1}, - {&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}, - // 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} -}; +extern RegisterBankInfo::ValueMapping ValMappings[]; /// Get the pointer to the ValueMapping representing the RegisterBank /// at \p RBIdx with a size of \p Size. @@ -140,12 +48,6 @@ return &ValMappings[ValMappingIdx]; } -PartialMappingIdx BankIDToCopyMapIdx[] { - PMI_None, // CCR - PMI_FirstFPR, // FPR - PMI_FirstGPR, // GPR -}; - /// Get the pointer to the ValueMapping of the operands of a copy /// instruction from the \p SrcBankID register bank to the \p DstBankID /// register bank with a size of \p Size. @@ -168,6 +70,7 @@ assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx && ValMappingIdx <= AArch64::LastCrossRegCpyIdx && "Mapping out of bound"); + assert(ValMappings[ValMappingIdx].BreakDown != nullptr && "Hit an invalid copy"); return &ValMappings[ValMappingIdx]; } Index: lib/Target/AArch64/AArch64RegisterBankInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -21,6 +21,8 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" +#define TBLGEN_REGISTERBANKINFO_CPP_EARLY +#include "AArch64GenRegisterBank.inc" // This file will be TableGen'ed at some point. #include "AArch64GenRegisterBankInfo.def" #define GET_REGBANK_IFACE_IMPL Index: utils/TableGen/RegisterBankEmitter.cpp =================================================================== --- utils/TableGen/RegisterBankEmitter.cpp +++ utils/TableGen/RegisterBankEmitter.cpp @@ -128,12 +128,21 @@ return partial_mappings().begin() != partial_mappings().end(); } + bool hasPartialMapping(unsigned Size) const { + return std::find(partial_mappings().begin(), partial_mappings().end(), + Size) != partial_mappings().end(); + } + /// This range is not valid if finalizePartialMappings() has not been /// called. iterator_range partial_mappings() const { return llvm::make_range(PartialMappings.begin(), PartialMappings.end()); } + + bool operator==(const RegisterBank &Other) const { + return getName() == Other.getName(); + } }; class RegisterBankEmitter { @@ -144,6 +153,11 @@ void emitHeader(raw_ostream &OS, const StringRef TargetName, const std::vector &Banks); void emitRegisterBankInfoPrivateMembers(raw_ostream &OS); + void emitPartialMappingsIdxEnum(raw_ostream &OS, + std::vector &Banks); + void emitPartMappingsArray(raw_ostream &OS, std::vector &Banks); + void emitValMappingsArrayAndIndexes(raw_ostream &OS, + std::vector &Banks); void emitRegisterBankInfoImplementation(raw_ostream &OS, const StringRef TargetName, @@ -242,10 +256,134 @@ OS << "\"" << EnumeratorPrefix << " indices not properly ordered\");\n"; } +/// Emit PartialMappingsIdx. +void RegisterBankEmitter::emitPartialMappingsIdxEnum( + raw_ostream &OS, std::vector &Banks) { + OS << "// PartialMappings.\n" + << "enum PartialMappingIdx {\n" + << " PMI_None = -1,\n"; + + for (const auto &Bank : Banks) + for (const auto &PartialMappingSize : Bank.partial_mappings()) + OS << " PMI_" << Bank.getName() << PartialMappingSize << ",\n"; + + const RegisterBank *FirstEmittedBank = nullptr; + for (const auto &Bank : Banks) { + if (Bank.hasPartialMappings()) { + if (FirstEmittedBank == nullptr) + FirstEmittedBank = &Bank; + OS << " PMI_First" << Bank.getName() << " = PMI_" << Bank.getName() + << *Bank.partial_mappings().begin() << ",\n"; + OS << " PMI_Last" << Bank.getName() << " = PMI_" << Bank.getName() + << *(Bank.partial_mappings().end() - 1) << ",\n"; + } + } + if (FirstEmittedBank) + OS << " PMI_Min = PMI_First" << FirstEmittedBank->getName() << "\n"; + OS << "};\n\n"; +} + +/// Emit PartMappings. +void RegisterBankEmitter::emitPartMappingsArray( + raw_ostream &OS, std::vector &Banks) { + OS << "// { StartIdx, Length, RegBank }\n" + << "RegisterBankInfo::PartialMapping PartMappings[] {\n"; + for (const auto &Bank : Banks) + for (const auto &Size : Bank.partial_mappings()) + OS << " {0, " << Size << ", " << Bank.getInstanceVarName() << "},\n"; + OS << "};\n" + << "\n"; +} + +/// Emit ValMappings, the anonymous index representing start and end of the 3-op +/// and cross register bank copy regions, and the BankIDToCopyMapIdx index. +void RegisterBankEmitter::emitValMappingsArrayAndIndexes( + raw_ostream &OS, std::vector &Banks) { + std::string BankIDToCopyMapIdxEntriesStr; + raw_string_ostream BankIDToCopyMapIdxEntries(BankIDToCopyMapIdxEntriesStr); + + std::string ValMappingIdxEnumeratorsStr; + raw_string_ostream ValMappingIdxEnumerators(ValMappingIdxEnumeratorsStr); + unsigned ValMappingIdx = 0; + + OS << "RegisterBankInfo::ValueMapping ValMappings[] {\n" + << " /* BreakDown, NumBreakDowns */\n" + << " // 3-operands instructions (all binary operations should end up\n" + << " // with one of those mappings).\n"; + ValMappingIdxEnumerators << " First3OpsIdx = " << ValMappingIdx << ",\n"; + for (const auto &Bank : Banks) { + for (const auto &Size : Bank.partial_mappings()) { + OS << " // " << Bank.getName() << Size << "\n "; + for (unsigned I = 0; I < 3; ++I, ++ValMappingIdx) + OS << " {&PartMappings[PMI_" << Bank.getName() << Size + << " - PMI_Min], 1},"; + OS << "\n"; + } + } + ValMappingIdxEnumerators << " Last3OpsIdx = " << ValMappingIdx << ",\n"; + + OS << " // Cross register bank copies.\n"; + ValMappingIdxEnumerators << " FirstCrossRegCpyIdx = " << ValMappingIdx + << ",\n"; + for (const auto &Bank : Banks) { + if (!Bank.hasPartialMappings()) { + BankIDToCopyMapIdxEntries << " PMI_None,\n"; + continue; + } + + BankIDToCopyMapIdxEntries << " PMI_First" << Bank.getName() << ",\n"; + + for (const auto &Size : Bank.partial_mappings()) { + for (const auto &OtherBank : Banks) { + if (Bank == OtherBank || !OtherBank.hasPartialMappings()) + continue; + + OS << " // " << Bank.getName() << Size << " -> " << OtherBank.getName() + << Size << "\n"; + + if (OtherBank.hasPartialMapping(Size)) { + OS << " {&PartMappings[PMI_" << Bank.getName() << Size + << " - PMI_Min], 1}, "; + OS << "{&PartMappings[PMI_" << OtherBank.getName() << Size + << " - PMI_Min], 1},\n"; + } else + OS << " {nullptr, 0}, {nullptr, 0},\n"; + + ValMappingIdx += 2; + } + } + } + ValMappingIdxEnumerators << " LastCrossRegCpyIdx = " << ValMappingIdx + << ",\n"; + + OS << "};\n\n"; + + OS << "enum ValueMappingIdx {\n" + << ValMappingIdxEnumerators.str() << " DistanceBetweenRegBanks = 3,\n" + " DistanceBetweenCrossRegCpy = 2\n" + "};\n\n"; + + OS << "PartialMappingIdx BankIDToCopyMapIdx[] {\n" + << BankIDToCopyMapIdxEntries.str() << " PMI_None,\n" + << "};\n\n"; + +} + void RegisterBankEmitter::emitRegisterBankInfoImplementation( raw_ostream &OS, StringRef TargetName, std::vector &Banks) { // RegisterBankInfo.cpp + OS << "#ifdef TBLGEN_REGISTERBANKINFO_CPP_EARLY\n" + << "#undef TBLGEN_REGISTERBANKINFO_CPP_EARLY\n" + << "namespace llvm {\n" + << "namespace " << TargetName << " {\n"; + emitPartialMappingsIdxEnum(OS, Banks); + emitPartMappingsArray(OS, Banks); + emitValMappingsArrayAndIndexes(OS, Banks); + OS << "}\n" + << "} // end namespace llvm\n" + << "#endif // TBLGEN_REGISTERBANKINFO_CPP_EARLY\n"; + OS << "#ifdef GET_REGBANK_IFACE_IMPL\n" << "#undef GET_REGBANK_IFACE_IMPL\n" << "namespace llvm {\n"