From 95e5b4d33f328532a1cdfda734d93120dca8b435 Mon Sep 17 00:00:00 2001 From: Thomas Symalla Date: Thu, 20 Feb 2025 13:50:49 +0100 Subject: [PATCH 1/3] Add comments about arguments to op declarations --- lib/TableGen/GenDialect.cpp | 7 +++ test/example/generated/ExampleDialect.h.inc | 50 +++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/lib/TableGen/GenDialect.cpp b/lib/TableGen/GenDialect.cpp index 2d6a465..2642195 100644 --- a/lib/TableGen/GenDialect.cpp +++ b/lib/TableGen/GenDialect.cpp @@ -180,6 +180,13 @@ class Builder; if (!op.description.empty()) description += createCommentFromString(op.description); + if (op.getNumFullArguments() > 0) { + description += "/// Arguments\n"; + for (const auto &[idx, arg] : llvm::enumerate(op.getFullArguments())) + description += "/// " + arg.type->getBuilderCppType().str() + " " + + arg.name + "\n"; + } + out << tgfmt(R"( $2 class $_op : public $0 { diff --git a/test/example/generated/ExampleDialect.h.inc b/test/example/generated/ExampleDialect.h.inc index 0553f53..f07b080 100644 --- a/test/example/generated/ExampleDialect.h.inc +++ b/test/example/generated/ExampleDialect.h.inc @@ -117,6 +117,10 @@ Initial = 2, /// For those times when you want a little extra, this operation adds two /// numbers and puts a constant on top. /// +/// Arguments +/// ::llvm::Value * lhs +/// ::llvm::Value * rhs +/// uint32_t extra class Add32Op : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.add32"}; @@ -154,6 +158,9 @@ Extra = 2, /// /// Longer description of... well, you know by now how this goes. /// +/// Arguments +/// ::llvm::Value * lhs +/// ::llvm::Value * rhs class CombineOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.combine"}; @@ -188,6 +195,9 @@ Rhs = 1, /// /// Return the element of `vector` with the given `index`. /// +/// Arguments +/// ::llvm::Value * vector +/// ::llvm::Value * index class ExtractElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.extractelement"}; @@ -222,6 +232,8 @@ Index = 1, /// /// Demonstrate a more complex unification case. /// +/// Arguments +/// ::llvm::Value * source class FromFixedVectorOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.fromfixedvector"}; @@ -281,6 +293,8 @@ bool verifier(::llvm::raw_ostream &errs); /// Demonstrates the use of the same unevaluatable `le` predicate in a valued /// position. /// +/// Arguments +/// ::llvm::Value * source class IExtOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.iext"}; @@ -312,6 +326,8 @@ Source = 0, /// /// Demonstrates the use of a predicate in an unvalued position. /// +/// Arguments +/// ::llvm::Value * source class ITruncOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.itrunc"}; @@ -343,6 +359,8 @@ Source = 0, /// /// Make an argument immutable /// +/// Arguments +/// bool val class ImmutableOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.immutable.op"}; @@ -372,6 +390,10 @@ Val = 0, /// Insert the given `value` into the given `vector` at the given `index` and /// returns the result. /// +/// Arguments +/// ::llvm::Value * vector +/// ::llvm::Value * value +/// ::llvm::Value * index class InsertElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.insertelement"}; @@ -410,6 +432,9 @@ Index = 2, /// Like InstNameConflictOp but this has a second parameter named like the /// dialect compiler's first choice /// +/// Arguments +/// ::llvm::Value * instName +/// ::llvm::Value * instName_0 class InstNameConflictDoubleOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict.double"}; @@ -446,6 +471,8 @@ InstName_0 = 1, /// value like IRBuilder methods. This op produces a conflict so the parameter /// will be renamed. /// +/// Arguments +/// ::llvm::Value * instName class InstNameConflictOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict"}; @@ -612,6 +639,8 @@ bool verifier(::llvm::raw_ostream &errs); /// /// Longer description of how this operation writes pieces of data. /// +/// Arguments +/// ::llvm::Value * data class SetWriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.set.write"}; @@ -642,6 +671,8 @@ Data = 0, /// /// Returns the store size of the given type in bytes. /// +/// Arguments +/// ::llvm::Type * sizeof_type class SizeOfOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.sizeof"}; @@ -673,6 +704,10 @@ SizeofType = 0, /// /// Illustrate the use of the OpClass feature. /// +/// Arguments +/// ::llvm::Value * ptr +/// ::llvm::Value * count +/// ::llvm::Value * initial class StreamAddOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.add"}; @@ -700,6 +735,10 @@ bool verifier(::llvm::raw_ostream &errs); /// /// Illustrate the use of the OpClass feature. /// +/// Arguments +/// ::llvm::Value * ptr +/// ::llvm::Value * count +/// ::llvm::Value * initial class StreamMaxOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.max"}; @@ -727,6 +766,10 @@ bool verifier(::llvm::raw_ostream &errs); /// /// Illustrate the use of the OpClass feature. /// +/// Arguments +/// ::llvm::Value * ptr +/// ::llvm::Value * count +/// ::llvm::Value * initial class StreamMinOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.min"}; @@ -754,6 +797,8 @@ bool verifier(::llvm::raw_ostream &errs); /// /// The argument should not have a setter method /// +/// Arguments +/// ::llvm::StringRef val class StringAttrOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.string.attr.op"}; @@ -782,6 +827,8 @@ Val = 0, /// /// Longer description of how this operation writes a piece of data. /// +/// Arguments +/// ::llvm::Value * data class WriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write"}; @@ -812,6 +859,9 @@ Data = 0, /// /// Longer description of how this operation writes pieces of data. /// +/// Arguments +/// ::llvm::Value * data +/// ::llvm::ArrayRef<::llvm::Value *> args class WriteVarArgOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write.vararg"}; From a6385745dc6358e664263eb0dd586dfe37493516 Mon Sep 17 00:00:00 2001 From: Thomas Symalla Date: Fri, 28 Feb 2025 08:17:15 +0100 Subject: [PATCH 2/3] Remove `llvm::` prefix from argument comments --- include/llvm-dialects/TableGen/Common.h | 6 +++ lib/TableGen/Common.cpp | 11 +++- lib/TableGen/GenDialect.cpp | 9 ++-- test/example/generated/ExampleDialect.h.inc | 60 ++++++++++----------- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/include/llvm-dialects/TableGen/Common.h b/include/llvm-dialects/TableGen/Common.h index a63907e..ab434ce 100644 --- a/include/llvm-dialects/TableGen/Common.h +++ b/include/llvm-dialects/TableGen/Common.h @@ -36,6 +36,12 @@ void emitHeader(llvm::raw_ostream& out); bool shouldEmitComments(); +/// Replace all occurrences of needle in haystack with replacement and return +/// the new string. +std::string replaceSubstring(const std::string &haystack, + const std::string &needle, + const std::string &replacement = ""); + /// Prefix an incoming multi-line string with a single-line comment string line /// by line. std::string createCommentFromString(const std::string &input); diff --git a/lib/TableGen/Common.cpp b/lib/TableGen/Common.cpp index 7ad5108..c033aba 100644 --- a/lib/TableGen/Common.cpp +++ b/lib/TableGen/Common.cpp @@ -22,6 +22,9 @@ #include "llvm/Support/CommandLine.h" +#include +#include + using namespace llvm_dialects; using namespace llvm; @@ -36,8 +39,14 @@ void llvm_dialects::emitHeader(raw_ostream& out) { bool llvm_dialects::shouldEmitComments() { return g_emitComments; } +std::string llvm_dialects::replaceSubstring(const std::string &haystack, + const std::string &needle, + const std::string &replacement) { + return std::regex_replace(haystack, std::regex(needle), replacement); +} + std::string llvm_dialects::createCommentFromString(const std::string &input) { - StringRef inRef{input}; + const StringRef inRef{input}; if (inRef.trim().empty()) return input; diff --git a/lib/TableGen/GenDialect.cpp b/lib/TableGen/GenDialect.cpp index 2642195..6f21855 100644 --- a/lib/TableGen/GenDialect.cpp +++ b/lib/TableGen/GenDialect.cpp @@ -26,6 +26,7 @@ #include "llvm-dialects/TableGen/SymbolTable.h" #include "llvm-dialects/TableGen/Traits.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormatVariadic.h" @@ -182,9 +183,11 @@ class Builder; if (op.getNumFullArguments() > 0) { description += "/// Arguments\n"; - for (const auto &[idx, arg] : llvm::enumerate(op.getFullArguments())) - description += "/// " + arg.type->getBuilderCppType().str() + " " + - arg.name + "\n"; + for (const auto &[idx, arg] : llvm::enumerate(op.getFullArguments())) { + const std::string sanitizedName = + replaceSubstring(arg.type->getBuilderCppType().str(), "::llvm::"); + description += "/// " + sanitizedName + " " + arg.name + "\n"; + } } out << tgfmt(R"( diff --git a/test/example/generated/ExampleDialect.h.inc b/test/example/generated/ExampleDialect.h.inc index f07b080..c5600c9 100644 --- a/test/example/generated/ExampleDialect.h.inc +++ b/test/example/generated/ExampleDialect.h.inc @@ -118,8 +118,8 @@ Initial = 2, /// numbers and puts a constant on top. /// /// Arguments -/// ::llvm::Value * lhs -/// ::llvm::Value * rhs +/// Value * lhs +/// Value * rhs /// uint32_t extra class Add32Op : public ::llvm::CallInst { @@ -159,8 +159,8 @@ Extra = 2, /// Longer description of... well, you know by now how this goes. /// /// Arguments -/// ::llvm::Value * lhs -/// ::llvm::Value * rhs +/// Value * lhs +/// Value * rhs class CombineOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.combine"}; @@ -196,8 +196,8 @@ Rhs = 1, /// Return the element of `vector` with the given `index`. /// /// Arguments -/// ::llvm::Value * vector -/// ::llvm::Value * index +/// Value * vector +/// Value * index class ExtractElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.extractelement"}; @@ -233,7 +233,7 @@ Index = 1, /// Demonstrate a more complex unification case. /// /// Arguments -/// ::llvm::Value * source +/// Value * source class FromFixedVectorOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.fromfixedvector"}; @@ -294,7 +294,7 @@ bool verifier(::llvm::raw_ostream &errs); /// position. /// /// Arguments -/// ::llvm::Value * source +/// Value * source class IExtOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.iext"}; @@ -327,7 +327,7 @@ Source = 0, /// Demonstrates the use of a predicate in an unvalued position. /// /// Arguments -/// ::llvm::Value * source +/// Value * source class ITruncOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.itrunc"}; @@ -391,9 +391,9 @@ Val = 0, /// returns the result. /// /// Arguments -/// ::llvm::Value * vector -/// ::llvm::Value * value -/// ::llvm::Value * index +/// Value * vector +/// Value * value +/// Value * index class InsertElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.insertelement"}; @@ -433,8 +433,8 @@ Index = 2, /// dialect compiler's first choice /// /// Arguments -/// ::llvm::Value * instName -/// ::llvm::Value * instName_0 +/// Value * instName +/// Value * instName_0 class InstNameConflictDoubleOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict.double"}; @@ -472,7 +472,7 @@ InstName_0 = 1, /// will be renamed. /// /// Arguments -/// ::llvm::Value * instName +/// Value * instName class InstNameConflictOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict"}; @@ -640,7 +640,7 @@ bool verifier(::llvm::raw_ostream &errs); /// Longer description of how this operation writes pieces of data. /// /// Arguments -/// ::llvm::Value * data +/// Value * data class SetWriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.set.write"}; @@ -672,7 +672,7 @@ Data = 0, /// Returns the store size of the given type in bytes. /// /// Arguments -/// ::llvm::Type * sizeof_type +/// Type * sizeof_type class SizeOfOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.sizeof"}; @@ -705,9 +705,9 @@ SizeofType = 0, /// Illustrate the use of the OpClass feature. /// /// Arguments -/// ::llvm::Value * ptr -/// ::llvm::Value * count -/// ::llvm::Value * initial +/// Value * ptr +/// Value * count +/// Value * initial class StreamAddOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.add"}; @@ -736,9 +736,9 @@ bool verifier(::llvm::raw_ostream &errs); /// Illustrate the use of the OpClass feature. /// /// Arguments -/// ::llvm::Value * ptr -/// ::llvm::Value * count -/// ::llvm::Value * initial +/// Value * ptr +/// Value * count +/// Value * initial class StreamMaxOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.max"}; @@ -767,9 +767,9 @@ bool verifier(::llvm::raw_ostream &errs); /// Illustrate the use of the OpClass feature. /// /// Arguments -/// ::llvm::Value * ptr -/// ::llvm::Value * count -/// ::llvm::Value * initial +/// Value * ptr +/// Value * count +/// Value * initial class StreamMinOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.min"}; @@ -798,7 +798,7 @@ bool verifier(::llvm::raw_ostream &errs); /// The argument should not have a setter method /// /// Arguments -/// ::llvm::StringRef val +/// StringRef val class StringAttrOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.string.attr.op"}; @@ -828,7 +828,7 @@ Val = 0, /// Longer description of how this operation writes a piece of data. /// /// Arguments -/// ::llvm::Value * data +/// Value * data class WriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write"}; @@ -860,8 +860,8 @@ Data = 0, /// Longer description of how this operation writes pieces of data. /// /// Arguments -/// ::llvm::Value * data -/// ::llvm::ArrayRef<::llvm::Value *> args +/// Value * data +/// ArrayRef args class WriteVarArgOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write.vararg"}; From f32a908f0675d9ca2702024adf17872c2c987c99 Mon Sep 17 00:00:00 2001 From: Thomas Symalla Date: Mon, 10 Mar 2025 07:35:11 +0100 Subject: [PATCH 3/3] Add `* ` prefix to argument lines --- lib/TableGen/GenDialect.cpp | 2 +- test/example/generated/ExampleDialect.h.inc | 64 ++++++++++----------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/TableGen/GenDialect.cpp b/lib/TableGen/GenDialect.cpp index 6f21855..63b00c3 100644 --- a/lib/TableGen/GenDialect.cpp +++ b/lib/TableGen/GenDialect.cpp @@ -186,7 +186,7 @@ class Builder; for (const auto &[idx, arg] : llvm::enumerate(op.getFullArguments())) { const std::string sanitizedName = replaceSubstring(arg.type->getBuilderCppType().str(), "::llvm::"); - description += "/// " + sanitizedName + " " + arg.name + "\n"; + description += "/// * " + sanitizedName + " " + arg.name + "\n"; } } diff --git a/test/example/generated/ExampleDialect.h.inc b/test/example/generated/ExampleDialect.h.inc index c5600c9..ecb210a 100644 --- a/test/example/generated/ExampleDialect.h.inc +++ b/test/example/generated/ExampleDialect.h.inc @@ -118,9 +118,9 @@ Initial = 2, /// numbers and puts a constant on top. /// /// Arguments -/// Value * lhs -/// Value * rhs -/// uint32_t extra +/// * Value * lhs +/// * Value * rhs +/// * uint32_t extra class Add32Op : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.add32"}; @@ -159,8 +159,8 @@ Extra = 2, /// Longer description of... well, you know by now how this goes. /// /// Arguments -/// Value * lhs -/// Value * rhs +/// * Value * lhs +/// * Value * rhs class CombineOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.combine"}; @@ -196,8 +196,8 @@ Rhs = 1, /// Return the element of `vector` with the given `index`. /// /// Arguments -/// Value * vector -/// Value * index +/// * Value * vector +/// * Value * index class ExtractElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.extractelement"}; @@ -233,7 +233,7 @@ Index = 1, /// Demonstrate a more complex unification case. /// /// Arguments -/// Value * source +/// * Value * source class FromFixedVectorOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.fromfixedvector"}; @@ -294,7 +294,7 @@ bool verifier(::llvm::raw_ostream &errs); /// position. /// /// Arguments -/// Value * source +/// * Value * source class IExtOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.iext"}; @@ -327,7 +327,7 @@ Source = 0, /// Demonstrates the use of a predicate in an unvalued position. /// /// Arguments -/// Value * source +/// * Value * source class ITruncOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.itrunc"}; @@ -360,7 +360,7 @@ Source = 0, /// Make an argument immutable /// /// Arguments -/// bool val +/// * bool val class ImmutableOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.immutable.op"}; @@ -391,9 +391,9 @@ Val = 0, /// returns the result. /// /// Arguments -/// Value * vector -/// Value * value -/// Value * index +/// * Value * vector +/// * Value * value +/// * Value * index class InsertElementOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.insertelement"}; @@ -433,8 +433,8 @@ Index = 2, /// dialect compiler's first choice /// /// Arguments -/// Value * instName -/// Value * instName_0 +/// * Value * instName +/// * Value * instName_0 class InstNameConflictDoubleOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict.double"}; @@ -472,7 +472,7 @@ InstName_0 = 1, /// will be renamed. /// /// Arguments -/// Value * instName +/// * Value * instName class InstNameConflictOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.inst.name.conflict"}; @@ -640,7 +640,7 @@ bool verifier(::llvm::raw_ostream &errs); /// Longer description of how this operation writes pieces of data. /// /// Arguments -/// Value * data +/// * Value * data class SetWriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.set.write"}; @@ -672,7 +672,7 @@ Data = 0, /// Returns the store size of the given type in bytes. /// /// Arguments -/// Type * sizeof_type +/// * Type * sizeof_type class SizeOfOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.sizeof"}; @@ -705,9 +705,9 @@ SizeofType = 0, /// Illustrate the use of the OpClass feature. /// /// Arguments -/// Value * ptr -/// Value * count -/// Value * initial +/// * Value * ptr +/// * Value * count +/// * Value * initial class StreamAddOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.add"}; @@ -736,9 +736,9 @@ bool verifier(::llvm::raw_ostream &errs); /// Illustrate the use of the OpClass feature. /// /// Arguments -/// Value * ptr -/// Value * count -/// Value * initial +/// * Value * ptr +/// * Value * count +/// * Value * initial class StreamMaxOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.max"}; @@ -767,9 +767,9 @@ bool verifier(::llvm::raw_ostream &errs); /// Illustrate the use of the OpClass feature. /// /// Arguments -/// Value * ptr -/// Value * count -/// Value * initial +/// * Value * ptr +/// * Value * count +/// * Value * initial class StreamMinOp : public StreamReduceOp { static const ::llvm::StringLiteral s_name; //{"xd.ir.stream.min"}; @@ -798,7 +798,7 @@ bool verifier(::llvm::raw_ostream &errs); /// The argument should not have a setter method /// /// Arguments -/// StringRef val +/// * StringRef val class StringAttrOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.string.attr.op"}; @@ -828,7 +828,7 @@ Val = 0, /// Longer description of how this operation writes a piece of data. /// /// Arguments -/// Value * data +/// * Value * data class WriteOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write"}; @@ -860,8 +860,8 @@ Data = 0, /// Longer description of how this operation writes pieces of data. /// /// Arguments -/// Value * data -/// ArrayRef args +/// * Value * data +/// * ArrayRef args class WriteVarArgOp : public ::llvm::CallInst { static const ::llvm::StringLiteral s_name; //{"xd.ir.write.vararg"};