Skip to content

Commit 50260f8

Browse files
authored
Auto-generate comments for dialect ops. (GPUOpen-Drivers#118)
Currently, the summary and description fields for dialect ops remain unused. Add those as comment above the class declaration.
1 parent d3ef239 commit 50260f8

File tree

8 files changed

+370
-1
lines changed

8 files changed

+370
-1
lines changed

example/ExampleDialect.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,19 @@ def StringAttrOp : Op<ExampleDialect, "string.attr.op", [WillReturn]> {
320320
The argument should not have a setter method
321321
}];
322322
}
323+
324+
def NoSummaryOp : Op<ExampleDialect, "no.summary.op", [WillReturn]> {
325+
let results = (outs);
326+
let arguments = (ins);
327+
328+
let description = [{
329+
Some description
330+
}];
331+
}
332+
333+
def NoDescriptionOp : Op<ExampleDialect, "no.description.op", [WillReturn]> {
334+
let results = (outs);
335+
let arguments = (ins);
336+
337+
let summary = "Some summary";
338+
}

include/llvm-dialects/TableGen/Common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "llvm/Support/raw_ostream.h"
2222
#include "llvm/TableGen/Record.h"
23+
#include <string>
2324

2425
#if !defined(LLVM_MAIN_REVISION) || LLVM_MAIN_REVISION >= 513628
2526
using RecordKeeperTy = const llvm::RecordKeeper;
@@ -35,4 +36,8 @@ void emitHeader(llvm::raw_ostream& out);
3536

3637
bool shouldEmitComments();
3738

39+
/// Prefix an incoming multi-line string with a single-line comment string line
40+
/// by line.
41+
std::string createCommentFromString(const std::string &input);
42+
3843
} // namespace llvm_dialects

include/llvm-dialects/TableGen/Operations.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class Operation : public OperationBase {
103103
public:
104104
std::string name;
105105
std::string mnemonic;
106+
std::string summary;
107+
std::string description;
106108
std::vector<Trait *> traits;
107109

108110
std::vector<NamedValue> results;

lib/TableGen/Common.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818

1919
#include "llvm-dialects/TableGen/Common.h"
20+
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/ADT/StringRef.h"
2022

2123
#include "llvm/Support/CommandLine.h"
2224

@@ -33,3 +35,18 @@ void llvm_dialects::emitHeader(raw_ostream& out) {
3335
}
3436

3537
bool llvm_dialects::shouldEmitComments() { return g_emitComments; }
38+
39+
std::string llvm_dialects::createCommentFromString(const std::string &input) {
40+
StringRef inRef{input};
41+
if (inRef.trim().empty())
42+
return input;
43+
44+
SmallVector<StringRef> lines;
45+
inRef.split(lines, '\n');
46+
47+
std::string outStr;
48+
for (auto line : lines)
49+
outStr += "/// " + line.str() + '\n';
50+
51+
return outStr;
52+
}

lib/TableGen/GenDialect.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,16 @@ class Builder;
172172
fmt.withOp(op.name);
173173
fmt.addSubst("mnemonic", op.mnemonic);
174174

175+
std::string description = "/// " + op.name + '\n';
176+
177+
if (!op.summary.empty())
178+
description += createCommentFromString(op.summary);
179+
180+
if (!op.description.empty())
181+
description += createCommentFromString(op.description);
182+
175183
out << tgfmt(R"(
184+
$2
176185
class $_op : public $0 {
177186
static const ::llvm::StringLiteral s_name; //{"$dialect.$mnemonic"};
178187
@@ -188,7 +197,8 @@ class Builder;
188197
&fmt,
189198
op.superclass() ? op.superclass()->name : "::llvm::CallInst",
190199
!op.haveResultOverloads() ? "isSimpleOperation"
191-
: "isOverloadedOperation");
200+
: "isOverloadedOperation",
201+
description);
192202

193203
for (const auto &builder : op.builders())
194204
builder.emitDeclaration(out, fmt);

lib/TableGen/Operations.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ bool Operation::parse(raw_ostream &errs, GenDialectsContext *context,
360360

361361
op->name = record->getName();
362362
op->mnemonic = record->getValueAsString("mnemonic");
363+
if (!record->isValueUnset("summary"))
364+
op->summary = record->getValueAsString("summary");
365+
366+
if (!record->isValueUnset("description"))
367+
op->description = record->getValueAsString("description");
363368
for (RecordTy *traitRec : record->getValueAsListOfDefs("traits"))
364369
op->traits.push_back(context->getTrait(traitRec));
365370

test/example/generated/ExampleDialect.cpp.inc

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ namespace xd::cpp {
112112
state.setError();
113113
});
114114

115+
builder.add<NoDescriptionOp>([](::llvm_dialects::VerifierState &state, NoDescriptionOp &op) {
116+
if (!op.verifier(state.out()))
117+
state.setError();
118+
});
119+
120+
builder.add<NoSummaryOp>([](::llvm_dialects::VerifierState &state, NoSummaryOp &op) {
121+
if (!op.verifier(state.out()))
122+
state.setError();
123+
});
124+
115125
builder.add<ReadOp>([](::llvm_dialects::VerifierState &state, ReadOp &op) {
116126
if (!op.verifier(state.out()))
117127
state.setError();
@@ -1519,6 +1529,108 @@ instName
15191529

15201530

15211531

1532+
const ::llvm::StringLiteral NoDescriptionOp::s_name{"xd.ir.no.description.op"};
1533+
1534+
NoDescriptionOp* NoDescriptionOp::create(llvm_dialects::Builder& b, const llvm::Twine &instName) {
1535+
::llvm::LLVMContext& context = b.getContext();
1536+
(void)context;
1537+
::llvm::Module& module = *b.GetInsertBlock()->getModule();
1538+
1539+
1540+
const ::llvm::AttributeList attrs
1541+
= ExampleDialect::get(context).getAttributeList(4);
1542+
auto fnType = ::llvm::FunctionType::get(::llvm::Type::getVoidTy(context), {
1543+
}, false);
1544+
1545+
auto fn = module.getOrInsertFunction(s_name, fnType, attrs);
1546+
::llvm::SmallString<32> newName;
1547+
for (unsigned i = 0; !::llvm::isa<::llvm::Function>(fn.getCallee()) ||
1548+
::llvm::cast<::llvm::Function>(fn.getCallee())->getFunctionType() != fn.getFunctionType(); i++) {
1549+
// If a function with the same name but a different types already exists,
1550+
// we get a bitcast of a function or a function with the wrong type.
1551+
// Try new names until we get one with the correct type.
1552+
newName = "";
1553+
::llvm::raw_svector_ostream newNameStream(newName);
1554+
newNameStream << s_name << "_" << i;
1555+
fn = module.getOrInsertFunction(newNameStream.str(), fnType, attrs);
1556+
}
1557+
assert(::llvm::isa<::llvm::Function>(fn.getCallee()));
1558+
assert(fn.getFunctionType() == fnType);
1559+
assert(::llvm::cast<::llvm::Function>(fn.getCallee())->getFunctionType() == fn.getFunctionType());
1560+
1561+
return ::llvm::cast<NoDescriptionOp>(b.CreateCall(fn, std::nullopt, instName));
1562+
}
1563+
1564+
1565+
bool NoDescriptionOp::verifier(::llvm::raw_ostream &errs) {
1566+
::llvm::LLVMContext &context = getModule()->getContext();
1567+
(void)context;
1568+
1569+
using ::llvm_dialects::printable;
1570+
1571+
if (arg_size() != 0) {
1572+
errs << " wrong number of arguments: " << arg_size()
1573+
<< ", expected 0\n";
1574+
return false;
1575+
}
1576+
return true;
1577+
}
1578+
1579+
1580+
1581+
1582+
1583+
const ::llvm::StringLiteral NoSummaryOp::s_name{"xd.ir.no.summary.op"};
1584+
1585+
NoSummaryOp* NoSummaryOp::create(llvm_dialects::Builder& b, const llvm::Twine &instName) {
1586+
::llvm::LLVMContext& context = b.getContext();
1587+
(void)context;
1588+
::llvm::Module& module = *b.GetInsertBlock()->getModule();
1589+
1590+
1591+
const ::llvm::AttributeList attrs
1592+
= ExampleDialect::get(context).getAttributeList(4);
1593+
auto fnType = ::llvm::FunctionType::get(::llvm::Type::getVoidTy(context), {
1594+
}, false);
1595+
1596+
auto fn = module.getOrInsertFunction(s_name, fnType, attrs);
1597+
::llvm::SmallString<32> newName;
1598+
for (unsigned i = 0; !::llvm::isa<::llvm::Function>(fn.getCallee()) ||
1599+
::llvm::cast<::llvm::Function>(fn.getCallee())->getFunctionType() != fn.getFunctionType(); i++) {
1600+
// If a function with the same name but a different types already exists,
1601+
// we get a bitcast of a function or a function with the wrong type.
1602+
// Try new names until we get one with the correct type.
1603+
newName = "";
1604+
::llvm::raw_svector_ostream newNameStream(newName);
1605+
newNameStream << s_name << "_" << i;
1606+
fn = module.getOrInsertFunction(newNameStream.str(), fnType, attrs);
1607+
}
1608+
assert(::llvm::isa<::llvm::Function>(fn.getCallee()));
1609+
assert(fn.getFunctionType() == fnType);
1610+
assert(::llvm::cast<::llvm::Function>(fn.getCallee())->getFunctionType() == fn.getFunctionType());
1611+
1612+
return ::llvm::cast<NoSummaryOp>(b.CreateCall(fn, std::nullopt, instName));
1613+
}
1614+
1615+
1616+
bool NoSummaryOp::verifier(::llvm::raw_ostream &errs) {
1617+
::llvm::LLVMContext &context = getModule()->getContext();
1618+
(void)context;
1619+
1620+
using ::llvm_dialects::printable;
1621+
1622+
if (arg_size() != 0) {
1623+
errs << " wrong number of arguments: " << arg_size()
1624+
<< ", expected 0\n";
1625+
return false;
1626+
}
1627+
return true;
1628+
}
1629+
1630+
1631+
1632+
1633+
15221634
const ::llvm::StringLiteral ReadOp::s_name{"xd.ir.read"};
15231635

15241636
ReadOp* ReadOp::create(llvm_dialects::Builder& b, ::llvm::Type* dataType, const llvm::Twine &instName) {
@@ -2357,6 +2469,22 @@ data
23572469
}
23582470

23592471

2472+
template <>
2473+
const ::llvm_dialects::OpDescription &
2474+
::llvm_dialects::OpDescription::get<xd::cpp::NoDescriptionOp>() {
2475+
static const ::llvm_dialects::OpDescription desc{false, "xd.ir.no.description.op"};
2476+
return desc;
2477+
}
2478+
2479+
2480+
template <>
2481+
const ::llvm_dialects::OpDescription &
2482+
::llvm_dialects::OpDescription::get<xd::cpp::NoSummaryOp>() {
2483+
static const ::llvm_dialects::OpDescription desc{false, "xd.ir.no.summary.op"};
2484+
return desc;
2485+
}
2486+
2487+
23602488
template <>
23612489
const ::llvm_dialects::OpDescription &
23622490
::llvm_dialects::OpDescription::get<xd::cpp::ReadOp>() {

0 commit comments

Comments
 (0)