1 | //===- PassDocGen.cpp - MLIR pass documentation generator -----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // PassDocGen uses the description of passes to generate documentation. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "DocGenUtilities.h" |
14 | #include "mlir/TableGen/GenInfo.h" |
15 | #include "mlir/TableGen/Pass.h" |
16 | #include "llvm/Support/FormatVariadic.h" |
17 | #include "llvm/TableGen/Record.h" |
18 | |
19 | using namespace mlir; |
20 | using namespace mlir::tblgen; |
21 | |
22 | /// Emit the documentation for the given pass. |
23 | static void emitDoc(const Pass &pass, raw_ostream &os) { |
24 | os << llvm::formatv(Fmt: "### `-{0}`\n" , Vals: pass.getArgument()); |
25 | emitSummary(summary: pass.getSummary(), os); |
26 | emitDescription(description: pass.getDescription(), os); |
27 | |
28 | // Handle the options of the pass. |
29 | ArrayRef<PassOption> options = pass.getOptions(); |
30 | if (!options.empty()) { |
31 | os << "\n#### Options\n```\n" ; |
32 | size_t longestOption = 0; |
33 | for (const PassOption &option : options) |
34 | longestOption = std::max(a: option.getArgument().size(), b: longestOption); |
35 | for (const PassOption &option : options) { |
36 | os << "-" << option.getArgument(); |
37 | os.indent(NumSpaces: longestOption - option.getArgument().size()) |
38 | << " : " << option.getDescription() << "\n" ; |
39 | } |
40 | os << "```\n" ; |
41 | } |
42 | |
43 | // Handle the statistics of the pass. |
44 | ArrayRef<PassStatistic> stats = pass.getStatistics(); |
45 | if (!stats.empty()) { |
46 | os << "\n#### Statistics\n```\n" ; |
47 | size_t longestStat = 0; |
48 | for (const PassStatistic &stat : stats) |
49 | longestStat = std::max(a: stat.getName().size(), b: longestStat); |
50 | for (const PassStatistic &stat : stats) { |
51 | os << stat.getName(); |
52 | os.indent(NumSpaces: longestStat - stat.getName().size()) |
53 | << " : " << stat.getDescription() << "\n" ; |
54 | } |
55 | os << "```\n" ; |
56 | } |
57 | } |
58 | |
59 | static void emitDocs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os) { |
60 | os << "<!-- Autogenerated by mlir-tblgen; don't manually edit -->\n" ; |
61 | auto passDefs = recordKeeper.getAllDerivedDefinitions(ClassName: "PassBase" ); |
62 | |
63 | // Collect the registered passes, sorted by argument name. |
64 | SmallVector<Pass, 16> passes(passDefs.begin(), passDefs.end()); |
65 | SmallVector<Pass *, 16> sortedPasses(llvm::make_pointer_range(Range&: passes)); |
66 | llvm::array_pod_sort(Start: sortedPasses.begin(), End: sortedPasses.end(), |
67 | Compare: [](Pass *const *lhs, Pass *const *rhs) { |
68 | return (*lhs)->getArgument().compare( |
69 | RHS: (*rhs)->getArgument()); |
70 | }); |
71 | for (Pass *pass : sortedPasses) |
72 | emitDoc(pass: *pass, os); |
73 | } |
74 | |
75 | static mlir::GenRegistration |
76 | genRegister("gen-pass-doc" , "Generate pass documentation" , |
77 | [](const llvm::RecordKeeper &records, raw_ostream &os) { |
78 | emitDocs(recordKeeper: records, os); |
79 | return false; |
80 | }); |
81 | |