From 03f02eaf3a4fd8e741f5421f46d091fe2818a10d Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Mon, 12 May 2025 11:01:42 +0100 Subject: [PATCH] [TableGen][CodeGen] Give every leaf register a unique regunit Give every leaf register a unique regunit, even if it has ad hoc aliases. Previously only leaf registers *without* ad hoc aliases would get a unique regunit, but that caused situations where regunits could not be used to distinguish a register from its subregs. For example: - Registers A and B alias. They both get regunit 0 only. - Register C has subregs A and B. It inherits regunits from its subregs, so it also gets regunit 0 only. After this fix, registers A and B will get a unique regunit in addition to the regunit representing the alias, for example: - A will get regunits 0 and 1. - B will get regunits 0 and 2. - C will get regunits 0, 1 and 2. --- llvm/test/TableGen/SubRegsAndAliases.td | 80 +++++++++++++++++++ .../TableGen/Common/CodeGenRegisters.cpp | 27 +++---- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 2 + 3 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 llvm/test/TableGen/SubRegsAndAliases.td diff --git a/llvm/test/TableGen/SubRegsAndAliases.td b/llvm/test/TableGen/SubRegsAndAliases.td new file mode 100644 index 0000000000000..ec450f8945b49 --- /dev/null +++ b/llvm/test/TableGen/SubRegsAndAliases.td @@ -0,0 +1,80 @@ +// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s +include "llvm/Target/Target.td" +def TestTarget : Target; + +def lo : SubRegIndex<32, 0>; +def hi : SubRegIndex<32, 32>; + +// One superreg with two subregs. +def Alo : Register<"">; +def Ahi : Register<"">; +def A : Register<""> { + let SubRegs = [Alo, Ahi]; + let SubRegIndices = [lo, hi]; +} + +// Same but the subregs alias. +def Blo : Register<"">; +def Bhi : Register<""> { + let Aliases = [Blo]; +} +def B : Register<""> { + let SubRegs = [Blo, Bhi]; + let SubRegIndices = [lo, hi]; +} + +// Same but the superreg has an alias. +def Clo : Register<"">; +def Chi : Register<"">; +def D : Register<"">; +def C : Register<""> { + let SubRegs = [Clo, Chi]; + let SubRegIndices = [lo, hi]; + let Aliases = [D]; +} + +def TestRC : RegisterClass<"Test", [i64], 0, (add A, B)>; + +// CHECK-LABEL: Register A: +// CHECK: SubReg hi = Ahi +// CHECK: SubReg lo = Alo +// CHECK: RegUnit 0 +// CHECK: RegUnit 1 + +// CHECK-LABEL: Register Ahi: +// CHECK: RegUnit 1 + +// CHECK-LABEL: Register Alo: +// CHECK: RegUnit 0 + +// CHECK-LABEL: Register B: +// CHECK: SubReg hi = Bhi +// CHECK: SubReg lo = Blo +// CHECK: RegUnit 2 +// CHECK: RegUnit 3 +// CHECK: RegUnit 4 + +// CHECK-LABEL: Register Bhi: +// CHECK: RegUnit 3 +// CHECK: RegUnit 4 + +// CHECK-LABEL: Register Blo: +// CHECK: RegUnit 2 +// CHECK: RegUnit 3 + +// CHECK-LABEL: Register C: +// CHECK: SubReg hi = Chi +// CHECK: SubReg lo = Clo +// CHECK: RegUnit 5 +// CHECK: RegUnit 6 +// CHECK: RegUnit 7 + +// CHECK-LABEL: Register Chi: +// CHECK: RegUnit 6 + +// CHECK-LABEL: Register Clo: +// CHECK: RegUnit 5 + +// CHECK-LABEL: Register D: +// CHECK: RegUnit 7 +// CHECK: RegUnit 8 diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp index 639f94f79ecd7..3b7604a05fa88 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp @@ -414,16 +414,17 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) { // Initialize RegUnitList. Because getSubRegs is called recursively, this // processes the register hierarchy in postorder. - // - // Inherit all sub-register units. It is good enough to look at the explicit - // sub-registers, the other registers won't contribute any more units. - for (const CodeGenRegister *SR : ExplicitSubRegs) - RegUnits |= SR->RegUnits; - - // Absent any ad hoc aliasing, we create one register unit per leaf register. - // These units correspond to the maximal cliques in the register overlap - // graph which is optimal. - // + if (ExplicitSubRegs.empty()) { + // Create one register unit per leaf register. These units correspond to the + // maximal cliques in the register overlap graph which is optimal. + RegUnits.set(RegBank.newRegUnit(this)); + } else { + // Inherit all sub-register units. It is good enough to look at the explicit + // sub-registers, the other registers won't contribute any more units. + for (const CodeGenRegister *SR : ExplicitSubRegs) + RegUnits |= SR->RegUnits; + } + // When there is ad hoc aliasing, we simply create one unit per edge in the // undirected ad hoc aliasing graph. Technically, we could do better by // identifying maximal cliques in the ad hoc graph, but cliques larger than 2 @@ -440,12 +441,6 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) { AR->RegUnits.set(Unit); } - // Finally, create units for leaf registers without ad hoc aliases. Note that - // a leaf register with ad hoc aliases doesn't get its own unit - it isn't - // necessary. This means the aliasing leaf registers can share a single unit. - if (RegUnits.empty()) - RegUnits.set(RegBank.newRegUnit(this)); - // We have now computed the native register units. More may be adopted later // for balancing purposes. NativeRegUnits = RegUnits; diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 98f0d7eaaff38..c2c6ab1f77aaa 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1934,6 +1934,8 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) { OS << "\tSubReg " << SubIdx->getName() << " = " << SubReg->getName() << '\n'; } + for (unsigned U : R.getNativeRegUnits()) + OS << "\tRegUnit " << U << '\n'; } }