[llvm] d416289 - [TableGen] Eliminate the dependency on SDNode definition order (#168745)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 24 03:59:24 PST 2025
Author: Anatoly Trosinenko
Date: 2025-11-24T14:59:19+03:00
New Revision: d41628941743b778432e30d93f25028ffb375fbc
URL: https://github.com/llvm/llvm-project/commit/d41628941743b778432e30d93f25028ffb375fbc
DIFF: https://github.com/llvm/llvm-project/commit/d41628941743b778432e30d93f25028ffb375fbc.diff
LOG: [TableGen] Eliminate the dependency on SDNode definition order (#168745)
Fix the dependency of `CodeGenDAGPatterns::ParseDefaultOperands()` on
the particular order of SDNode definitions. Implicit usage of the first
definition as a placeholder makes `llvm-tblgen -gen-dag-isel` fail if
that SDNode is not usable as an output pattern operator and an instance
of `OperandWithDefaultOps` is used in a pattern.
Presently, each `OperandWithDefaultOps` record is processed by
constructing an instance of TreePattern from its `DefaultOps` argument
that has the form `(ops ...)`. Even though the result of processing the
root operator of that DAG is not inspected by `ParseDefaultOperands()`
function itself, that operator has to be supported by the underlying
`TreePattern::ParseTreePattern()` function. For that reason, a temporary
DAG is created by replacing the root operator of `DefaultOps` argument
with the first SDNode defined, which is usually `def imm : ...` defined
in `TargetSelectionDAG.td` file.
This results in misleading errors being reported when implementing new
`SDNode` types, if the new definition happens to be added before the
`def imm : ...` line. The error is reported by several test cases
executed by `check-llvm` target, as well as by the regular build, if one
of the enabled targets inherit one of its operand types from
`OperandWithDefaultOps`:
OptionalIntOperand: ../llvm/test/TableGen/DAGDefaultOps.td:28:5: error: In OptionalIntOperand: Cannot use 'unexpected_node' in an output pattern!
def OptionalIntOperand: OperandWithDefaultOps<i32, (ops (i32 0))>;
This commit implements a dedicated constructor of `TreePattern` to be
used if the caller does not care about the particular root operator of
the pattern being processed.
Added:
Modified:
llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 2bea0ca2bfabb..8251c8983cc80 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -2922,6 +2922,14 @@ TreePattern::TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
Trees.push_back(ParseTreePattern(Pat, ""));
}
+TreePattern::TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
+ ArrayRef<const StringInit *> ArgNames, bool isInput,
+ CodeGenDAGPatterns &cdp)
+ : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
+ Infer(*this) {
+ Trees.push_back(ParseRootlessTreePattern(Args, ArgNames));
+}
+
TreePattern::TreePattern(const Record *TheRec, TreePatternNodePtr Pat,
bool isInput, CodeGenDAGPatterns &cdp)
: TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
@@ -2950,6 +2958,19 @@ void TreePattern::ComputeNamedNodes(TreePatternNode &N) {
ComputeNamedNodes(Child);
}
+TreePatternNodePtr
+TreePattern::ParseRootlessTreePattern(ArrayRef<const Init *> Args,
+ ArrayRef<const StringInit *> ArgNames) {
+ std::vector<TreePatternNodePtr> Children;
+
+ for (auto [Arg, ArgName] : llvm::zip_equal(Args, ArgNames)) {
+ StringRef NameStr = ArgName ? ArgName->getValue() : "";
+ Children.push_back(ParseTreePattern(Arg, NameStr));
+ }
+
+ return makeIntrusiveRefCnt<TreePatternNode>(nullptr, std::move(Children), 1);
+}
+
TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
StringRef OpName) {
RecordKeeper &RK = TheInit->getRecordKeeper();
@@ -3487,20 +3508,12 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
ArrayRef<const Record *> DefaultOps =
Records.getAllDerivedDefinitions("OperandWithDefaultOps");
- // Find some SDNode.
- assert(!SDNodes.empty() && "No SDNodes parsed?");
- const Init *SomeSDNode = SDNodes.begin()->first->getDefInit();
-
for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
const DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
- // Clone the DefaultInfo dag node, changing the operator from 'ops' to
- // SomeSDnode so that we can parse this.
- const DagInit *DI = DagInit::get(SomeSDNode, DefaultInfo->getArgs(),
- DefaultInfo->getArgNames());
-
// Create a TreePattern to parse this.
- TreePattern P(DefaultOps[i], DI, false, *this);
+ TreePattern P(DefaultOps[i], DefaultInfo->getArgs(),
+ DefaultInfo->getArgNames(), false, *this);
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
// Copy the operands over into a DAGDefaultOperand.
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index 633327e2f74e5..9a67933013c1c 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -917,6 +917,9 @@ class TreePattern {
CodeGenDAGPatterns &ise);
TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
CodeGenDAGPatterns &ise);
+ TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
+ ArrayRef<const StringInit *> ArgNames, bool isInput,
+ CodeGenDAGPatterns &ise);
TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput,
CodeGenDAGPatterns &ise);
@@ -981,6 +984,9 @@ class TreePattern {
private:
TreePatternNodePtr ParseTreePattern(const Init *DI, StringRef OpName);
+ TreePatternNodePtr
+ ParseRootlessTreePattern(ArrayRef<const Init *> Args,
+ ArrayRef<const StringInit *> ArgNames);
void ComputeNamedNodes();
void ComputeNamedNodes(TreePatternNode &N);
};
More information about the llvm-commits
mailing list