diff --git a/llvm/test/TableGen/RegisterInfoEmitter-BaseClassOrder.td b/llvm/test/TableGen/RegisterInfoEmitter-BaseClassOrder.td --- a/llvm/test/TableGen/RegisterInfoEmitter-BaseClassOrder.td +++ b/llvm/test/TableGen/RegisterInfoEmitter-BaseClassOrder.td @@ -28,11 +28,13 @@ def MyTarget : Target; -// CHECK: static const TargetRegisterClass *BaseClasses[4] = { -// CHECK-NEXT: nullptr, -// CHECK-NEXT: &MyTarget::BaseCRegClass, -// CHECK-NEXT: &MyTarget::BaseARegClass, -// CHECK-NEXT: &MyTarget::BaseBRegClass, -// CHECK-NEXT: } -// CHECK-NEXT: static const uint8_t Mapping[8] = { -// CHECK-NEXT: 0,2,2,1,1,3,3,0, }; +// CHECK: static const uint16_t Mapping[8] = { +// CHECK-NEXT: InvalidRegClassID, // NoRegister +// CHECK-NEXT: MyTarget::BaseARegClassID, // R0 +// CHECK-NEXT: MyTarget::BaseARegClassID, // R1 +// CHECK-NEXT: MyTarget::BaseCRegClassID, // R2 +// CHECK-NEXT: MyTarget::BaseCRegClassID, // R3 +// CHECK-NEXT: MyTarget::BaseBRegClassID, // R4 +// CHECK-NEXT: MyTarget::BaseBRegClassID, // R5 +// CHECK-NEXT: InvalidRegClassID, // R6 +// CHECK-NEXT: }; diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1591,8 +1591,8 @@ BaseClasses.push_back(&RC); } if (!BaseClasses.empty()) { - // Represent class indexes with uint8_t and allocate one index for nullptr - assert(BaseClasses.size() <= UINT8_MAX && "Too many base register classes"); + assert(BaseClasses.size() < UINT16_MAX && + "Too many base register classes"); // Apply order struct BaseClassOrdering { @@ -1603,30 +1603,35 @@ }; llvm::stable_sort(BaseClasses, BaseClassOrdering()); - // Build mapping for Regs (+1 for NoRegister) - std::vector Mapping(Regs.size() + 1, 0); - for (int RCIdx = BaseClasses.size() - 1; RCIdx >= 0; --RCIdx) { - for (const auto Reg : BaseClasses[RCIdx]->getMembers()) - Mapping[Reg->EnumValue] = RCIdx + 1; - } - OS << "\n// Register to base register class mapping\n\n"; OS << "\n"; OS << "const TargetRegisterClass *" << ClassName << "::getPhysRegBaseClass(MCRegister Reg)" << " const {\n"; - OS << " static const TargetRegisterClass *BaseClasses[" << (BaseClasses.size() + 1) << "] = {\n"; - OS << " nullptr,\n"; - for (const auto RC : BaseClasses) - OS << " &" << RC->getQualifiedName() << "RegClass,\n"; - OS << " };\n"; - OS << " static const uint8_t Mapping[" << Mapping.size() << "] = {\n "; - for (const uint8_t Value : Mapping) - OS << (unsigned)Value << ","; - OS << " };\n\n"; - OS << " assert(Reg < sizeof(Mapping));\n"; - OS << " return BaseClasses[Mapping[Reg]];\n"; - OS << "}\n"; + OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n"; + OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n"; + OS << " InvalidRegClassID, // NoRegister\n"; + for (const CodeGenRegister &Reg : Regs) { + const CodeGenRegisterClass *BaseRC = nullptr; + for (const CodeGenRegisterClass *RC : BaseClasses) { + if (is_contained(RC->getMembers(), &Reg)) { + BaseRC = RC; + break; + } + } + + OS << " " + << (BaseRC ? BaseRC->getQualifiedName() + "RegClassID" + : "InvalidRegClassID") + << ", // " << Reg.getName() << "\n"; + } + OS << " };\n\n" + " assert(Reg < ArrayRef(Mapping).size());\n" + " unsigned RCID = Mapping[Reg];\n" + " if (RCID == InvalidRegClassID)\n" + " return nullptr;\n" + " return RegisterClasses[RCID];\n" + "}\n"; } }