diff --git a/mlir/test/mlir-tblgen/gen-dialect-doc.td b/mlir/test/mlir-tblgen/gen-dialect-doc.td index 120164345fb2c..ca0b6e38edf82 100644 --- a/mlir/test/mlir-tblgen/gen-dialect-doc.td +++ b/mlir/test/mlir-tblgen/gen-dialect-doc.td @@ -85,7 +85,7 @@ def TestTypeDefParams : TypeDef { // CHECK: Interfaces: NoMemoryEffect (MemoryEffectOpInterface) // CHECK: Effects: MemoryEffects::Effect{} -// CHECK: ## Attribute constraint definition +// CHECK: ## Attribute constraints // CHECK: ### attribute summary // CHECK: attribute description @@ -97,7 +97,7 @@ def TestTypeDefParams : TypeDef { // CHECK: Syntax: // CHECK: #test.test_attr_def_params -// CHECK: ## Type constraint definition +// CHECK: ## Type constraints // CHECK: ### type summary // CHECK: type description diff --git a/mlir/tools/mlir-tblgen/OpDocGen.cpp b/mlir/tools/mlir-tblgen/OpDocGen.cpp index 773ad6ec198b9..b5b26a70859ec 100644 --- a/mlir/tools/mlir-tblgen/OpDocGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp @@ -265,10 +265,22 @@ static void emitOpDoc(const Operator &op, raw_ostream &os) { os << "\n"; } +static void emitSourceLink(StringRef inputFilename, raw_ostream &os) { + size_t pathBegin = inputFilename.find("mlir/include/mlir/"); + if (pathBegin == StringRef::npos) + return; + + StringRef inputFromMlirInclude = inputFilename.substr(pathBegin); + + os << "[source](https://github.com/llvm/llvm-project/blob/main/" + << inputFromMlirInclude << ")\n\n"; +} + static void emitOpDoc(const RecordKeeper &recordKeeper, raw_ostream &os) { auto opDefs = getRequestedOpDefinitions(recordKeeper); os << "\n"; + emitSourceLink(recordKeeper.getInputFilename(), os); for (const llvm::Record *opDef : opDefs) emitOpDoc(Operator(opDef), os); } @@ -392,12 +404,13 @@ static void maybeNest(bool nest, llvm::function_ref fn, } } -static void emitBlock(ArrayRef attributes, +static void emitBlock(ArrayRef attributes, StringRef inputFilename, ArrayRef attrDefs, ArrayRef ops, ArrayRef types, ArrayRef typeDefs, raw_ostream &os) { if (!ops.empty()) { - os << "## Operation definition\n\n"; + os << "## Operations\n\n"; + emitSourceLink(inputFilename, os); for (const OpDocGroup &grouping : ops) { bool nested = !grouping.summary.empty(); maybeNest( @@ -417,32 +430,32 @@ static void emitBlock(ArrayRef attributes, } if (!attributes.empty()) { - os << "## Attribute constraint definition\n\n"; + os << "## Attribute constraints\n\n"; for (const Attribute &attr : attributes) emitAttrDoc(attr, os); } if (!attrDefs.empty()) { - os << "## Attribute definition\n\n"; + os << "## Attributes\n\n"; for (const AttrDef &def : attrDefs) emitAttrOrTypeDefDoc(def, os); } // TODO: Add link between use and def for types if (!types.empty()) { - os << "## Type constraint definition\n\n"; + os << "## Type constraints\n\n"; for (const Type &type : types) emitTypeDoc(type, os); } if (!typeDefs.empty()) { - os << "## Type definition\n\n"; + os << "## Types\n\n"; for (const TypeDef &def : typeDefs) emitAttrOrTypeDefDoc(def, os); } } -static void emitDialectDoc(const Dialect &dialect, +static void emitDialectDoc(const Dialect &dialect, StringRef inputFilename, ArrayRef attributes, ArrayRef attrDefs, ArrayRef ops, ArrayRef types, ArrayRef typeDefs, @@ -456,7 +469,7 @@ static void emitDialectDoc(const Dialect &dialect, if (!r.match(dialect.getDescription())) os << "[TOC]\n\n"; - emitBlock(attributes, attrDefs, ops, types, typeDefs, os); + emitBlock(attributes, inputFilename, attrDefs, ops, types, typeDefs, os); } static bool emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) { @@ -536,8 +549,9 @@ static bool emitDialectDoc(const RecordKeeper &recordKeeper, raw_ostream &os) { }); os << "\n"; - emitDialectDoc(*dialect, dialectAttrs, dialectAttrDefs, dialectOps, - dialectTypes, dialectTypeDefs, os); + emitDialectDoc(*dialect, recordKeeper.getInputFilename(), dialectAttrs, + dialectAttrDefs, dialectOps, dialectTypes, dialectTypeDefs, + os); return false; }