[Mlir-commits] [mlir] [MLIR] Generate cpp comments for TableGen summary and description (PR #139606)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon May 12 12:03:21 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-core

Author: Peng Chen (pchen7e2)

<details>
<summary>Changes</summary>

This commit takes the `summary` and `description` of TableGen files and generate a cpp comments on top of the declarations of generated cpp classes. It only affects `Dialect`, `Type` and `Op` for now. I'd like to get people's opinions on the direction before doing the same for other components such as `Interface`.

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. I attach a screenshot as an example here to show what it looks like in VSCode with LSP properly set up:

<img width="971" alt="Screenshot 2025-05-12 at 12 00 24 PM" src="https://github.com/user-attachments/assets/6404e4cd-385c-4da1-b155-8f93326459e9" />


---
Full diff: https://github.com/llvm/llvm-project/pull/139606.diff


7 Files Affected:

- (added) mlir/test/mlir-tblgen/cpp-class-comments.td (+74) 
- (modified) mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp (+8-1) 
- (modified) mlir/tools/mlir-tblgen/CMakeLists.txt (+1) 
- (added) mlir/tools/mlir-tblgen/CppGenUtilities.cpp (+39) 
- (added) mlir/tools/mlir-tblgen/CppGenUtilities.h (+29) 
- (modified) mlir/tools/mlir-tblgen/DialectGen.cpp (+6-1) 
- (modified) mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp (+7-2) 


``````````diff
diff --git a/mlir/test/mlir-tblgen/cpp-class-comments.td b/mlir/test/mlir-tblgen/cpp-class-comments.td
new file mode 100644
index 0000000000000..66d7e692dee25
--- /dev/null
+++ b/mlir/test/mlir-tblgen/cpp-class-comments.td
@@ -0,0 +1,74 @@
+// RUN: mlir-tblgen -gen-dialect-decls -I %S/../../include %s | FileCheck %s --check-prefix=DIALECT
+// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP
+// RUN: mlir-tblgen -gen-typedef-decls -I %S/../../include %s | FileCheck %s --check-prefix=TYPE
+
+include "mlir/IR/OpBase.td"
+
+// check dialect with summary and description
+def A_Dialect : Dialect {
+  let name = "a";
+  let cppNamespace = "";
+
+  let summary = "This is a summary";
+  let description = [{
+
+    This is a description, needs trimming
+
+  }];
+// DIALECT: /// This is a summary
+// DIALECT-NEXT: /// This is a description, needs trimming
+// DIALECT-NEXT: class ADialect : public ::mlir::Dialect {
+}
+
+def A_SomeOp1 : Op<A_Dialect, "some_op1", []>{
+  let summary = "Some Op1 summary line1 \nsummary line2";
+
+  let description = [{
+      Some Op1 description
+  }];
+
+  let cppNamespace = "OP1";
+// OP: namespace OP1
+// OP-NEXT: /// Some Op1 summary line1
+// OP-NEXT: /// summary line2
+// OP-NEXT: /// Some Op1 description
+// OP-NEXT: class SomeOp1;
+}
+
+// test weird characters in description
+def A_SomeOp2 : Op<A_Dialect, "some_op2", []>{
+  let summary = "";
+
+  let description = [{
+      $ptr (`,` $mask^)? (`,` $other^)?
+      oilist(
+        `a` `=` $1 | `b` `=` $2
+      )
+  }];
+// OP: /// $ptr (`,` $mask^)? (`,` $other^)?
+// OP-NEXT: /// oilist(
+// OP-NEXT: /// `a` `=` $1 | `b` `=` $2
+// OP-NEXT: /// )
+// OP-NEXT: class SomeOp2;
+}
+
+class AType<string name> : TypeDef<A_Dialect, name> { }
+
+
+def A_TensorType : AType<"Tensor"> {
+  let typeName = "a.simple_a_tensor";
+
+  let summary = "Tensor Type A summary";
+
+  let description = [{
+      Tensor Type A description
+  }];
+
+  let extraClassDeclaration = [{
+    void getSignlessBlockType() const {
+    }
+  }];
+// TYPE: /// Tensor Type A summary
+// TYPE-NEXT: /// Tensor Type A description
+// TYPE-NEXT: class TensorType;
+}
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 05686c0539754..2a6071602fa49 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AttrOrTypeFormatGen.h"
+#include "CppGenUtilities.h"
 #include "mlir/TableGen/AttrOrTypeDef.h"
 #include "mlir/TableGen/Class.h"
 #include "mlir/TableGen/CodeGenHelpers.h"
@@ -813,8 +814,14 @@ bool DefGenerator::emitDecls(StringRef selectedDialect) {
     NamespaceEmitter nsEmitter(os, defs.front().getDialect());
 
     // Declare all the def classes first (in case they reference each other).
-    for (const AttrOrTypeDef &def : defs)
+    for (const AttrOrTypeDef &def : defs) {
+      std::string comments = tblgen::emitSummaryAndDescComments(
+          def.getSummary(), def.getDescription());
+      if (!comments.empty()) {
+        os << comments << "\n";
+      }
       os << "class " << def.getCppClassName() << ";\n";
+    }
 
     // Emit the declarations.
     for (const AttrOrTypeDef &def : defs)
diff --git a/mlir/tools/mlir-tblgen/CMakeLists.txt b/mlir/tools/mlir-tblgen/CMakeLists.txt
index 9431c59860522..2a7ef7e0576c8 100644
--- a/mlir/tools/mlir-tblgen/CMakeLists.txt
+++ b/mlir/tools/mlir-tblgen/CMakeLists.txt
@@ -33,6 +33,7 @@ add_tablegen(mlir-tblgen MLIR
   RewriterGen.cpp
   SPIRVUtilsGen.cpp
   TosaUtilsGen.cpp
+  CppGenUtilities.cpp
   )
 
 target_link_libraries(mlir-tblgen
diff --git a/mlir/tools/mlir-tblgen/CppGenUtilities.cpp b/mlir/tools/mlir-tblgen/CppGenUtilities.cpp
new file mode 100644
index 0000000000000..ebca20cc685f4
--- /dev/null
+++ b/mlir/tools/mlir-tblgen/CppGenUtilities.cpp
@@ -0,0 +1,39 @@
+//===- CppGenUtilities.cpp - MLIR cpp gen utilities --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines common utilities for generating cpp files from tablegen
+// structures.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CppGenUtilities.h"
+#include "mlir/Support/IndentedOstream.h"
+
+std::string
+mlir::tblgen::emitSummaryAndDescComments(llvm::StringRef summary,
+                                         llvm::StringRef description) {
+
+  std::string comments = "";
+  StringRef trimmedSummary = summary.trim();
+  StringRef trimmedDesc = description.trim();
+  llvm::raw_string_ostream os(comments);
+  raw_indented_ostream ros(os);
+
+  if (!trimmedSummary.empty()) {
+    ros.printReindented(trimmedSummary, "/// ");
+  }
+
+  if (!trimmedDesc.empty()) {
+    if (!trimmedSummary.empty()) {
+      // If there is a summary, add a newline after it.
+      ros << "\n";
+    }
+    ros.printReindented(trimmedDesc, "/// ");
+  }
+  return comments;
+}
diff --git a/mlir/tools/mlir-tblgen/CppGenUtilities.h b/mlir/tools/mlir-tblgen/CppGenUtilities.h
new file mode 100644
index 0000000000000..231c59a9e148f
--- /dev/null
+++ b/mlir/tools/mlir-tblgen/CppGenUtilities.h
@@ -0,0 +1,29 @@
+//===- CppGenUtilities.h - MLIR cpp gen utilities ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines common utilities for generating cpp files from tablegen
+// structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_
+#define MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_
+
+#include "llvm/ADT/StringRef.h"
+
+namespace mlir {
+namespace tblgen {
+
+// Emit the summary and description as a C++ comment, perperly aligned placed
+// adjacent to the class declaration of generated classes.
+std::string emitSummaryAndDescComments(llvm::StringRef summary,
+                                       llvm::StringRef description);
+} // namespace tblgen
+} // namespace mlir
+
+#endif // MLIR_TOOLS_MLIRTBLGEN_CPPGENUTILITIES_H_
diff --git a/mlir/tools/mlir-tblgen/DialectGen.cpp b/mlir/tools/mlir-tblgen/DialectGen.cpp
index 6cf71d2bb0174..292ff0b9daa73 100644
--- a/mlir/tools/mlir-tblgen/DialectGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectGen.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CppGenUtilities.h"
 #include "DialectGenUtilities.h"
 #include "mlir/TableGen/Class.h"
 #include "mlir/TableGen/CodeGenHelpers.h"
@@ -109,6 +110,7 @@ tblgen::findDialectToGenerate(ArrayRef<Dialect> dialects) {
 /// {1}: The dialect namespace.
 /// {2}: The dialect parent class.
 static const char *const dialectDeclBeginStr = R"(
+{3}
 class {0} : public ::mlir::{2} {
   explicit {0}(::mlir::MLIRContext *context);
 
@@ -245,8 +247,11 @@ static void emitDialectDecl(Dialect &dialect, raw_ostream &os) {
     std::string cppName = dialect.getCppClassName();
     StringRef superClassName =
         dialect.isExtensible() ? "ExtensibleDialect" : "Dialect";
+
+    std::string comments = tblgen::emitSummaryAndDescComments(
+        dialect.getSummary(), dialect.getDescription());
     os << llvm::formatv(dialectDeclBeginStr, cppName, dialect.getName(),
-                        superClassName);
+                        superClassName, comments);
 
     // If the dialect requested the default attribute printer and parser, emit
     // the declarations for the hooks.
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index 3f397f3a8e6fd..373d3762cbb1a 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CppGenUtilities.h"
 #include "OpClass.h"
 #include "OpFormatGen.h"
 #include "OpGenHelpers.h"
@@ -2640,8 +2641,7 @@ void OpEmitter::genSeparateArgParamBuilder() {
 
       // Avoid emitting "resultTypes.size() >= 0u" which is always true.
       if (!hasVariadicResult || numNonVariadicResults != 0)
-        body << "  "
-             << "assert(resultTypes.size() "
+        body << "  " << "assert(resultTypes.size() "
              << (hasVariadicResult ? ">=" : "==") << " "
              << numNonVariadicResults
              << "u && \"mismatched number of results\");\n";
@@ -4749,6 +4749,11 @@ static void emitOpClassDecls(const RecordKeeper &records,
   for (auto *def : defs) {
     Operator op(*def);
     NamespaceEmitter emitter(os, op.getCppNamespace());
+    std::string comments = tblgen::emitSummaryAndDescComments(
+        op.getSummary(), op.getDescription());
+    if (!comments.empty()) {
+      os << comments << "\n";
+    }
     os << "class " << op.getCppClassName() << ";\n";
   }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/139606


More information about the Mlir-commits mailing list