[llvm-branch-commits] [llvm] TableGen: Compute register sizes once for the sub-register size check (PR #234802)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 22 16:46:55 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/234802
checkSubRegIndexSizes found the size of each register by scanning every
register class for one containing it, about 18 million class membership
tests for AMDGPU. Compute the size of all registers in one pass over
the members of each register class instead, and pass it in.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 578 355 113
After 576 (-0.2%) 345 (-2.8%) 110 (-2.4%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
>From bfacc3afd3ebb02756e166f492f82c9f9856437c Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 22 Oct 2026 13:41:40 -0700
Subject: [PATCH] TableGen: Compute register sizes once for the sub-register
size check
checkSubRegIndexSizes found the size of each register by scanning every
register class for one containing it, about 18 million class membership
tests for AMDGPU. Compute the size of all registers in one pass over
the members of each register class instead, and pass it in.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 578 355 113
After 576 (-0.2%) 345 (-2.8%) 110 (-2.4%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
.../TableGen/Common/CodeGenRegisters.cpp | 50 ++++++++++---------
llvm/utils/TableGen/Common/CodeGenRegisters.h | 5 +-
2 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 1674db63afb72..0cbd1855429e3 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -399,32 +399,12 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
// strided/spaced register tuples (e.g. ARM's Tuples3DSpc,
// [dsub_0, dsub_2, dsub_4]) deliberately place sub-registers at non-adjacent
// offsets that extend past the nominal size, and are not bugs.
-void CodeGenRegister::checkSubRegIndexSizes(CodeGenRegBank &RegBank) const {
+void CodeGenRegister::checkSubRegIndexSizes(unsigned ParentSize) const {
// Only registers that are covered by their sub-registers promise to be fully
// tiled by them; for those an explicit SubRegIndex extending past the
// register is a genuine bug. A register that is not covered by its
// sub-registers makes no such promise, so don't second-guess its layout.
- if (!CoveredBySubRegs)
- return;
-
- // This register's own bit size is the largest register class containing it.
- unsigned ParentSize = 0;
- for (const auto &RC : RegBank.getRegClasses()) {
- if (!RC.contains(this) || !RC.RSI.hasDefault())
- continue;
- // Only trust a register-class size that is backed by a real value type.
- // An 'untyped' class carries a placeholder size, not the register's bit
- // width, so its size cannot be compared against sub-register extents.
- // getValueTypes() is indexed by HwMode; DefaultMode is the first entry.
- ArrayRef<ValueTypeByHwMode> VTs = RC.getValueTypes();
- if (VTs.empty())
- continue;
- const ValueTypeByHwMode &VT = VTs[DefaultMode];
- if (!VT.isSimple() || VT.getSimple() == MVT::Untyped)
- continue;
- ParentSize = std::max(ParentSize, RC.RSI.get(DefaultMode).RegSize);
- }
- if (!ParentSize)
+ if (!CoveredBySubRegs || !ParentSize)
return;
// Collect the explicit sub-register (offset, size) ranges. Bail on any
@@ -1399,9 +1379,31 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
RegCategories.emplace_back(*this, R);
// Now that register classes (and their sizes) are built, check that no
- // explicit SubRegIndex makes a sub-register overflow its register.
+ // explicit SubRegIndex makes a sub-register overflow its register. Each
+ // register's own bit size is the largest register class containing it.
+ std::vector<unsigned> ParentSizes(Registers.size());
+ for (const auto &RC : RegClasses) {
+ if (!RC.RSI.hasDefault())
+ continue;
+ // Only trust a register-class size that is backed by a real value type.
+ // An 'untyped' class carries a placeholder size, not the register's bit
+ // width, so its size cannot be compared against sub-register extents.
+ // getValueTypes() is indexed by HwMode; DefaultMode is the first entry.
+ ArrayRef<ValueTypeByHwMode> VTs = RC.getValueTypes();
+ if (VTs.empty())
+ continue;
+ const ValueTypeByHwMode &VT = VTs[DefaultMode];
+ if (!VT.isSimple() || VT.getSimple() == MVT::Untyped)
+ continue;
+ unsigned Size = RC.RSI.get(DefaultMode).RegSize;
+ for (const CodeGenRegister *Reg : RC.getMembers()) {
+ unsigned &ParentSize = ParentSizes[getRegIndex(Reg)];
+ ParentSize = std::max(ParentSize, Size);
+ }
+ }
+
for (const auto &Reg : Registers)
- Reg.checkSubRegIndexSizes(*this);
+ Reg.checkSubRegIndexSizes(ParentSizes[getRegIndex(&Reg)]);
}
// Create a synthetic CodeGenSubRegIndex without a corresponding Record.
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index 8bc3447453acc..4af1351aed65b 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -246,8 +246,9 @@ class CodeGenRegister {
// Diagnose an explicit SubRegIndex whose declared size makes a sub-register
// extend past the register that contains it (an oversized lane mask that
- // silently corrupts sub-register liveness and spilling). See the definition.
- void checkSubRegIndexSizes(CodeGenRegBank &) const;
+ // silently corrupts sub-register liveness and spilling). ParentSize is the
+ // size of the register, or 0 if it is unknown. See the definition.
+ void checkSubRegIndexSizes(unsigned ParentSize) const;
SubRegArrayRef getSubRegs() const {
assert(SuperRegsComplete && "Must precompute super-registers");
More information about the llvm-branch-commits
mailing list