summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-03-24 19:36:51 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-03-24 19:36:51 +0000
commit4717fd4c0faf454ff37f133709320d0cfec0da89 (patch)
treea0db547668fddbb2736d85d9cb0fc3fe2cacbc96
parent9c22886a0105241b7bdc0f77a61bcae36e586a41 (diff)
downloadllvm-4717fd4c0faf454ff37f133709320d0cfec0da89.tar.gz
llvm-4717fd4c0faf454ff37f133709320d0cfec0da89.tar.bz2
llvm-4717fd4c0faf454ff37f133709320d0cfec0da89.tar.xz
Allow TableGen DAG arguments to be just a name.
DAG arguments can optionally be named: (dag node, node:$name) With this change, the node is also optional: (dag node, node:$name, $name) The missing node is treated as an UnsetInit, so the above is equivalent to: (dag node, node:$name, ?:$name) This syntax is useful in output patterns where we currently require the types of variables to be repeated: def : Pat<(subc i32:$b, i32:$c), (SUBCCrr i32:$b, i32:$c)>; This is preferable: def : Pat<(subc i32:$b, i32:$c), (SUBCCrr $b, $c)>; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177843 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/TableGen/LangRef.rst2
-rw-r--r--lib/TableGen/TGParser.cpp40
-rw-r--r--test/TableGen/Dag.td12
3 files changed, 38 insertions, 16 deletions
diff --git a/docs/TableGen/LangRef.rst b/docs/TableGen/LangRef.rst
index c9e1efba03..bd28a9031d 100644
--- a/docs/TableGen/LangRef.rst
+++ b/docs/TableGen/LangRef.rst
@@ -286,7 +286,7 @@ given values.
.. productionlist::
SimpleValue: "(" `DagArg` `DagArgList` ")"
DagArgList: `DagArg` ("," `DagArg`)*
- DagArg: `Value` [":" `TokVarName`]
+ DagArg: `Value` [":" `TokVarName`] | `TokVarName`
The initial :token:`DagArg` is called the "operator" of the dag.
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index c4b48fe5e8..86ad2a6e3c 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -1547,29 +1547,39 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
/// ParseDagArgList - Parse the argument list for a dag literal expression.
///
-/// ParseDagArgList ::= Value (':' VARNAME)?
-/// ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)?
+/// DagArg ::= Value (':' VARNAME)?
+/// DagArg ::= VARNAME
+/// DagArgList ::= DagArg
+/// DagArgList ::= DagArgList ',' DagArg
std::vector<std::pair<llvm::Init*, std::string> >
TGParser::ParseDagArgList(Record *CurRec) {
std::vector<std::pair<llvm::Init*, std::string> > Result;
while (1) {
- Init *Val = ParseValue(CurRec);
- if (Val == 0) return std::vector<std::pair<llvm::Init*, std::string> >();
-
- // If the variable name is present, add it.
- std::string VarName;
- if (Lex.getCode() == tgtok::colon) {
- if (Lex.Lex() != tgtok::VarName) { // eat the ':'
- TokError("expected variable name in dag literal");
+ // DagArg ::= VARNAME
+ if (Lex.getCode() == tgtok::VarName) {
+ // A missing value is treated like '?'.
+ Result.push_back(std::make_pair(UnsetInit::get(), Lex.getCurStrVal()));
+ Lex.Lex();
+ } else {
+ // DagArg ::= Value (':' VARNAME)?
+ Init *Val = ParseValue(CurRec);
+ if (Val == 0)
return std::vector<std::pair<llvm::Init*, std::string> >();
- }
- VarName = Lex.getCurStrVal();
- Lex.Lex(); // eat the VarName.
- }
- Result.push_back(std::make_pair(Val, VarName));
+ // If the variable name is present, add it.
+ std::string VarName;
+ if (Lex.getCode() == tgtok::colon) {
+ if (Lex.Lex() != tgtok::VarName) { // eat the ':'
+ TokError("expected variable name in dag literal");
+ return std::vector<std::pair<llvm::Init*, std::string> >();
+ }
+ VarName = Lex.getCurStrVal();
+ Lex.Lex(); // eat the VarName.
+ }
+ Result.push_back(std::make_pair(Val, VarName));
+ }
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat the ','
}
diff --git a/test/TableGen/Dag.td b/test/TableGen/Dag.td
index 40399a48ee..14d616b521 100644
--- a/test/TableGen/Dag.td
+++ b/test/TableGen/Dag.td
@@ -70,3 +70,15 @@ def VAL4 : bar<foo2, somedef2>;
// CHECK-NEXT: dag Dag3 = (somedef2 2);
// CHECK-NEXT: NAME = ?
// CHECK-NEXT: }
+
+def VAL5 : bar<foo2, somedef2> {
+ // Named operands.
+ let Dag1 = (somedef1 1:$name1);
+
+ // Name, no node.
+ let Dag2 = (somedef2 $name2, $name3);
+}
+
+// CHECK: def VAL5 {
+// CHECK-NEXT: dag Dag1 = (somedef1 1:$name1);
+// CHECK-NEXT: dag Dag2 = (somedef2 ?:$name2, ?:$name3);