//===- 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;
using llvm::RecordKeeper;

/// Emit the documentation for the given pass.
static void emitDoc(const Pass &pass, raw_ostream &os) {
  os << llvm::formatv("\n### `-{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```\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```\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 RecordKeeper &records, raw_ostream &os) {
  os << "<!-- Autogenerated by mlir-tblgen; don't manually edit -->\n";
  auto passDefs = records.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 RecordKeeper &records, raw_ostream &os) {
                  emitDocs(records, os);
                  return false;
                });
