Skip to content

[TableGen][CodeGen] Give every leaf register a unique regunit #139526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions llvm/test/TableGen/SubRegsAndAliases.td
Original file line number Diff line number Diff line change
@@ -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
27 changes: 11 additions & 16 deletions llvm/utils/TableGen/Common/CodeGenRegisters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions llvm/utils/TableGen/RegisterInfoEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}

Expand Down