diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 292fa3c94969b..374f9f2e7f569 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -41,12 +41,10 @@ class RegScavenger; class VirtRegMap; class LiveIntervals; class LiveInterval; - class TargetRegisterClass { public: using iterator = const MCPhysReg *; using const_iterator = const MCPhysReg *; - using sc_iterator = const TargetRegisterClass* const *; // Instance variables filled by tablegen, do not use! const MCRegisterClass *MC; @@ -67,7 +65,8 @@ class TargetRegisterClass { /// Whether a combination of subregisters can cover every register in the /// class. See also the CoveredBySubRegs description in Target.td. const bool CoveredBySubRegs; - const sc_iterator SuperClasses; + const unsigned *SuperClasses; + const uint16_t SuperClassesSize; ArrayRef (*OrderFunc)(const MachineFunction&); /// Return the register class ID number. @@ -175,18 +174,16 @@ class TargetRegisterClass { return SuperRegIndices; } - /// Returns a NULL-terminated list of super-classes. The + /// Returns a list of super-classes. The /// classes are ordered by ID which is also a topological ordering from large /// to small classes. The list does NOT include the current class. - sc_iterator getSuperClasses() const { - return SuperClasses; + ArrayRef superclasses() const { + return ArrayRef(SuperClasses, SuperClassesSize); } /// Return true if this TargetRegisterClass is a subset /// class of at least one other TargetRegisterClass. - bool isASubClass() const { - return SuperClasses[0] != nullptr; - } + bool isASubClass() const { return SuperClasses != nullptr; } /// Returns the preferred order for allocating registers from this register /// class in MF. The raw order comes directly from the .td file and may diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index a1f068f0e049b..291bfc0610f85 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -262,30 +262,31 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF, const TargetRegisterClass * ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const { - const TargetRegisterClass *Super = RC; - TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); + unsigned SuperID = RC->getID(); + auto I = RC->superclasses().begin(); + auto E = RC->superclasses().end(); do { - switch (Super->getID()) { + switch (SuperID) { case ARM::GPRRegClassID: case ARM::SPRRegClassID: case ARM::DPRRegClassID: case ARM::GPRPairRegClassID: - return Super; + return getRegClass(SuperID); case ARM::QPRRegClassID: case ARM::QQPRRegClassID: case ARM::QQQQPRRegClassID: if (MF.getSubtarget().hasNEON()) - return Super; + return getRegClass(SuperID); break; case ARM::MQPRRegClassID: case ARM::MQQPRRegClassID: case ARM::MQQQQPRRegClassID: if (MF.getSubtarget().hasMVEIntegerOps()) - return Super; + return getRegClass(SuperID); break; } - Super = *I++; - } while (Super); + SuperID = (I != E) ? *I++ : ~0U; + } while (SuperID != ~0U); return RC; } diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index d4d121e438008..2731c523963e5 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -431,8 +431,9 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex( return WSub[GenIdx]; } - if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses()) - return getHexagonSubRegIndex(*SuperRC, GenIdx); + if (!RC.superclasses().empty()) + return getHexagonSubRegIndex(*getRegClass(*RC.superclasses().begin()), + GenIdx); llvm_unreachable("Invalid register class"); } diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 43dfc4108f838..019d4cfa33fba 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -692,21 +692,23 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, InflateGPRC++; } - for (const auto *I = RC->getSuperClasses(); *I; ++I) { - if (getRegSizeInBits(**I) != getRegSizeInBits(*RC)) + for (unsigned SuperID : RC->superclasses()) { + if (getRegSizeInBits(*getRegClass(SuperID)) != getRegSizeInBits(*RC)) continue; - switch ((*I)->getID()) { + switch (SuperID) { case PPC::VSSRCRegClassID: - return Subtarget.hasP8Vector() ? *I : DefaultSuperclass; + return Subtarget.hasP8Vector() ? getRegClass(SuperID) + : DefaultSuperclass; case PPC::VSFRCRegClassID: case PPC::VSRCRegClassID: - return *I; + return getRegClass(SuperID); case PPC::VSRpRCRegClassID: - return Subtarget.pairedVectorMemops() ? *I : DefaultSuperclass; + return Subtarget.pairedVectorMemops() ? getRegClass(SuperID) + : DefaultSuperclass; case PPC::ACCRCRegClassID: case PPC::UACCRCRegClassID: - return Subtarget.hasMMA() ? *I : DefaultSuperclass; + return Subtarget.hasMMA() ? getRegClass(SuperID) : DefaultSuperclass; } } } diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 50db211c99d88..164d420595516 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -123,7 +123,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, const X86Subtarget &Subtarget = MF.getSubtarget(); const TargetRegisterClass *Super = RC; - TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); + auto I = RC->superclasses().begin(); + auto E = RC->superclasses().end(); do { switch (Super->getID()) { case X86::FR32RegClassID: @@ -172,7 +173,12 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC)) return Super; } - Super = *I++; + if (I != E) { + Super = getRegClass(*I); + ++I; + } else { + Super = nullptr; + } } while (Super); return RC; } diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp index c32c2ce859af5..ab28963b39311 100644 --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -584,7 +584,7 @@ TEST(MachineInstrTest, SpliceOperands) { // test tied operands MCRegisterClass MRC{ 0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true}; - TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0}; + TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0, 0}; // MachineRegisterInfo will be very upset if these registers aren't // allocatable. assert(RC.isAllocatable() && "unusable TargetRegisterClass"); diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index a6f87119aca5b..bfcd52da1c39c 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1286,9 +1286,6 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { } OS << "};\n"; - OS << "\nstatic const TargetRegisterClass *const " - << "NullRegClasses[] = { nullptr };\n\n"; - // Emit register class bit mask tables. The first bit mask emitted for a // register class, RC, is the set of sub-classes, including RC itself. // @@ -1340,19 +1337,18 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { SuperRegIdxSeqs.emit(OS, printSubRegIndex); OS << "};\n\n"; - // Emit NULL terminated super-class lists. + // Emit super-class lists. for (const auto &RC : RegisterClasses) { ArrayRef Supers = RC.getSuperClasses(); - // Skip classes without supers. We can reuse NullRegClasses. + // Skip classes without supers. if (Supers.empty()) continue; - OS << "static const TargetRegisterClass *const " << RC.getName() - << "Superclasses[] = {\n"; + OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n"; for (const auto *Super : Supers) - OS << " &" << Super->getQualifiedName() << "RegClass,\n"; - OS << " nullptr\n};\n\n"; + OS << " " << Super->getQualifiedIdName() << ",\n"; + OS << "};\n\n"; } // Emit methods. @@ -1406,9 +1402,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { << (RC.CoveredBySubRegs ? "true" : "false") << ", /* CoveredBySubRegs */\n "; if (RC.getSuperClasses().empty()) - OS << "NullRegClasses,\n "; + OS << "nullptr, "; else - OS << RC.getName() << "Superclasses,\n "; + OS << RC.getName() << "Superclasses, "; + OS << RC.getSuperClasses().size() << ",\n "; if (RC.AltOrderSelect.empty()) OS << "nullptr\n"; else