19be4be3eSRiver Riddle //===- PassDocGen.cpp - MLIR pass documentation generator -----------------===// 29be4be3eSRiver Riddle // 39be4be3eSRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 49be4be3eSRiver Riddle // See https://llvm.org/LICENSE.txt for license information. 59be4be3eSRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69be4be3eSRiver Riddle // 79be4be3eSRiver Riddle //===----------------------------------------------------------------------===// 89be4be3eSRiver Riddle // 99be4be3eSRiver Riddle // PassDocGen uses the description of passes to generate documentation. 109be4be3eSRiver Riddle // 119be4be3eSRiver Riddle //===----------------------------------------------------------------------===// 129be4be3eSRiver Riddle 139be4be3eSRiver Riddle #include "DocGenUtilities.h" 149be4be3eSRiver Riddle #include "mlir/TableGen/GenInfo.h" 159be4be3eSRiver Riddle #include "mlir/TableGen/Pass.h" 169be4be3eSRiver Riddle #include "llvm/Support/FormatVariadic.h" 179be4be3eSRiver Riddle #include "llvm/TableGen/Record.h" 189be4be3eSRiver Riddle 199be4be3eSRiver Riddle using namespace mlir; 209be4be3eSRiver Riddle using namespace mlir::tblgen; 21bccd37f6SRahul Joshi using llvm::RecordKeeper; 229be4be3eSRiver Riddle 239be4be3eSRiver Riddle /// Emit the documentation for the given pass. 249be4be3eSRiver Riddle static void emitDoc(const Pass &pass, raw_ostream &os) { 254acbd444Srikhuijzer os << llvm::formatv("### `-{0}`\n", pass.getArgument()); 264acbd444Srikhuijzer emitSummary(pass.getSummary(), os); 279be4be3eSRiver Riddle emitDescription(pass.getDescription(), os); 289be4be3eSRiver Riddle 299be4be3eSRiver Riddle // Handle the options of the pass. 309be4be3eSRiver Riddle ArrayRef<PassOption> options = pass.getOptions(); 319be4be3eSRiver Riddle if (!options.empty()) { 329be4be3eSRiver Riddle os << "\n#### Options\n```\n"; 339be4be3eSRiver Riddle size_t longestOption = 0; 349be4be3eSRiver Riddle for (const PassOption &option : options) 359be4be3eSRiver Riddle longestOption = std::max(option.getArgument().size(), longestOption); 369be4be3eSRiver Riddle for (const PassOption &option : options) { 379be4be3eSRiver Riddle os << "-" << option.getArgument(); 389be4be3eSRiver Riddle os.indent(longestOption - option.getArgument().size()) 399be4be3eSRiver Riddle << " : " << option.getDescription() << "\n"; 409be4be3eSRiver Riddle } 419be4be3eSRiver Riddle os << "```\n"; 429be4be3eSRiver Riddle } 439be4be3eSRiver Riddle 449be4be3eSRiver Riddle // Handle the statistics of the pass. 459be4be3eSRiver Riddle ArrayRef<PassStatistic> stats = pass.getStatistics(); 469be4be3eSRiver Riddle if (!stats.empty()) { 479be4be3eSRiver Riddle os << "\n#### Statistics\n```\n"; 489be4be3eSRiver Riddle size_t longestStat = 0; 499be4be3eSRiver Riddle for (const PassStatistic &stat : stats) 509be4be3eSRiver Riddle longestStat = std::max(stat.getName().size(), longestStat); 519be4be3eSRiver Riddle for (const PassStatistic &stat : stats) { 529be4be3eSRiver Riddle os << stat.getName(); 539be4be3eSRiver Riddle os.indent(longestStat - stat.getName().size()) 549be4be3eSRiver Riddle << " : " << stat.getDescription() << "\n"; 559be4be3eSRiver Riddle } 569be4be3eSRiver Riddle os << "```\n"; 579be4be3eSRiver Riddle } 589be4be3eSRiver Riddle } 599be4be3eSRiver Riddle 60*e8137503SRahul Joshi static void emitDocs(const RecordKeeper &records, raw_ostream &os) { 619be4be3eSRiver Riddle os << "<!-- Autogenerated by mlir-tblgen; don't manually edit -->\n"; 62*e8137503SRahul Joshi auto passDefs = records.getAllDerivedDefinitions("PassBase"); 639be4be3eSRiver Riddle 649be4be3eSRiver Riddle // Collect the registered passes, sorted by argument name. 659be4be3eSRiver Riddle SmallVector<Pass, 16> passes(passDefs.begin(), passDefs.end()); 669be4be3eSRiver Riddle SmallVector<Pass *, 16> sortedPasses(llvm::make_pointer_range(passes)); 679be4be3eSRiver Riddle llvm::array_pod_sort(sortedPasses.begin(), sortedPasses.end(), 689be4be3eSRiver Riddle [](Pass *const *lhs, Pass *const *rhs) { 699be4be3eSRiver Riddle return (*lhs)->getArgument().compare( 709be4be3eSRiver Riddle (*rhs)->getArgument()); 719be4be3eSRiver Riddle }); 729be4be3eSRiver Riddle for (Pass *pass : sortedPasses) 739be4be3eSRiver Riddle emitDoc(*pass, os); 749be4be3eSRiver Riddle } 759be4be3eSRiver Riddle 769be4be3eSRiver Riddle static mlir::GenRegistration 779be4be3eSRiver Riddle genRegister("gen-pass-doc", "Generate pass documentation", 78bccd37f6SRahul Joshi [](const RecordKeeper &records, raw_ostream &os) { 799be4be3eSRiver Riddle emitDocs(records, os); 809be4be3eSRiver Riddle return false; 819be4be3eSRiver Riddle }); 82