[llvm] [TableGen] Support type aliases via new keyword deftype (PR #79570)
David Spickett via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 26 02:37:26 PST 2024
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/79570
>From 867058380e5b02f1fc7fa0d00a0122ec03d7f82b Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Fri, 26 Jan 2024 18:22:49 +0800
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
---
llvm/docs/TableGen/ProgRef.rst | 18 ++++++++++++---
llvm/lib/TableGen/TGLexer.cpp | 1 +
llvm/lib/TableGen/TGLexer.h | 1 +
llvm/lib/TableGen/TGParser.cpp | 41 +++++++++++++++++++++++++++++++++-
llvm/lib/TableGen/TGParser.h | 2 ++
llvm/test/TableGen/deftype.td | 22 ++++++++++++++++++
6 files changed, 81 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/TableGen/deftype.td
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 59ddef975c4877e..f1bbe32ec204731 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -570,8 +570,8 @@ files.
.. productionlist::
TableGenFile: (`Statement` | `IncludeDirective`
:| `PreprocessorDirective`)*
- Statement: `Assert` | `Class` | `Def` | `Defm` | `Defset` | `Defvar`
- :| `Dump` | `Foreach` | `If` | `Let` | `MultiClass`
+ Statement: `Assert` | `Class` | `Def` | `Defm` | `Defset` | `Deftype`
+ :| `Defvar` | `Dump` | `Foreach` | `If` | `Let` | `MultiClass`
The following sections describe each of these top-level statements.
@@ -931,7 +931,8 @@ template that expands into multiple records.
: `ParentClassList`
: "{" `MultiClassStatement`+ "}"
MultiClassID: `TokIdentifier`
- MultiClassStatement: `Assert` | `Def` | `Defm` | `Defvar` | `Foreach` | `If` | `Let`
+ MultiClassStatement: `Assert` | `Def` | `Defm` | `Deftype` | `Defvar`
+ :| `Foreach` | `If` | `Let`
As with regular classes, the multiclass has a name and can accept template
arguments. A multiclass can inherit from other multiclasses, which causes
@@ -1215,6 +1216,17 @@ set.
Anonymous records created inside initialization expressions using the
``ClassID<...>`` syntax are not collected in the set.
+``deftype`` --- define a type
+--------------------------------
+
+A ``deftype`` statement defines a type. Its value can be used
+throughout the statements that follow the definition.
+
+.. productionlist::
+ Deftype: "deftype" `TokIdentifier` "=" `Value` ";"
+
+The identifier on the left of the ``=`` is defined to be a type name
+whose actual type is given by the type expression on the right of the ``=``.
``defvar`` --- define a variable
--------------------------------
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index c811a67d930d481..545643234f6992e 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -360,6 +360,7 @@ tgtok::TokKind TGLexer::LexIdentifier() {
.Case("foreach", tgtok::Foreach)
.Case("defm", tgtok::Defm)
.Case("defset", tgtok::Defset)
+ .Case("deftype", tgtok::Deftype)
.Case("multiclass", tgtok::MultiClass)
.Case("field", tgtok::Field)
.Case("let", tgtok::Let)
diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 2e2aa59f344083d..25dcd9fbadef7bb 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -97,6 +97,7 @@ enum TokKind {
Def,
Defm,
Defset,
+ Deftype,
Defvar,
Dump,
Foreach,
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index e7dcb91ba20a60f..1574505ded33ad0 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1103,11 +1103,17 @@ RecTy *TGParser::ParseType() {
case tgtok::Dag:
Lex.Lex();
return DagRecTy::get(Records);
- case tgtok::Id:
+ case tgtok::Id: {
+ std::string TypeName = Lex.getCurStrVal();
+ if (TypeAliases.count(TypeName)) {
+ Lex.Lex();
+ return TypeAliases[TypeName];
+ }
if (Record *R = ParseClassID())
return RecordRecTy::get(R);
TokError("unknown class name");
return nullptr;
+ }
case tgtok::Bits: {
if (Lex.Lex() != tgtok::less) { // Eat 'bits'
TokError("expected '<' after bits type");
@@ -3665,6 +3671,36 @@ bool TGParser::ParseDefset() {
return false;
}
+/// ParseDeftype - Parse a defvar statement.
+///
+/// Deftype ::= DEFTYPE Id '=' Value ';'
+///
+bool TGParser::ParseDeftype() {
+ assert(Lex.getCode() == tgtok::Deftype);
+ Lex.Lex(); // Eat the 'deftype' token
+
+ if (Lex.getCode() != tgtok::Id)
+ return TokError("expected identifier");
+
+ std::string TypeName = Lex.getCurStrVal();
+ if (TypeAliases.count(TypeName))
+ return TokError("type of this name already exists");
+
+ Lex.Lex();
+ if (!consume(tgtok::equal))
+ return TokError("expected '='");
+
+ RecTy *Type = ParseType();
+ if (!Type)
+ return true;
+ TypeAliases[TypeName] = Type;
+
+ if (!consume(tgtok::semi))
+ return TokError("expected ';'");
+
+ return false;
+}
+
/// ParseDefvar - Parse a defvar statement.
///
/// Defvar ::= DEFVAR Id '=' Value ';'
@@ -4265,6 +4301,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
/// Object ::= LETCommand '{' ObjectList '}'
/// Object ::= LETCommand Object
/// Object ::= Defset
+/// Object ::= Deftype
/// Object ::= Defvar
/// Object ::= Assert
/// Object ::= Dump
@@ -4276,6 +4313,8 @@ bool TGParser::ParseObject(MultiClass *MC) {
case tgtok::Assert: return ParseAssert(MC);
case tgtok::Def: return ParseDef(MC);
case tgtok::Defm: return ParseDefm(MC);
+ case tgtok::Deftype:
+ return ParseDeftype();
case tgtok::Defvar: return ParseDefvar();
case tgtok::Dump:
return ParseDump(MC);
diff --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h
index 0929154fed3d414..b08e250870901af 100644
--- a/llvm/lib/TableGen/TGParser.h
+++ b/llvm/lib/TableGen/TGParser.h
@@ -143,6 +143,7 @@ class TGParser {
TGLexer Lex;
std::vector<SmallVector<LetRecord, 4>> LetStack;
std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses;
+ std::map<std::string, RecTy *> TypeAliases;
/// Loops - Keep track of any foreach loops we are within.
///
@@ -264,6 +265,7 @@ class TGParser {
bool ParseDefm(MultiClass *CurMultiClass);
bool ParseDef(MultiClass *CurMultiClass);
bool ParseDefset();
+ bool ParseDeftype();
bool ParseDefvar(Record *CurRec = nullptr);
bool ParseDump(MultiClass *CurMultiClass, Record *CurRec = nullptr);
bool ParseForeach(MultiClass *CurMultiClass);
diff --git a/llvm/test/TableGen/deftype.td b/llvm/test/TableGen/deftype.td
new file mode 100644
index 000000000000000..ee430cbdaf7a208
--- /dev/null
+++ b/llvm/test/TableGen/deftype.td
@@ -0,0 +1,22 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+
+deftype Byte = bits<8>;
+deftype IntList = list<int>;
+deftype ByteList = list<Byte>;
+class Class<Byte b> {
+ Byte byte = b;
+}
+deftype ClassList = list<Class>;
+
+// CHECK: def test {
+// CHECK-NEXT: bits<8> byte = { 0, 1, 1, 1, 1, 0, 1, 1 };
+// CHECK-NEXT: list<int> ints = [1, 2, 3];
+// CHECK-NEXT: list<bits<8>> bytes = [{ 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 1, 1 }];
+// CHECK-NEXT: list<Class> defs = [anonymous_0, anonymous_1, anonymous_2];
+// CHECK-NEXT: }
+def test {
+ Byte byte = 123;
+ IntList ints = [1, 2, 3];
+ ByteList bytes = [1, 2, 3];
+ ClassList defs = [Class<1>, Class<2>, Class<3>];
+}
>From 3f642857652aeecc140eaf0641e73f789945f733 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Fri, 26 Jan 2024 18:29:19 +0800
Subject: [PATCH 2/3] Reword doc
Created using spr 1.3.4
---
llvm/docs/TableGen/ProgRef.rst | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index f1bbe32ec204731..41196d7cdc6cea3 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -931,8 +931,7 @@ template that expands into multiple records.
: `ParentClassList`
: "{" `MultiClassStatement`+ "}"
MultiClassID: `TokIdentifier`
- MultiClassStatement: `Assert` | `Def` | `Defm` | `Deftype` | `Defvar`
- :| `Foreach` | `If` | `Let`
+ MultiClassStatement: `Assert` | `Def` | `Defm` | `Defvar` | `Foreach` | `If` | `Let`
As with regular classes, the multiclass has a name and can accept template
arguments. A multiclass can inherit from other multiclasses, which causes
@@ -1219,15 +1218,18 @@ Anonymous records created inside initialization expressions using the
``deftype`` --- define a type
--------------------------------
-A ``deftype`` statement defines a type. Its value can be used
-throughout the statements that follow the definition.
+A ``deftype`` statement defines a type. The type can be used throughout the
+statements that follow the definition.
.. productionlist::
- Deftype: "deftype" `TokIdentifier` "=" `Value` ";"
+ Deftype: "deftype" `TokIdentifier` "=" `Type` ";"
The identifier on the left of the ``=`` is defined to be a type name
whose actual type is given by the type expression on the right of the ``=``.
+Currently, only primitive types are supported and ``deftype`` statements can
+only appear at the top level.
+
``defvar`` --- define a variable
--------------------------------
>From 14e3e83472c4d9391709e35dc29bce0735634a10 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Fri, 26 Jan 2024 18:37:15 +0800
Subject: [PATCH 3/3] Type name should not be conflict with exited class
Created using spr 1.3.4
---
llvm/lib/TableGen/TGParser.cpp | 4 ++--
llvm/test/TableGen/deftype.td | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 1574505ded33ad0..f6d82cddc6a0535 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -3683,8 +3683,8 @@ bool TGParser::ParseDeftype() {
return TokError("expected identifier");
std::string TypeName = Lex.getCurStrVal();
- if (TypeAliases.count(TypeName))
- return TokError("type of this name already exists");
+ if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
+ return TokError("type of this name '" + TypeName + "' already exists");
Lex.Lex();
if (!consume(tgtok::equal))
diff --git a/llvm/test/TableGen/deftype.td b/llvm/test/TableGen/deftype.td
index ee430cbdaf7a208..baf403e27ab0473 100644
--- a/llvm/test/TableGen/deftype.td
+++ b/llvm/test/TableGen/deftype.td
@@ -1,4 +1,6 @@
// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
+// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
deftype Byte = bits<8>;
deftype IntList = list<int>;
@@ -20,3 +22,13 @@ def test {
ByteList bytes = [1, 2, 3];
ClassList defs = [Class<1>, Class<2>, Class<3>];
}
+
+#ifdef ERROR1
+// ERROR1: [[@LINE+1]]:9: error: type of this name 'Byte' already exists
+deftype Byte = bits<8>;
+#endif
+
+#ifdef ERROR2
+// ERROR2: [[@LINE+1]]:9: error: type of this name 'Class' already exists
+deftype Class = int;
+#endif
More information about the llvm-commits
mailing list