diff --git a/mlir/test/mlir-tblgen/gen-dialect-doc.td b/mlir/test/mlir-tblgen/gen-dialect-doc.td --- a/mlir/test/mlir-tblgen/gen-dialect-doc.td +++ b/mlir/test/mlir-tblgen/gen-dialect-doc.td @@ -29,6 +29,11 @@ // CHECK: TOC added by tool. // CHECK: [TOC] +// CHECK-NOT: [TOC] +// CHECK: Traits: SingleBlockImplicitTerminator +// CHECK: Interfaces: NoSideEffect (MemoryEffectOpInterface) +// CHECK: Effects: MemoryEffects::Effect{} + // CHECK: ## Attribute constraint definition // CHECK: ### attribute summary // CHECK: attribute description @@ -37,10 +42,6 @@ // CHECK: ### type summary // CHECK: type description -// CHECK-NOT: [TOC] -// CHECK: Traits: SingleBlockImplicitTerminator -// CHECK: Interfaces: NoSideEffect (MemoryEffectOpInterface) -// CHECK: Effects: MemoryEffects::Effect{} def Toc_Dialect : Dialect { let name = "test_toc"; diff --git a/mlir/tools/mlir-tblgen/OpDocGen.cpp b/mlir/tools/mlir-tblgen/OpDocGen.cpp --- a/mlir/tools/mlir-tblgen/OpDocGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDocGen.cpp @@ -316,6 +316,12 @@ if (!r.match(dialect.getDescription())) os << "[TOC]\n\n"; + if (!ops.empty()) { + os << "## Operation definition\n\n"; + for (const Operator &op : ops) + emitOpDoc(op, os); + } + if (!attributes.empty()) { os << "## Attribute constraint definition\n\n"; for (const Attribute &attr : attributes) @@ -335,12 +341,6 @@ emitTypeDoc(type, os); } - if (!ops.empty()) { - os << "## Operation definition\n\n"; - for (const Operator &op : ops) - emitOpDoc(op, os); - } - if (!typeDefs.empty()) { os << "## Type definition\n\n"; for (const TypeDef &def : typeDefs) @@ -367,35 +367,42 @@ llvm::StringMap> dialectOps; llvm::StringMap> dialectTypes; llvm::StringMap> dialectTypeDefs; + llvm::SmallDenseSet seen; + for (Record *attrDef : attrDefDefs) { + AttrDef attr(attrDef); + dialectAttrDefs[attr.getDialect().getName()].push_back(attr); + dialectsWithDocs.insert(attr.getDialect()); + seen.insert(attrDef); + } for (Record *attrDef : attrDefs) { + if (seen.count(attrDef)) + continue; Attribute attr(attrDef); if (const Dialect &dialect = attr.getDialect()) { dialectAttrs[dialect.getName()].push_back(attr); dialectsWithDocs.insert(dialect); } } - for (Record *attrDef : attrDefDefs) { - AttrDef attr(attrDef); - dialectAttrDefs[attr.getDialect().getName()].push_back(attr); - dialectsWithDocs.insert(attr.getDialect()); - } for (Record *opDef : opDefs) { Operator op(opDef); dialectOps[op.getDialect().getName()].push_back(op); dialectsWithDocs.insert(op.getDialect()); } + for (Record *typeDef : typeDefDefs) { + TypeDef type(typeDef); + dialectTypeDefs[type.getDialect().getName()].push_back(type); + dialectsWithDocs.insert(type.getDialect()); + seen.insert(typeDef); + } for (Record *typeDef : typeDefs) { + if (seen.count(typeDef)) + continue; Type type(typeDef); if (const Dialect &dialect = type.getDialect()) { dialectTypes[dialect.getName()].push_back(type); dialectsWithDocs.insert(dialect); } } - for (Record *typeDef : typeDefDefs) { - TypeDef type(typeDef); - dialectTypeDefs[type.getDialect().getName()].push_back(type); - dialectsWithDocs.insert(type.getDialect()); - } Optional dialect = findDialectToGenerate(dialectsWithDocs.getArrayRef());