Skip to content

Commit 6f3f08a

Browse files
authored
CodeGen: Eliminate dynamic relocations in the register superclass tables. (llvm#119487)
This reapplies llvm#119122 with a fix for UBSAN errors in the X86 backend related to incrementing a nullptr.
1 parent 5fae408 commit 6f3f08a

File tree

7 files changed

+44
-40
lines changed

7 files changed

+44
-40
lines changed

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@ class RegScavenger;
4141
class VirtRegMap;
4242
class LiveIntervals;
4343
class LiveInterval;
44-
4544
class TargetRegisterClass {
4645
public:
4746
using iterator = const MCPhysReg *;
4847
using const_iterator = const MCPhysReg *;
49-
using sc_iterator = const TargetRegisterClass* const *;
5048

5149
// Instance variables filled by tablegen, do not use!
5250
const MCRegisterClass *MC;
@@ -67,7 +65,8 @@ class TargetRegisterClass {
6765
/// Whether a combination of subregisters can cover every register in the
6866
/// class. See also the CoveredBySubRegs description in Target.td.
6967
const bool CoveredBySubRegs;
70-
const sc_iterator SuperClasses;
68+
const unsigned *SuperClasses;
69+
const uint16_t SuperClassesSize;
7170
ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
7271

7372
/// Return the register class ID number.
@@ -175,18 +174,16 @@ class TargetRegisterClass {
175174
return SuperRegIndices;
176175
}
177176

178-
/// Returns a NULL-terminated list of super-classes. The
177+
/// Returns a list of super-classes. The
179178
/// classes are ordered by ID which is also a topological ordering from large
180179
/// to small classes. The list does NOT include the current class.
181-
sc_iterator getSuperClasses() const {
182-
return SuperClasses;
180+
ArrayRef<unsigned> superclasses() const {
181+
return ArrayRef(SuperClasses, SuperClassesSize);
183182
}
184183

185184
/// Return true if this TargetRegisterClass is a subset
186185
/// class of at least one other TargetRegisterClass.
187-
bool isASubClass() const {
188-
return SuperClasses[0] != nullptr;
189-
}
186+
bool isASubClass() const { return SuperClasses != nullptr; }
190187

191188
/// Returns the preferred order for allocating registers from this register
192189
/// class in MF. The raw order comes directly from the .td file and may

llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,30 +262,31 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,
262262
const TargetRegisterClass *
263263
ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
264264
const MachineFunction &MF) const {
265-
const TargetRegisterClass *Super = RC;
266-
TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
265+
unsigned SuperID = RC->getID();
266+
auto I = RC->superclasses().begin();
267+
auto E = RC->superclasses().end();
267268
do {
268-
switch (Super->getID()) {
269+
switch (SuperID) {
269270
case ARM::GPRRegClassID:
270271
case ARM::SPRRegClassID:
271272
case ARM::DPRRegClassID:
272273
case ARM::GPRPairRegClassID:
273-
return Super;
274+
return getRegClass(SuperID);
274275
case ARM::QPRRegClassID:
275276
case ARM::QQPRRegClassID:
276277
case ARM::QQQQPRRegClassID:
277278
if (MF.getSubtarget<ARMSubtarget>().hasNEON())
278-
return Super;
279+
return getRegClass(SuperID);
279280
break;
280281
case ARM::MQPRRegClassID:
281282
case ARM::MQQPRRegClassID:
282283
case ARM::MQQQQPRRegClassID:
283284
if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps())
284-
return Super;
285+
return getRegClass(SuperID);
285286
break;
286287
}
287-
Super = *I++;
288-
} while (Super);
288+
SuperID = (I != E) ? *I++ : ~0U;
289+
} while (SuperID != ~0U);
289290
return RC;
290291
}
291292

llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,9 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
431431
return WSub[GenIdx];
432432
}
433433

434-
if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
435-
return getHexagonSubRegIndex(*SuperRC, GenIdx);
434+
if (!RC.superclasses().empty())
435+
return getHexagonSubRegIndex(*getRegClass(*RC.superclasses().begin()),
436+
GenIdx);
436437

437438
llvm_unreachable("Invalid register class");
438439
}

llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -692,21 +692,23 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
692692
InflateGPRC++;
693693
}
694694

695-
for (const auto *I = RC->getSuperClasses(); *I; ++I) {
696-
if (getRegSizeInBits(**I) != getRegSizeInBits(*RC))
695+
for (unsigned SuperID : RC->superclasses()) {
696+
if (getRegSizeInBits(*getRegClass(SuperID)) != getRegSizeInBits(*RC))
697697
continue;
698698

699-
switch ((*I)->getID()) {
699+
switch (SuperID) {
700700
case PPC::VSSRCRegClassID:
701-
return Subtarget.hasP8Vector() ? *I : DefaultSuperclass;
701+
return Subtarget.hasP8Vector() ? getRegClass(SuperID)
702+
: DefaultSuperclass;
702703
case PPC::VSFRCRegClassID:
703704
case PPC::VSRCRegClassID:
704-
return *I;
705+
return getRegClass(SuperID);
705706
case PPC::VSRpRCRegClassID:
706-
return Subtarget.pairedVectorMemops() ? *I : DefaultSuperclass;
707+
return Subtarget.pairedVectorMemops() ? getRegClass(SuperID)
708+
: DefaultSuperclass;
707709
case PPC::ACCRCRegClassID:
708710
case PPC::UACCRCRegClassID:
709-
return Subtarget.hasMMA() ? *I : DefaultSuperclass;
711+
return Subtarget.hasMMA() ? getRegClass(SuperID) : DefaultSuperclass;
710712
}
711713
}
712714
}

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
123123
const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
124124

125125
const TargetRegisterClass *Super = RC;
126-
TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
126+
auto I = RC->superclasses().begin();
127+
auto E = RC->superclasses().end();
127128
do {
128129
switch (Super->getID()) {
129130
case X86::FR32RegClassID:
@@ -172,7 +173,12 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
172173
if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
173174
return Super;
174175
}
175-
Super = *I++;
176+
if (I != E) {
177+
Super = getRegClass(*I);
178+
++I;
179+
} else {
180+
Super = nullptr;
181+
}
176182
} while (Super);
177183
return RC;
178184
}

llvm/unittests/CodeGen/MachineInstrTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ TEST(MachineInstrTest, SpliceOperands) {
584584
// test tied operands
585585
MCRegisterClass MRC{
586586
0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
587-
TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
587+
TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0, 0};
588588
// MachineRegisterInfo will be very upset if these registers aren't
589589
// allocatable.
590590
assert(RC.isAllocatable() && "unusable TargetRegisterClass");

llvm/utils/TableGen/RegisterInfoEmitter.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,9 +1286,6 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
12861286
}
12871287
OS << "};\n";
12881288

1289-
OS << "\nstatic const TargetRegisterClass *const "
1290-
<< "NullRegClasses[] = { nullptr };\n\n";
1291-
12921289
// Emit register class bit mask tables. The first bit mask emitted for a
12931290
// register class, RC, is the set of sub-classes, including RC itself.
12941291
//
@@ -1340,19 +1337,18 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
13401337
SuperRegIdxSeqs.emit(OS, printSubRegIndex);
13411338
OS << "};\n\n";
13421339

1343-
// Emit NULL terminated super-class lists.
1340+
// Emit super-class lists.
13441341
for (const auto &RC : RegisterClasses) {
13451342
ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
13461343

1347-
// Skip classes without supers. We can reuse NullRegClasses.
1344+
// Skip classes without supers.
13481345
if (Supers.empty())
13491346
continue;
13501347

1351-
OS << "static const TargetRegisterClass *const " << RC.getName()
1352-
<< "Superclasses[] = {\n";
1348+
OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n";
13531349
for (const auto *Super : Supers)
1354-
OS << " &" << Super->getQualifiedName() << "RegClass,\n";
1355-
OS << " nullptr\n};\n\n";
1350+
OS << " " << Super->getQualifiedIdName() << ",\n";
1351+
OS << "};\n\n";
13561352
}
13571353

13581354
// Emit methods.
@@ -1406,9 +1402,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
14061402
<< (RC.CoveredBySubRegs ? "true" : "false")
14071403
<< ", /* CoveredBySubRegs */\n ";
14081404
if (RC.getSuperClasses().empty())
1409-
OS << "NullRegClasses,\n ";
1405+
OS << "nullptr, ";
14101406
else
1411-
OS << RC.getName() << "Superclasses,\n ";
1407+
OS << RC.getName() << "Superclasses, ";
1408+
OS << RC.getSuperClasses().size() << ",\n ";
14121409
if (RC.AltOrderSelect.empty())
14131410
OS << "nullptr\n";
14141411
else

0 commit comments

Comments
 (0)