[llvm-branch-commits] [llvm] TableGen: Look up sub-register index compositions in an array (PR #232818)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 17 01:29:58 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/232818
>From 1662c23ba91ff7088dc7d8a0ed9f9cf8c0661807 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 16 Oct 2026 05:42:31 -0700
Subject: [PATCH 1/2] TableGen: Look up sub-register index compositions in an
array
compose() looked up each composition in a std::map. It is called for
every super-register class set in extendSuperRegClasses, and by
addComposite. Sub-register indices are numbered densely, so also keep
each index's compositions in an array indexed by enum value. For
AMDGPU's 400 indices this is about 1 MB.
AMDGPU tablegen runs that build the register bank:
Gigainstructions Gigacycles CPU seconds
Before 746 474 148
After 721 (-3.4%) 446 (-6.1%) 139 (-5.8%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
llvm/utils/TableGen/Common/CodeGenRegisters.h | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index 333bc4aa07314..4b648db3c9103 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -99,9 +99,9 @@ class CodeGenSubRegIndex {
// Returns the subreg index that results from composing this with Idx.
// Returns NULL if this and Idx don't compose.
- CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const {
- CompMap::const_iterator I = Composed.find(Idx);
- return I == Composed.end() ? nullptr : I->second;
+ CodeGenSubRegIndex *compose(const CodeGenSubRegIndex *Idx) const {
+ return Idx->EnumValue < ComposedByIdx.size() ? ComposedByIdx[Idx->EnumValue]
+ : nullptr;
}
// Add a composite subreg index: this+A = B.
@@ -109,15 +109,20 @@ class CodeGenSubRegIndex {
CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, CodeGenSubRegIndex *B,
const CodeGenHwModes &CGH) {
assert(A && B);
- std::pair<CompMap::iterator, bool> Ins = Composed.try_emplace(A, B);
unsigned NumModes = CGH.getNumModeIds();
// An earlier identical call already added the ranges for every mode, so
// there is nothing left to do once B has an offset in all of them.
- if (!Ins.second && Ins.first->second == B &&
- B->hasOffsetInAllModes(NumModes))
+ if (compose(A) == B && B->hasOffsetInAllModes(NumModes))
return nullptr;
+ std::pair<CompMap::iterator, bool> Ins = Composed.try_emplace(A, B);
+ if (Ins.second) {
+ if (ComposedByIdx.size() <= A->EnumValue)
+ ComposedByIdx.resize(A->EnumValue + 1);
+ ComposedByIdx[A->EnumValue] = B;
+ }
+
// Synthetic subreg indices that aren't contiguous (for instance ARM
// register tuples) don't have a bit range, so it's OK to let
// B->Offset == -1. For the other cases, accumulate the offset and set
@@ -186,6 +191,8 @@ class CodeGenSubRegIndex {
bool OffsetInAllModes = false;
CompMap Composed;
+ // Composed indexed by the EnumValue of the first index, for compose().
+ SmallVector<CodeGenSubRegIndex *, 0> ComposedByIdx;
};
/// CodeGenRegister - Represents a register definition.
>From f499a0766a1582f7e04c04512c0110fd7259c2b8 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 17 Oct 2026 01:05:36 -0700
Subject: [PATCH 2/2] Return conflicting compositions from addComposite
immediately
Check for an existing composition up front: return a conflicting one
right away, instead of after updating B's ranges from a composition that
isn't recorded. This no longer needs the try_emplace result. The
generated code for all in-tree targets is unchanged, and the instruction
count is the same.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
llvm/utils/TableGen/Common/CodeGenRegisters.h | 22 ++++++++++++-------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index 4b648db3c9103..3666469f5726f 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -111,13 +111,19 @@ class CodeGenSubRegIndex {
assert(A && B);
unsigned NumModes = CGH.getNumModeIds();
- // An earlier identical call already added the ranges for every mode, so
- // there is nothing left to do once B has an offset in all of them.
- if (compose(A) == B && B->hasOffsetInAllModes(NumModes))
- return nullptr;
-
- std::pair<CompMap::iterator, bool> Ins = Composed.try_emplace(A, B);
- if (Ins.second) {
+ CodeGenSubRegIndex *Prev = compose(A);
+ if (Prev == B) {
+ // An earlier identical call already added the ranges for every mode, so
+ // there is nothing left to do once B has an offset in all of them.
+ if (B->hasOffsetInAllModes(NumModes))
+ return nullptr;
+ } else {
+ // Keep an existing conflicting composition, and return it.
+ if (Prev)
+ return Prev;
+
+ if (!Composed.try_emplace(A, B).second)
+ llvm_unreachable("ComposedByIdx out of sync with Composed");
if (ComposedByIdx.size() <= A->EnumValue)
ComposedByIdx.resize(A->EnumValue + 1);
ComposedByIdx[A->EnumValue] = B;
@@ -153,7 +159,7 @@ class CodeGenSubRegIndex {
BRange.Size = ARange.Size;
}
- return (Ins.second || Ins.first->second == B) ? nullptr : Ins.first->second;
+ return nullptr;
}
// Update the composite maps of components specified in 'ComposedOf'.
More information about the llvm-branch-commits
mailing list