xref: /llvm-project/mlir/tools/mlir-tblgen/PassDocGen.cpp (revision e813750354bbc08551cf23ff559a54b4a9ea1f29)
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