Skip to content

Commit 3138f6c

Browse files
authored
[MLIR] Generate cpp comments for TableGen summary and description (llvm#139606)
This commit takes the `summary` and `description` of TableGen files and generate a cpp comments on top of the declarations of generated cpp classes. The main motivation is to improve the developer experience. When people work on compilers from an IDE, they will be able to hover over the symbols (e.g. `"ADialect::BOp"`) in their cpp code and see the summary and descriptions without having to referring to the `.td` files.
1 parent 5ee67ee commit 3138f6c

File tree

8 files changed

+238
-5
lines changed

8 files changed

+238
-5
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// RUN: mlir-tblgen -gen-dialect-decls -I %S/../../include %s | FileCheck %s --check-prefix=DIALECT
2+
// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP
3+
// RUN: mlir-tblgen -gen-typedef-decls -I %S/../../include %s | FileCheck %s --check-prefix=TYPE
4+
// RUN: mlir-tblgen -gen-attrdef-decls -I %S/../../include %s | FileCheck %s --check-prefix=ATTR
5+
// RUN: mlir-tblgen -gen-attr-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=ATTR-INTERFACE
6+
// RUN: mlir-tblgen -gen-op-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP-INTERFACE
7+
// RUN: mlir-tblgen -gen-type-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=TYPE-INTERFACE
8+
// RUN: mlir-tblgen -gen-enum-decls -I %S/../../include %s | FileCheck %s --check-prefix=ENUM
9+
10+
include "mlir/IR/AttrTypeBase.td"
11+
include "mlir/IR/EnumAttr.td"
12+
include "mlir/IR/OpBase.td"
13+
14+
// check dialect with summary and description
15+
def A_Dialect : Dialect {
16+
let name = "a";
17+
let cppNamespace = "";
18+
19+
let summary = "This is a summary";
20+
let description = [{
21+
22+
This is a description, needs trimming
23+
24+
}];
25+
// DIALECT: /// This is a summary
26+
// DIALECT-NEXT: /// This is a description, needs trimming
27+
// DIALECT-NEXT: class ADialect : public ::mlir::Dialect {
28+
}
29+
30+
def A_SomeOp1 : Op<A_Dialect, "some_op1", []>{
31+
let summary = "Some Op1 summary line1 \nsummary line2";
32+
33+
let description = [{
34+
Some Op1 description
35+
}];
36+
37+
let cppNamespace = "OP1";
38+
// OP: namespace OP1
39+
// OP-NEXT: /// Some Op1 summary line1
40+
// OP-NEXT: /// summary line2
41+
// OP-NEXT: /// Some Op1 description
42+
// OP-NEXT: class SomeOp1;
43+
}
44+
45+
// test weird characters in description
46+
def A_SomeOp2 : Op<A_Dialect, "some_op2", []>{
47+
let summary = "";
48+
49+
let description = [{
50+
$ptr (`,` $mask^)? (`,` $other^)?
51+
oilist(
52+
`a` `=` $1 | `b` `=` $2
53+
)
54+
}];
55+
// OP: /// $ptr (`,` $mask^)? (`,` $other^)?
56+
// OP-NEXT: /// oilist(
57+
// OP-NEXT: /// `a` `=` $1 | `b` `=` $2
58+
// OP-NEXT: /// )
59+
// OP-NEXT: class SomeOp2;
60+
}
61+
62+
def A_TensorType : TypeDef<A_Dialect,"Tensor"> {
63+
let typeName = "a.simple_a_tensor";
64+
65+
let summary = "Tensor Type A summary";
66+
67+
let description = [{
68+
Tensor Type A description
69+
}];
70+
71+
let extraClassDeclaration = [{
72+
void getSignlessBlockType() const {
73+
}
74+
}];
75+
// TYPE: /// Tensor Type A summary
76+
// TYPE-NEXT: /// Tensor Type A description
77+
// TYPE-NEXT: class TensorType;
78+
}
79+
80+
def A_SimpleAttr : AttrDef<A_Dialect,"SimpleA"> {
81+
let attrName = "a.simple_attr";
82+
let summary = "Simple Attr A summary";
83+
84+
let description = [{
85+
Simple Attr A description
86+
}];
87+
// ATTR: /// Simple Attr A summary
88+
// ATTR-NEXT: /// Simple Attr A description
89+
// ATTR-NEXT: class SimpleAAttr;
90+
}
91+
92+
def EncodingTrait : AttrInterface<"EncodingTrait"> {
93+
let cppNamespace = "mlir::a::traits";
94+
let description = [{
95+
Common trait for all layouts.
96+
}];
97+
let methods = [
98+
];
99+
// ATTR-INTERFACE: namespace mlir
100+
// ATTR-INTERFACE-NEXT: namespace a
101+
// ATTR-INTERFACE-NEXT: namespace traits
102+
// ATTR-INTERFACE-NEXT: /// Common trait for all layouts.
103+
// ATTR-INTERFACE-NEXT: class EncodingTrait;
104+
}
105+
106+
def SimpleEncodingTrait : AttrInterface<"SimpleEncodingTrait"> {
107+
let cppNamespace = "a::traits";
108+
// ATTR-INTERFACE: namespace a {
109+
// ATTR-INTERFACE-NEXT: namespace traits {
110+
// ATTR-INTERFACE-NEXT: class SimpleEncodingTrait;
111+
}
112+
113+
def SimpleOpInterface : OpInterface<"SimpleOpInterface"> {
114+
let cppNamespace = "a::traits";
115+
let description = [{
116+
117+
Simple Op Interface description
118+
}];
119+
// OP-INTERFACE: namespace a {
120+
// OP-INTERFACE-NEXT: namespace traits {
121+
// OP-INTERFACE-NEXT: /// Simple Op Interface description
122+
// OP-INTERFACE-NEXT: class SimpleOpInterface;
123+
}
124+
125+
def SimpleTypeInterface : TypeInterface<"SimpleTypeInterface"> {
126+
let description = [{
127+
Simple Type Interface description
128+
}];
129+
// TYPE-INTERFACE: /// Simple Type Interface description
130+
// TYPE-INTERFACE-NEXT: class SimpleTypeInterface;
131+
}
132+
133+
def MyBitEnum: I32BitEnumAttr<"MyBitEnum", "An example bit enum",
134+
[I32BitEnumCaseBit<"Bit0", 0, "tagged">,
135+
I32BitEnumCaseBit<"Bit1", 1>]> {
136+
let genSpecializedAttr = 0;
137+
// ENUM: // An example bit enum
138+
// ENUM-NEXT: enum class MyBitEnum
139+
}

mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "AttrOrTypeFormatGen.h"
10+
#include "CppGenUtilities.h"
1011
#include "mlir/TableGen/AttrOrTypeDef.h"
1112
#include "mlir/TableGen/Class.h"
1213
#include "mlir/TableGen/CodeGenHelpers.h"
@@ -813,8 +814,14 @@ bool DefGenerator::emitDecls(StringRef selectedDialect) {
813814
NamespaceEmitter nsEmitter(os, defs.front().getDialect());
814815

815816
// Declare all the def classes first (in case they reference each other).
816-
for (const AttrOrTypeDef &def : defs)
817+
for (const AttrOrTypeDef &def : defs) {
818+
std::string comments = tblgen::emitSummaryAndDescComments(
819+
def.getSummary(), def.getDescription());
820+
if (!comments.empty()) {
821+
os << comments << "\n";
822+
}
817823
os << "class " << def.getCppClassName() << ";\n";
824+
}
818825

819826
// Emit the declarations.
820827
for (const AttrOrTypeDef &def : defs)

mlir/tools/mlir-tblgen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_tablegen(mlir-tblgen MLIR
3333
RewriterGen.cpp
3434
SPIRVUtilsGen.cpp
3535
TosaUtilsGen.cpp
36+
CppGenUtilities.cpp
3637
)
3738

3839
target_link_libraries(mlir-tblgen
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===- CppGenUtilities.cpp - MLIR cpp gen utilities --------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Defines common utilities for generating cpp files from tablegen
10+
// structures.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "CppGenUtilities.h"
15+
#include "mlir/Support/IndentedOstream.h"
16+
17+
std::string
18+
mlir::tblgen::emitSummaryAndDescComments(llvm::StringRef summary,
19+
llvm::StringRef description) {
20+
21+
std::string comments = "";
22+
StringRef trimmedSummary = summary.trim();
23+
StringRef trimmedDesc = description.trim();
24+
llvm::raw_string_ostream os(comments);
25+
raw_indented_ostream ros(os);
26+
27+
if (!trimmedSummary.empty()) {
28+
ros.printReindented(trimmedSummary, "/// ");
29+
}
30+
31+
if (!trimmedDesc.empty()) {
32+
if (!trimmedSummary.empty()) {
33+
// If there is a summary, add a newline after it.
34+
ros << "\n";
35+
}
36+
ros.printReindented(trimmedDesc, "/// ");
37+
}
38+
return comments;
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===- CppGenUtilities.h - MLIR cpp gen utilities ---------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines common utilities for generating cpp files from tablegen
10+
// structures.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_
15+
#define MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_
16+
17+
#include "llvm/ADT/StringRef.h"
18+
19+
namespace mlir {
20+
namespace tblgen {
21+
22+
// Emit the summary and description as a C++ comment, perperly aligned placed
23+
// adjacent to the class declaration of generated classes.
24+
std::string emitSummaryAndDescComments(llvm::StringRef summary,
25+
llvm::StringRef description);
26+
} // namespace tblgen
27+
} // namespace mlir
28+
29+
#endif // MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_

mlir/tools/mlir-tblgen/DialectGen.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "CppGenUtilities.h"
1314
#include "DialectGenUtilities.h"
1415
#include "mlir/TableGen/Class.h"
1516
#include "mlir/TableGen/CodeGenHelpers.h"
@@ -108,7 +109,9 @@ tblgen::findDialectToGenerate(ArrayRef<Dialect> dialects) {
108109
/// {0}: The name of the dialect class.
109110
/// {1}: The dialect namespace.
110111
/// {2}: The dialect parent class.
112+
/// {3}: The summary and description comments.
111113
static const char *const dialectDeclBeginStr = R"(
114+
{3}
112115
class {0} : public ::mlir::{2} {
113116
explicit {0}(::mlir::MLIRContext *context);
114117
@@ -245,8 +248,11 @@ static void emitDialectDecl(Dialect &dialect, raw_ostream &os) {
245248
std::string cppName = dialect.getCppClassName();
246249
StringRef superClassName =
247250
dialect.isExtensible() ? "ExtensibleDialect" : "Dialect";
251+
252+
std::string comments = tblgen::emitSummaryAndDescComments(
253+
dialect.getSummary(), dialect.getDescription());
248254
os << llvm::formatv(dialectDeclBeginStr, cppName, dialect.getName(),
249-
superClassName);
255+
superClassName, comments);
250256

251257
// If the dialect requested the default attribute printer and parser, emit
252258
// the declarations for the hooks.

mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "CppGenUtilities.h"
1415
#include "OpClass.h"
1516
#include "OpFormatGen.h"
1617
#include "OpGenHelpers.h"
@@ -2640,8 +2641,7 @@ void OpEmitter::genSeparateArgParamBuilder() {
26402641

26412642
// Avoid emitting "resultTypes.size() >= 0u" which is always true.
26422643
if (!hasVariadicResult || numNonVariadicResults != 0)
2643-
body << " "
2644-
<< "assert(resultTypes.size() "
2644+
body << " " << "assert(resultTypes.size() "
26452645
<< (hasVariadicResult ? ">=" : "==") << " "
26462646
<< numNonVariadicResults
26472647
<< "u && \"mismatched number of results\");\n";
@@ -4749,6 +4749,11 @@ static void emitOpClassDecls(const RecordKeeper &records,
47494749
for (auto *def : defs) {
47504750
Operator op(*def);
47514751
NamespaceEmitter emitter(os, op.getCppNamespace());
4752+
std::string comments = tblgen::emitSummaryAndDescComments(
4753+
op.getSummary(), op.getDescription());
4754+
if (!comments.empty()) {
4755+
os << comments << "\n";
4756+
}
47524757
os << "class " << op.getCppClassName() << ";\n";
47534758
}
47544759

mlir/tools/mlir-tblgen/OpInterfacesGen.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "CppGenUtilities.h"
1314
#include "DocGenUtilities.h"
1415
#include "mlir/TableGen/Format.h"
1516
#include "mlir/TableGen/GenInfo.h"
@@ -527,6 +528,11 @@ void InterfaceGenerator::emitInterfaceDecl(const Interface &interface) {
527528

528529
// Emit a forward declaration of the interface class so that it becomes usable
529530
// in the signature of its methods.
531+
std::string comments = tblgen::emitSummaryAndDescComments(
532+
"", interface.getDescription().value_or(""));
533+
if (!comments.empty()) {
534+
os << comments << "\n";
535+
}
530536
os << "class " << interfaceName << ";\n";
531537

532538
// Emit the traits struct containing the concept and model declarations.
@@ -589,7 +595,8 @@ void InterfaceGenerator::emitInterfaceDecl(const Interface &interface) {
589595
<< " auto* interface = getInterfaceFor(base);\n"
590596
<< " if (!interface)\n"
591597
" return false;\n"
592-
" " << interfaceName << " odsInterfaceInstance(base, interface);\n"
598+
" "
599+
<< interfaceName << " odsInterfaceInstance(base, interface);\n"
593600
<< " " << tblgen::tgfmt(extraClassOf->trim(), &extraClassOfFmt)
594601
<< "\n }\n";
595602
}

0 commit comments

Comments
 (0)