//===- PassDocGen.cpp - MLIR pass documentation generator -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// PassDocGen uses the description of passes to generate documentation.
//
//===----------------------------------------------------------------------===//

#include "DocGenUtilities.h"
#include "mlir/TableGen/GenInfo.h"
#include "mlir/TableGen/Pass.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Record.h"

using namespace mlir;
using namespace mlir::tblgen;

/// Emit the documentation for the given pass.
static void emitDoc(const Pass &pass, raw_ostream &os) {
  os << llvm::formatv("### `-{0}`\n", pass.getArgument());
  emitSummary(pass.getSummary(), os);
  emitDescription(pass.getDescription(), os);

  // Handle the options of the pass.
  ArrayRef<PassOption> options = pass.getOptions();
  if (!options.empty()) {
    os << "\n#### Options\n```\n";
    size_t longestOption = 0;
    for (const PassOption &option : options)
      longestOption = std::max(option.getArgument().size(), longestOption);
    for (const PassOption &option : options) {
      os << "-" << option.getArgument();
      os.indent(longestOption - option.getArgument().size())
          << " : " << option.getDescription() << "\n";
    }
    os << "```\n";
  }

  // Handle the statistics of the pass.
  ArrayRef<PassStatistic> stats = pass.getStatistics();
  if (!stats.empty()) {
    os << "\n#### Statistics\n```\n";
    size_t longestStat = 0;
    for (const PassStatistic &stat : stats)
      longestStat = std::max(stat.getName().size(), longestStat);
    for (const PassStatistic &stat : stats) {
      os << stat.getName();
      os.indent(longestStat - stat.getName().size())
          << " : " << stat.getDescription() << "\n";
    }
    os << "```\n";
  }
}

static void emitDocs(const llvm::RecordKeeper &recordKeeper, raw_ostream &os) {
  os << "<!-- Autogenerated by mlir-tblgen; don't manually edit -->\n";
  auto passDefs = recordKeeper.getAllDerivedDefinitions("PassBase");

  // Collect the registered passes, sorted by argument name.
  SmallVector<Pass, 16> passes(passDefs.begin(), passDefs.end());
  SmallVector<Pass *, 16> sortedPasses(llvm::make_pointer_range(passes));
  llvm::array_pod_sort(sortedPasses.begin(), sortedPasses.end(),
                       [](Pass *const *lhs, Pass *const *rhs) {
                         return (*lhs)->getArgument().compare(
                             (*rhs)->getArgument());
                       });
  for (Pass *pass : sortedPasses)
    emitDoc(*pass, os);
}

static mlir::GenRegistration
    genRegister("gen-pass-doc", "Generate pass documentation",
                [](const llvm::RecordKeeper &records, raw_ostream &os) {
                  emitDocs(records, os);
                  return false;
                });
