//===- 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}`: {1}\n", pass.getArgument(),
                      pass.getSummary());
  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;
                });
