[llvm] r358117 - [TableGen] Introduce !listsplat 'binary' operator

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 10 11:26:36 PDT 2019


Author: lebedevri
Date: Wed Apr 10 11:26:36 2019
New Revision: 358117

URL: http://llvm.org/viewvc/llvm-project?rev=358117&view=rev
Log:
[TableGen] Introduce !listsplat 'binary' operator

Summary:
```
``!listsplat(a, size)``
    A list value that contains the value ``a`` ``size`` times.
    Example: ``!listsplat(0, 2)`` results in ``[0, 0]``.
```

I plan to use this in X86ScheduleBdVer2.td for LoadRes handling.

This is a little bit controversial because unlike every other binary operator
the types aren't identical.

Reviewers: stoklund, javed.absar, nhaehnle, craig.topper

Reviewed By: javed.absar

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60367

Added:
    llvm/trunk/test/TableGen/listsplat.td
Modified:
    llvm/trunk/docs/TableGen/LangIntro.rst
    llvm/trunk/docs/TableGen/LangRef.rst
    llvm/trunk/include/llvm/TableGen/Record.h
    llvm/trunk/lib/TableGen/Record.cpp
    llvm/trunk/lib/TableGen/TGLexer.cpp
    llvm/trunk/lib/TableGen/TGLexer.h
    llvm/trunk/lib/TableGen/TGParser.cpp
    llvm/trunk/utils/kate/llvm-tablegen.xml

Modified: llvm/trunk/docs/TableGen/LangIntro.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGen/LangIntro.rst?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/docs/TableGen/LangIntro.rst (original)
+++ llvm/trunk/docs/TableGen/LangIntro.rst Wed Apr 10 11:26:36 2019
@@ -189,6 +189,10 @@ supported include:
     More than two arguments are accepted with the result being the concatenation
     of all the lists given.
 
+``!listsplat(a, size)``
+    A list value that contains the value ``a`` ``size`` times.
+    Example: ``!listsplat(0, 2)`` results in ``[0, 0]``.
+
 ``!strconcat(a, b, ...)``
     A string value that is the result of concatenating the 'a' and 'b' strings.
     More than two arguments are accepted with the result being the concatenation

Modified: llvm/trunk/docs/TableGen/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGen/LangRef.rst?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/docs/TableGen/LangRef.rst (original)
+++ llvm/trunk/docs/TableGen/LangRef.rst Wed Apr 10 11:26:36 2019
@@ -100,7 +100,7 @@ wide variety of meanings:
                :!or     !empty   !subst   !foreach   !strconcat
                :!cast   !listconcat       !size      !foldl
                :!isa    !dag     !le      !lt        !ge
-               :!gt     !ne      !mul
+               :!gt     !ne      !mul     !listsplat
 
 TableGen also has !cond operator that needs a slightly different
 syntax compared to other "bang operators":

Modified: llvm/trunk/include/llvm/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/TableGen/Record.h?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/include/llvm/TableGen/Record.h (original)
+++ llvm/trunk/include/llvm/TableGen/Record.h Wed Apr 10 11:26:36 2019
@@ -801,7 +801,8 @@ public:
 class BinOpInit : public OpInit, public FoldingSetNode {
 public:
   enum BinaryOp : uint8_t { ADD, MUL, AND, OR, SHL, SRA, SRL, LISTCONCAT,
-                            STRCONCAT, CONCAT, EQ, NE, LE, LT, GE, GT };
+                            LISTSPLAT, STRCONCAT, CONCAT, EQ, NE, LE, LT, GE,
+                            GT };
 
 private:
   Init *LHS, *RHS;
@@ -821,6 +822,7 @@ public:
                         RecTy *Type);
   static Init *getStrConcat(Init *lhs, Init *rhs);
   static Init *getListConcat(TypedInit *lhs, Init *rhs);
+  static Init *getListSplat(TypedInit *lhs, Init *rhs);
 
   void Profile(FoldingSetNodeID &ID) const;
 

Modified: llvm/trunk/lib/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/Record.cpp?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/Record.cpp (original)
+++ llvm/trunk/lib/TableGen/Record.cpp Wed Apr 10 11:26:36 2019
@@ -875,6 +875,10 @@ Init *BinOpInit::getListConcat(TypedInit
    return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
 }
 
+Init *BinOpInit::getListSplat(TypedInit *LHS, Init *RHS) {
+  return BinOpInit::get(BinOpInit::LISTSPLAT, LHS, RHS, LHS->getType());
+}
+
 Init *BinOpInit::Fold(Record *CurRec) const {
   switch (getOpcode()) {
   case CONCAT: {
@@ -915,6 +919,15 @@ Init *BinOpInit::Fold(Record *CurRec) co
     }
     break;
   }
+  case LISTSPLAT: {
+    TypedInit *Value = dyn_cast<TypedInit>(LHS);
+    IntInit *Size = dyn_cast<IntInit>(RHS);
+    if (Value && Size) {
+      SmallVector<Init *, 8> Args(Size->getValue(), Value);
+      return ListInit::get(Args, Value->getType());
+    }
+    break;
+  }
   case STRCONCAT: {
     StringInit *LHSs = dyn_cast<StringInit>(LHS);
     StringInit *RHSs = dyn_cast<StringInit>(RHS);
@@ -1022,6 +1035,7 @@ std::string BinOpInit::getAsString() con
   case GE: Result = "!ge"; break;
   case GT: Result = "!gt"; break;
   case LISTCONCAT: Result = "!listconcat"; break;
+  case LISTSPLAT: Result = "!listsplat"; break;
   case STRCONCAT: Result = "!strconcat"; break;
   }
   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";

Modified: llvm/trunk/lib/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.cpp?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/lib/TableGen/TGLexer.cpp Wed Apr 10 11:26:36 2019
@@ -564,6 +564,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
     .Case("foldl", tgtok::XFoldl)
     .Case("foreach", tgtok::XForEach)
     .Case("listconcat", tgtok::XListConcat)
+    .Case("listsplat", tgtok::XListSplat)
     .Case("strconcat", tgtok::XStrConcat)
     .Default(tgtok::Error);
 

Modified: llvm/trunk/lib/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.h?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.h (original)
+++ llvm/trunk/lib/TableGen/TGLexer.h Wed Apr 10 11:26:36 2019
@@ -49,9 +49,9 @@ namespace tgtok {
     MultiClass, String, Defset,
 
     // !keywords.
-    XConcat, XADD, XMUL, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat,
-    XCast, XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XCond,
-    XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt,
+    XConcat, XADD, XMUL, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XListSplat,
+    XStrConcat, XCast, XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty,
+    XIf, XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt,
 
     // Integer value.
     IntVal,

Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed Apr 10 11:26:36 2019
@@ -1042,6 +1042,7 @@ Init *TGParser::ParseOperation(Record *C
   case tgtok::XGe:
   case tgtok::XGt:
   case tgtok::XListConcat:
+  case tgtok::XListSplat:
   case tgtok::XStrConcat: {  // Value ::= !binop '(' Value ',' Value ')'
     tgtok::TokKind OpTok = Lex.getCode();
     SMLoc OpLoc = Lex.getLoc();
@@ -1065,6 +1066,7 @@ Init *TGParser::ParseOperation(Record *C
     case tgtok::XGe:     Code = BinOpInit::GE; break;
     case tgtok::XGt:     Code = BinOpInit::GT; break;
     case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
+    case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
     case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
     }
 
@@ -1103,6 +1105,9 @@ Init *TGParser::ParseOperation(Record *C
       // We don't know the list type until we parse the first argument
       ArgType = ItemType;
       break;
+    case tgtok::XListSplat:
+      // Can't do any typechecking until we parse the first argument.
+      break;
     case tgtok::XStrConcat:
       Type = StringRecTy::get();
       ArgType = StringRecTy::get();
@@ -1142,6 +1147,33 @@ Init *TGParser::ParseOperation(Record *C
             return nullptr;
           }
           break;
+        case BinOpInit::LISTSPLAT:
+          if (ItemType && InitList.size() == 1) {
+            if (!isa<ListRecTy>(ItemType)) {
+              Error(OpLoc,
+                    Twine("expected output type to be a list, got type '") +
+                        ItemType->getAsString() + "'");
+              return nullptr;
+            }
+            if (!ArgType->getListTy()->typeIsConvertibleTo(ItemType)) {
+              Error(OpLoc, Twine("expected first arg type to be '") +
+                               ArgType->getAsString() +
+                               "', got value of type '" +
+                               cast<ListRecTy>(ItemType)
+                                   ->getElementType()
+                                   ->getAsString() +
+                               "'");
+              return nullptr;
+            }
+          }
+          if (InitList.size() == 2 && !isa<IntRecTy>(ArgType)) {
+            Error(InitLoc, Twine("expected second parameter to be an int, got "
+                                 "value of type '") +
+                               ArgType->getAsString() + "'");
+            return nullptr;
+          }
+          ArgType = nullptr; // Broken invariant: types not identical.
+          break;
         case BinOpInit::EQ:
         case BinOpInit::NE:
           if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
@@ -1179,8 +1211,12 @@ Init *TGParser::ParseOperation(Record *C
     }
     Lex.Lex();  // eat the ')'
 
+    // listconcat returns a list with type of the argument.
     if (Code == BinOpInit::LISTCONCAT)
       Type = ArgType;
+    // listsplat returns a list of type of the *first* argument.
+    if (Code == BinOpInit::LISTSPLAT)
+      Type = cast<TypedInit>(InitList.front())->getType()->getListTy();
 
     // We allow multiple operands to associative operators like !strconcat as
     // shorthand for nesting them.
@@ -1718,6 +1754,7 @@ Init *TGParser::ParseOperationCond(Recor
 ///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
+///   SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
 ///
@@ -2031,6 +2068,7 @@ Init *TGParser::ParseSimpleValue(Record
   case tgtok::XGe:
   case tgtok::XGt:
   case tgtok::XListConcat:
+  case tgtok::XListSplat:
   case tgtok::XStrConcat:   // Value ::= !binop '(' Value ',' Value ')'
   case tgtok::XIf:
   case tgtok::XCond:

Added: llvm/trunk/test/TableGen/listsplat.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/listsplat.td?rev=358117&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/listsplat.td (added)
+++ llvm/trunk/test/TableGen/listsplat.td Wed Apr 10 11:26:36 2019
@@ -0,0 +1,75 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+
+// CHECK: ------------- Classes -----------------
+// CHECK-NEXT: class X<int X:a = ?, int X:b = ?> {
+// CHECK-NEXT:   list<int> x = !listsplat(X:a, X:b);
+// CHECK-NEXT: }
+// CHECK-NEXT: class Y<string Y:a = ?, int Y:b = ?> {
+// CHECK-NEXT:   list<string> x = !listsplat(Y:a, Y:b);
+// CHECK-NEXT: }
+// CHECK-NEXT: ------------- Defs -----------------
+// CHECK-NEXT: def DX00 {      // X
+// CHECK-NEXT:   list<int> x = [];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DX01 {      // X
+// CHECK-NEXT:   list<int> x = [0];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DX02 {      // X
+// CHECK-NEXT:   list<int> x = [0, 0];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DX10 {      // X
+// CHECK-NEXT:   list<int> x = [];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DX11 {      // X
+// CHECK-NEXT:   list<int> x = [1];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DX12 {      // X
+// CHECK-NEXT:   list<int> x = [1, 1];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYa0 {      // Y
+// CHECK-NEXT:   list<string> x = [];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYa1 {      // Y
+// CHECK-NEXT:   list<string> x = ["a"];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYa2 {      // Y
+// CHECK-NEXT:   list<string> x = ["a", "a"];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYe0 {      // Y
+// CHECK-NEXT:   list<string> x = [];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYe1 {      // Y
+// CHECK-NEXT:   list<string> x = [""];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DYe2 {      // Y
+// CHECK-NEXT:   list<string> x = ["", ""];
+// CHECK-NEXT: }
+// CHECK-NEXT: def DZ {        // X
+// CHECK-NEXT:   list<int> x = [42, 42, 42];
+// CHECK-NEXT: }
+
+class X<int a, int b> {
+  list<int> x = !listsplat(a, b);
+}
+
+class Y<string a, int b> {
+  list<string> x = !listsplat(a, b);
+}
+
+def DX00 : X<0, 0>;
+def DX01 : X<0, 1>;
+def DX02 : X<0, 2>;
+
+def DX10 : X<1, 0>;
+def DX11 : X<1, 1>;
+def DX12 : X<1, 2>;
+
+def DYe0 : Y<"", 0>;
+def DYe1 : Y<"", 1>;
+def DYe2 : Y<"", 2>;
+
+def DYa0 : Y<"a", 0>;
+def DYa1 : Y<"a", 1>;
+def DYa2 : Y<"a", 2>;
+
+def DZ : X<42, !size([1, 2, 3])>;

Modified: llvm/trunk/utils/kate/llvm-tablegen.xml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/kate/llvm-tablegen.xml?rev=358117&r1=358116&r2=358117&view=diff
==============================================================================
--- llvm/trunk/utils/kate/llvm-tablegen.xml (original)
+++ llvm/trunk/utils/kate/llvm-tablegen.xml Wed Apr 10 11:26:36 2019
@@ -28,6 +28,7 @@
       <item> !strconcat </item>
       <item> !cast </item>
       <item> !listconcat </item>
+      <item> !listsplat </item>
       <item> !size </item>
       <item> !foldl </item>
       <item> !isa </item>




More information about the llvm-commits mailing list