https://github.com/arsenm created
https://github.com/llvm/llvm-project/pull/231083
Lists, dags, bits and arguments made only of leaf values always resolve
to themselves, but resolving them still walked every element. Record
this when they are created and return early.
Gigainstructions executed by llvm-tblgen --null-backend
before after
AMDGPU.td 79.12 71.73 -9.3%
X86.td 6.25 6.12 -2.1%
AArch64.td 3.40 3.28 -3.7%
RISCV.td 8.34 8.19 -1.8%
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
<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 3ab5ef20a7a4440a78df886a38d56babcb574461 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Sun, 11 Oct 2026 02:44:19 -0700
Subject: [PATCH] TableGen: Skip resolving values that cannot change
Lists, dags, bits and arguments made only of leaf values always resolve
to themselves, but resolving them still walked every element. Record
this when they are created and return early.
Gigainstructions executed by llvm-tblgen --null-backend
before after
AMDGPU.td 79.12 71.73 -9.3%
X86.td 6.25 6.12 -2.1%
AArch64.td 3.40 3.28 -3.7%
RISCV.td 8.34 8.19 -1.8%
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
llvm/include/llvm/TableGen/Record.h | 20 ++++++++++++++++++--
llvm/lib/TableGen/Record.cpp | 19 +++++++++++++++++++
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/TableGen/Record.h
b/llvm/include/llvm/TableGen/Record.h
index 2d73260a80799..01ad1287dccc1 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -336,6 +336,9 @@ class Init {
protected:
uint8_t Opc; // Used by UnOpInit, BinOpInit, and TernOpInit
+ /// Set if resolveReferences returns this value unchanged with any resolver.
+ bool TriviallyResolved;
+
private:
virtual void anchor();
@@ -343,11 +346,22 @@ class Init {
/// Get the kind (type) of the value.
InitKind getKind() const { return Kind; }
+ /// Return true if \p K is a value kind that cannot contain references.
+ static bool isLeafKind(InitKind K) {
+ return K == IK_BitInit || K == IK_DefInit || K == IK_IntInit ||
+ K == IK_StringInit || K == IK_UnsetInit;
+ }
+
+ /// Return true if resolveReferences returns this value unchanged with any
+ /// resolver. This is a cheap, conservative subset of isConcrete().
+ bool isTriviallyResolved() const { return TriviallyResolved; }
+
/// Get the record keeper that initialized this Init.
RecordKeeper &getRecordKeeper() const;
protected:
- explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {}
+ explicit Init(InitKind K, uint8_t Opc = 0)
+ : Kind(K), Opc(Opc), TriviallyResolved(isLeafKind(K)) {}
public:
Init(const Init &) = delete;
@@ -503,7 +517,9 @@ class ArgumentInit final : public Init, public
FoldingSetNode {
protected:
explicit ArgumentInit(const Init *Value, ArgAuxType Aux)
- : Init(IK_ArgumentInit), Value(Value), Aux(Aux) {}
+ : Init(IK_ArgumentInit), Value(Value), Aux(Aux) {
+ TriviallyResolved = Value->isTriviallyResolved();
+ }
public:
ArgumentInit(const ArgumentInit &) = delete;
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 62664ef78d992..9903e05511c81 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -393,6 +393,9 @@ const ArgumentInit *ArgumentInit::get(const Init *Value,
ArgAuxType Aux) {
}
const Init *ArgumentInit::resolveReferences(Resolver &R) const {
+ if (isTriviallyResolved())
+ return this;
+
const Init *NewValue = Value->resolveReferences(R);
if (NewValue != Value)
return cloneWithValue(NewValue);
@@ -424,6 +427,8 @@ BitsInit::BitsInit(RecordKeeper &RK, ArrayRef<const Init *>
Bits)
: TypedInit(IK_BitsInit, BitsRecTy::get(RK, Bits.size())),
NumBits(Bits.size()) {
llvm::uninitialized_copy(Bits, getTrailingObjects());
+ // Other values are converted to a bit when resolved.
+ TriviallyResolved = all_of(Bits, IsaPred<BitInit, UnsetInit>);
}
BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<const Init *> Bits) {
@@ -517,6 +522,9 @@ std::string BitsInit::getAsString() const {
// resolveReferences - If there are any field references that refer to fields
// that have been filled in, we can propagate the values now.
const Init *BitsInit::resolveReferences(Resolver &R) const {
+ if (isTriviallyResolved())
+ return this;
+
bool Changed = false;
SmallVector<const Init *, 16> NewBits(getNumBits());
@@ -649,6 +657,8 @@ ListInit::ListInit(ArrayRef<const Init *> Elements, const
RecTy *EltTy)
: TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
NumElements(Elements.size()) {
llvm::uninitialized_copy(Elements, getTrailingObjects());
+ TriviallyResolved = all_of(
+ Elements, [](const Init *Elt) { return Elt->isTriviallyResolved(); });
}
const ListInit *ListInit::get(ArrayRef<const Init *> Elements,
@@ -706,6 +716,9 @@ const Record *ListInit::getElementAsRecord(unsigned Idx)
const {
}
const Init *ListInit::resolveReferences(Resolver &R) const {
+ if (isTriviallyResolved())
+ return this;
+
SmallVector<const Init *, 8> Resolved;
Resolved.reserve(size());
bool Changed = false;
@@ -2608,6 +2621,9 @@ DagInit::DagInit(const Init *V, const StringInit *VN,
ValName(VN), NumArgs(Args.size()) {
llvm::uninitialized_copy(Args, getTrailingObjects<const Init *>());
llvm::uninitialized_copy(ArgNames, getTrailingObjects<const StringInit *>());
+ TriviallyResolved =
+ V->isTriviallyResolved() &&
+ all_of(Args, [](const Init *Arg) { return Arg->isTriviallyResolved(); });
}
const DagInit *DagInit::get(const Init *V, const StringInit *VN,
@@ -2657,6 +2673,9 @@ std::optional<unsigned> DagInit::getArgNo(StringRef Name)
const {
}
const Init *DagInit::resolveReferences(Resolver &R) const {
+ if (isTriviallyResolved())
+ return this;
+
SmallVector<const Init *, 8> NewArgs;
NewArgs.reserve(arg_size());
bool ArgsChanged = false;
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits