Skip to content

Commit d416289

Browse files
authored
[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.
1 parent 1dc6ad0 commit d416289

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,14 @@ TreePattern::TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
29222922
Trees.push_back(ParseTreePattern(Pat, ""));
29232923
}
29242924

2925+
TreePattern::TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
2926+
ArrayRef<const StringInit *> ArgNames, bool isInput,
2927+
CodeGenDAGPatterns &cdp)
2928+
: TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
2929+
Infer(*this) {
2930+
Trees.push_back(ParseRootlessTreePattern(Args, ArgNames));
2931+
}
2932+
29252933
TreePattern::TreePattern(const Record *TheRec, TreePatternNodePtr Pat,
29262934
bool isInput, CodeGenDAGPatterns &cdp)
29272935
: TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
@@ -2950,6 +2958,19 @@ void TreePattern::ComputeNamedNodes(TreePatternNode &N) {
29502958
ComputeNamedNodes(Child);
29512959
}
29522960

2961+
TreePatternNodePtr
2962+
TreePattern::ParseRootlessTreePattern(ArrayRef<const Init *> Args,
2963+
ArrayRef<const StringInit *> ArgNames) {
2964+
std::vector<TreePatternNodePtr> Children;
2965+
2966+
for (auto [Arg, ArgName] : llvm::zip_equal(Args, ArgNames)) {
2967+
StringRef NameStr = ArgName ? ArgName->getValue() : "";
2968+
Children.push_back(ParseTreePattern(Arg, NameStr));
2969+
}
2970+
2971+
return makeIntrusiveRefCnt<TreePatternNode>(nullptr, std::move(Children), 1);
2972+
}
2973+
29532974
TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
29542975
StringRef OpName) {
29552976
RecordKeeper &RK = TheInit->getRecordKeeper();
@@ -3487,20 +3508,12 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
34873508
ArrayRef<const Record *> DefaultOps =
34883509
Records.getAllDerivedDefinitions("OperandWithDefaultOps");
34893510

3490-
// Find some SDNode.
3491-
assert(!SDNodes.empty() && "No SDNodes parsed?");
3492-
const Init *SomeSDNode = SDNodes.begin()->first->getDefInit();
3493-
34943511
for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
34953512
const DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
34963513

3497-
// Clone the DefaultInfo dag node, changing the operator from 'ops' to
3498-
// SomeSDnode so that we can parse this.
3499-
const DagInit *DI = DagInit::get(SomeSDNode, DefaultInfo->getArgs(),
3500-
DefaultInfo->getArgNames());
3501-
35023514
// Create a TreePattern to parse this.
3503-
TreePattern P(DefaultOps[i], DI, false, *this);
3515+
TreePattern P(DefaultOps[i], DefaultInfo->getArgs(),
3516+
DefaultInfo->getArgNames(), false, *this);
35043517
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
35053518

35063519
// Copy the operands over into a DAGDefaultOperand.

llvm/utils/TableGen/Common/CodeGenDAGPatterns.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,9 @@ class TreePattern {
917917
CodeGenDAGPatterns &ise);
918918
TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
919919
CodeGenDAGPatterns &ise);
920+
TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
921+
ArrayRef<const StringInit *> ArgNames, bool isInput,
922+
CodeGenDAGPatterns &ise);
920923
TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput,
921924
CodeGenDAGPatterns &ise);
922925

@@ -981,6 +984,9 @@ class TreePattern {
981984

982985
private:
983986
TreePatternNodePtr ParseTreePattern(const Init *DI, StringRef OpName);
987+
TreePatternNodePtr
988+
ParseRootlessTreePattern(ArrayRef<const Init *> Args,
989+
ArrayRef<const StringInit *> ArgNames);
984990
void ComputeNamedNodes();
985991
void ComputeNamedNodes(TreePatternNode &N);
986992
};

0 commit comments

Comments
 (0)