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("### `-{0}`: {1}\n", pass.getArgument(), 25 pass.getSummary()); 26 emitDescription(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(option.getArgument().size(), longestOption); 35 for (const PassOption &option : options) { 36 os << "-" << option.getArgument(); 37 os.indent(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(stat.getName().size(), longestStat); 50 for (const PassStatistic &stat : stats) { 51 os << stat.getName(); 52 os.indent(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("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(passes)); 66 llvm::array_pod_sort(sortedPasses.begin(), sortedPasses.end(), 67 [](Pass *const *lhs, Pass *const *rhs) { 68 return (*lhs)->getArgument().compare( 69 (*rhs)->getArgument()); 70 }); 71 for (Pass *pass : sortedPasses) 72 emitDoc(*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(records, os); 79 return false; 80 }); 81