Allow TableGen DAG arguments to be just a name.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 24 Mar 2013 19:36:51 +0000 (19:36 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 24 Mar 2013 19:36:51 +0000 (19:36 +0000)
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

docs/TableGen/LangRef.rst
lib/TableGen/TGParser.cpp
test/TableGen/Dag.td

index c9e1efba03fbe1b6c6428b2c51eb6f1d54845bed..bd28a9031d74ecdcdd95c2514ad996238a5207c1 100644 (file)
@@ -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.
 
index c4b48fe5e895d539c7b21cb1e0eed1d54587419e..86ad2a6e3c09c6899d0d534baa5c72654d8d3b6e 100644 (file)
@@ -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 ','
   }
index 40399a48ee2fd0c3ee637ed1d6f8d214d3a0536e..14d616b521733c2242a315712f5be9a7f585c760 100644 (file)
@@ -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);