[llvm-branch-commits] [llvm] TableGen: Match each instregex pattern only once (PR #235485)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 25 09:41:59 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/235485
Scheduling models use the same instregex patterns many times, and every
use matched the pattern against the instruction names again. AArch64
evaluates 12501 patterns, only 4344 of them distinct, for a total of 34
million regex matches. Cache the instructions each pattern matches, so a
repeated pattern costs a lookup.
AArch64GenSubtargetInfo.inc tablegen run:
Gigainstructions Gigacycles CPU seconds
Before 67.9 31.1 9.4
After 44.6 (-34.3%) 18.8 (-39.6%) 5.7 (-39.1%)
All 366 tablegen runs in an LLVM build with all targets:
Gigainstructions Gigacycles CPU seconds
Before 2252 1409 499
After 2188 (-2.8%) 1380 (-2.1%) 489 (-1.9%)
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 178aea6a00f56574b9832b8daf3cf9973c3cfd99 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 22 Oct 2026 17:26:28 -0700
Subject: [PATCH] TableGen: Match each instregex pattern only once
Scheduling models use the same instregex patterns many times, and every
use matched the pattern against the instruction names again. AArch64
evaluates 12501 patterns, only 4344 of them distinct, for a total of 34
million regex matches. Cache the instructions each pattern matches, so a
repeated pattern costs a lookup.
AArch64GenSubtargetInfo.inc tablegen run:
Gigainstructions Gigacycles CPU seconds
Before 67.9 31.1 9.4
After 44.6 (-34.3%) 18.8 (-39.6%) 5.7 (-39.1%)
All 366 tablegen runs in an LLVM build with all targets:
Gigainstructions Gigacycles CPU seconds
Before 2252 1409 499
After 2188 (-2.8%) 1380 (-2.1%) 489 (-1.9%)
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
.../utils/TableGen/Common/CodeGenSchedule.cpp | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index 0a5fcc68b7bfc..f412663a11663 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -52,6 +52,10 @@ struct InstrsOp : public SetTheory::Operator {
// (instregex "OpcPat",...) Find all instructions matching an opcode pattern.
struct InstRegexOp : public SetTheory::Operator {
const CodeGenTarget &Target;
+ // The instructions matching each pattern. Scheduling models repeat many
+ // patterns, so only match each one once.
+ StringMap<std::vector<const Record *>> Matches;
+
InstRegexOp(const CodeGenTarget &t) : Target(t) {}
/// Remove any text inside of parentheses from S.
@@ -90,6 +94,13 @@ struct InstRegexOp : public SetTheory::Operator {
PrintFatalError(Loc, "instregex requires pattern string: " +
Expr->getAsString());
StringRef Original = SI->getValue();
+ auto [It, Inserted] = Matches.try_emplace(Original);
+ std::vector<const Record *> &Matched = It->second;
+ if (!Inserted) {
+ Elts.insert(Matched.begin(), Matched.end());
+ continue;
+ }
+
// Drop an explicit ^ anchor to not interfere with prefix search.
bool HadAnchor = Original.consume_front("^");
@@ -130,16 +141,12 @@ struct InstRegexOp : public SetTheory::Operator {
Regexpr = Regex(pat);
}
- int NumMatches = 0;
-
// The generic opcodes are unsorted, handle them manually.
for (auto *Inst : Generics) {
StringRef InstName = Inst->getName();
if (InstName.starts_with(Prefix) &&
- (!Regexpr || Regexpr->match(InstName.substr(Prefix.size())))) {
- Elts.insert(Inst->TheDef);
- NumMatches++;
- }
+ (!Regexpr || Regexpr->match(InstName.substr(Prefix.size()))))
+ Matched.push_back(Inst->TheDef);
}
// Target instructions are split into two ranges: pseudo instructions
@@ -162,16 +169,15 @@ struct InstRegexOp : public SetTheory::Operator {
// Check if there's a regex that needs to be checked.
const auto HandleNonGeneric = [&](const CodeGenInstruction *Inst) {
StringRef InstName = Inst->getName();
- if (!Regexpr || Regexpr->match(InstName.substr(Prefix.size()))) {
- Elts.insert(Inst->TheDef);
- NumMatches++;
- }
+ if (!Regexpr || Regexpr->match(InstName.substr(Prefix.size())))
+ Matched.push_back(Inst->TheDef);
};
std::for_each(Range1.first, Range1.second, HandleNonGeneric);
std::for_each(Range2.first, Range2.second, HandleNonGeneric);
- if (0 == NumMatches)
+ if (Matched.empty())
PrintFatalError(Loc, "instregex has no matches: " + Original);
+ Elts.insert(Matched.begin(), Matched.end());
}
}
};
More information about the llvm-branch-commits
mailing list