//===- ViewOpGraph.cpp - View/write op graphviz graphs --------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "mlir/Transforms/ViewOpGraph.h"

#include "mlir/IR/AsmState.h"
#include "mlir/IR/Block.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/IndentedOstream.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/GraphWriter.h"
#include <map>
#include <optional>
#include <utility>

namespace mlir {
#define GEN_PASS_DEF_VIEWOPGRAPHPASS
#include "mlir/Transforms/Passes.h.inc"
} // namespace mlir

using namespace mlir;

static const StringRef kLineStyleControlFlow = "dashed";
static const StringRef kLineStyleDataFlow = "solid";
static const StringRef kShapeNode = "Mrecord";
static const StringRef kShapeNone = "plain";

/// Return the size limits for eliding large attributes.
static int64_t getLargeAttributeSizeLimit() {
  // Use the default from the printer flags if possible.
  if (std::optional<int64_t> limit =
          OpPrintingFlags().getLargeElementsAttrLimit())
    return *limit;
  return 16;
}

/// Return all values printed onto a stream as a string.
static std::string strFromOs(function_ref<void(raw_ostream &)> func) {
  std::string buf;
  llvm::raw_string_ostream os(buf);
  func(os);
  return buf;
}

/// Put quotation marks around a given string.
static std::string quoteString(const std::string &str) {
  return "\"" + str + "\"";
}

/// For Graphviz record nodes:
/// " Braces, vertical bars and angle brackets must be escaped with a backslash
/// character if you wish them to appear as a literal character "
static std::string escapeLabelString(const std::string &str) {
  std::string buf;
  llvm::raw_string_ostream os(buf);
  for (char c : str) {
    if (llvm::is_contained({'{', '|', '<', '}', '>', '\n', '"'}, c))
      os << '\\';
    os << c;
  }
  return buf;
}

using AttributeMap = std::map<std::string, std::string>;

namespace {
/// This struct represents a node in the DOT language. Each node has an
/// identifier and an optional identifier for the cluster (subgraph) that
/// contains the node.
/// Note: In the DOT language, edges can be drawn only from nodes to nodes, but
/// not between clusters. However, edges can be clipped to the boundary of a
/// cluster with `lhead` and `ltail` attributes. Therefore, when creating a new
/// cluster, an invisible "anchor" node is created.
struct Node {
public:
  Node(int id = 0, std::optional<int> clusterId = std::nullopt)
      : id(id), clusterId(clusterId) {}

  int id;
  std::optional<int> clusterId;
};

struct DataFlowEdge {
  Value value;
  Node node;
  std::string port;
};

/// Printer options for Graphviz visualization of an MLIR operation.
struct OpGraphPrinterOptions {
  /// Limit attribute/type length to number of chars.
  unsigned maxLabelLen = 20;
  /// Print attributes of operations.
  bool printAttrs = true;
  /// Print control flow edges.
  bool printControlFlowEdges = false;
  /// Print data flow edges.
  bool printDataFlowEdges = true;
  /// Print result types of operations.
  bool printResultTypes = true;

  /// Default options for printing a CFG region.
  static OpGraphPrinterOptions cfgRegionDefaults() {
    OpGraphPrinterOptions options;
    options.printControlFlowEdges = true;
    options.printDataFlowEdges = false;
    return options;
  }
};

/// Printer to emit a Graphviz dataflow visualization of an MLIR operation.
/// Note: See https://www.graphviz.org/doc/info/lang.html for more information
/// about the Graphviz DOT language.
class OpGraphPrinter {
public:
  OpGraphPrinter(const OpGraphPrinterOptions &options, raw_ostream &os,
                 Operation *asmStateOp,
                 const OpPrintingFlags &opPrintingFlags = OpPrintingFlags())
      : opts(options), os(os), asmState(asmStateOp, opPrintingFlags) {}

  void emitOperationGraph(Operation &op) {
    initColorMapping(op);
    emitGraph([&]() {
      processOperation(&op);
      emitAllEdgeStmts();
    });
  }

  void emitRegionCFGGraph(Region &region) {
    initColorMapping(region);
    emitGraph([&]() { processRegion(region); });
  }

private:
  /// Generate a color mapping that will color every operation with the same
  /// name the same way. It'll interpolate the hue in the HSV color-space,
  /// using muted colors that provide good contrast for black text.
  template <typename T>
  void initColorMapping(T &irEntity) {
    backgroundColors.clear();
    SmallVector<Operation *> ops;
    irEntity.walk([&](Operation *op) {
      auto &entry = backgroundColors[op->getName()];
      if (entry.first == 0)
        ops.push_back(op);
      ++entry.first;
    });
    for (auto indexedOps : llvm::enumerate(ops)) {
      double hue = ((double)indexedOps.index()) / ops.size();
      // Use lower saturation (0.3) and higher value (0.95) for better
      // readability
      backgroundColors[indexedOps.value()->getName()].second =
          std::to_string(hue) + " 0.3 0.95";
    }
  }

  /// Emit all edges. This function should be called after all nodes have been
  /// emitted.
  void emitAllEdgeStmts() {
    if (opts.printDataFlowEdges) {
      for (const auto &e : dataFlowEdges) {
        emitEdgeStmt(valueToNode[e.value], e.node, e.port, kLineStyleDataFlow);
      }
    }

    for (const std::string &edge : edges)
      os << edge << ";\n";
    edges.clear();
  }

  /// Emit a cluster (subgraph). The specified builder generates the body of the
  /// cluster. Return the anchor node of the cluster.
  Node emitClusterStmt(function_ref<void()> builder,
                       const std::string &label = "") {
    int clusterId = ++counter;
    os << "subgraph cluster_" << clusterId << " {\n";
    os.indent();
    // Emit invisible anchor node from/to which arrows can be drawn.
    Node anchorNode = emitNodeStmt(" ", kShapeNone);
    os << attrStmt("label", quoteString(label)) << ";\n";
    builder();
    os.unindent();
    os << "}\n";
    return Node(anchorNode.id, clusterId);
  }

  /// Generate an attribute statement.
  std::string attrStmt(const Twine &key, const Twine &value) {
    return (key + " = " + value).str();
  }

  /// Emit an attribute list.
  void emitAttrList(raw_ostream &os, const AttributeMap &map) {
    os << "[";
    interleaveComma(map, os, [&](const auto &it) {
      os << this->attrStmt(it.first, it.second);
    });
    os << "]";
  }

  // Print an MLIR attribute to `os`. Large attributes are truncated.
  void emitMlirAttr(raw_ostream &os, Attribute attr) {
    // A value used to elide large container attribute.
    int64_t largeAttrLimit = getLargeAttributeSizeLimit();

    // Always emit splat attributes.
    if (isa<SplatElementsAttr>(attr)) {
      os << escapeLabelString(
          strFromOs([&](raw_ostream &os) { attr.print(os); }));
      return;
    }

    // Elide "big" elements attributes.
    auto elements = dyn_cast<ElementsAttr>(attr);
    if (elements && elements.getNumElements() > largeAttrLimit) {
      os << std::string(elements.getShapedType().getRank(), '[') << "..."
         << std::string(elements.getShapedType().getRank(), ']') << " : ";
      emitMlirType(os, elements.getType());
      return;
    }

    auto array = dyn_cast<ArrayAttr>(attr);
    if (array && static_cast<int64_t>(array.size()) > largeAttrLimit) {
      os << "[...]";
      return;
    }

    // Print all other attributes.
    std::string buf;
    llvm::raw_string_ostream ss(buf);
    attr.print(ss);
    os << escapeLabelString(truncateString(buf));
  }

  // Print a truncated and escaped MLIR type to `os`.
  void emitMlirType(raw_ostream &os, Type type) {
    std::string buf;
    llvm::raw_string_ostream ss(buf);
    type.print(ss);
    os << escapeLabelString(truncateString(buf));
  }

  // Print a truncated and escaped MLIR operand to `os`.
  void emitMlirOperand(raw_ostream &os, Value operand) {
    operand.printAsOperand(os, asmState);
  }

  /// Append an edge to the list of edges.
  /// Note: Edges are written to the output stream via `emitAllEdgeStmts`.
  void emitEdgeStmt(Node n1, Node n2, std::string port, StringRef style) {
    AttributeMap attrs;
    attrs["style"] = style.str();
    // Use `ltail` and `lhead` to draw edges between clusters.
    if (n1.clusterId)
      attrs["ltail"] = "cluster_" + std::to_string(*n1.clusterId);
    if (n2.clusterId)
      attrs["lhead"] = "cluster_" + std::to_string(*n2.clusterId);

    edges.push_back(strFromOs([&](raw_ostream &os) {
      os << "v" << n1.id;
      if (!port.empty() && !n1.clusterId)
        // Attach edge to south compass point of the result
        os << ":res" << port << ":s";
      os << " -> ";
      os << "v" << n2.id;
      if (!port.empty() && !n2.clusterId)
        // Attach edge to north compass point of the operand
        os << ":arg" << port << ":n";
      emitAttrList(os, attrs);
    }));
  }

  /// Emit a graph. The specified builder generates the body of the graph.
  void emitGraph(function_ref<void()> builder) {
    os << "digraph G {\n";
    os.indent();
    // Edges between clusters are allowed only in compound mode.
    os << attrStmt("compound", "true") << ";\n";
    builder();
    os.unindent();
    os << "}\n";
  }

  /// Emit a node statement.
  Node emitNodeStmt(const std::string &label, StringRef shape = kShapeNode,
                    StringRef background = "") {
    int nodeId = ++counter;
    AttributeMap attrs;
    attrs["label"] = quoteString(label);
    attrs["shape"] = shape.str();
    if (!background.empty()) {
      attrs["style"] = "filled";
      attrs["fillcolor"] = quoteString(background.str());
    }
    os << llvm::format("v%i ", nodeId);
    emitAttrList(os, attrs);
    os << ";\n";
    return Node(nodeId);
  }

  std::string getValuePortName(Value operand) {
    // Print value as an operand and omit the leading '%' character.
    auto str = strFromOs(
        [&](raw_ostream &os) { operand.printAsOperand(os, asmState); });
    // Replace % and # with _
    llvm::replace(str, '%', '_');
    llvm::replace(str, '#', '_');
    return str;
  }

  std::string getClusterLabel(Operation *op) {
    return strFromOs([&](raw_ostream &os) {
      // Print operation name and type.
      os << op->getName();
      if (opts.printResultTypes) {
        os << " : (";
        std::string buf;
        llvm::raw_string_ostream ss(buf);
        interleaveComma(op->getResultTypes(), ss);
        os << truncateString(buf) << ")";
      }

      // Print attributes.
      if (opts.printAttrs) {
        os << "\\l";
        NamedAttrList attrs(op->getDiscardableAttrDictionary());
        op->getName().walkInherentAttrs(
            op,
            [&](StringRef name, Attribute &attr) { attrs.append(name, attr); });
        for (const NamedAttribute &attr : attrs) {
          os << escapeLabelString(attr.getName().getValue().str()) << ": ";
          emitMlirAttr(os, attr.getValue());
          os << "\\l";
        }
      }
    });
  }

  /// Generate a label for an operation.
  std::string getRecordLabel(Operation *op) {
    return strFromOs([&](raw_ostream &os) {
      os << "{";

      // Print operation inputs.
      if (op->getNumOperands() > 0) {
        os << "{";
        auto operandToPort = [&](Value operand) {
          os << "<arg" << getValuePortName(operand) << "> ";
          emitMlirOperand(os, operand);
        };
        interleave(op->getOperands(), os, operandToPort, "|");
        os << "}|";
      }
      // Print operation name and type.
      os << op->getName() << "\\l";

      // Print attributes.
      if (opts.printAttrs) {
        NamedAttrList attrs(op->getDiscardableAttrDictionary());
        op->getName().walkInherentAttrs(
            op,
            [&](StringRef name, Attribute &attr) { attrs.append(name, attr); });
        if (!attrs.empty()) {
          // Extra line break to separate attributes from the operation name.
          os << "\\l";
          for (const NamedAttribute &attr : attrs) {
            os << attr.getName().getValue() << ": ";
            emitMlirAttr(os, attr.getValue());
            os << "\\l";
          }
        }
      }

      if (op->getNumResults() > 0) {
        os << "|{";
        auto resultToPort = [&](Value result) {
          os << "<res" << getValuePortName(result) << "> ";
          emitMlirOperand(os, result);
          if (opts.printResultTypes) {
            os << " ";
            emitMlirType(os, result.getType());
          }
        };
        interleave(op->getResults(), os, resultToPort, "|");
        os << "}";
      }

      os << "}";
    });
  }

  /// Generate a label for a block argument.
  std::string getLabel(BlockArgument arg) {
    return strFromOs([&](raw_ostream &os) {
      os << "<res" << getValuePortName(arg) << "> ";
      arg.printAsOperand(os, asmState);
      if (opts.printResultTypes) {
        os << " ";
        emitMlirType(os, arg.getType());
      }
    });
  }

  /// Process a block. Emit a cluster and one node per block argument and
  /// operation inside the cluster.
  void processBlock(Block &block) {
    emitClusterStmt([&]() {
      for (BlockArgument &blockArg : block.getArguments())
        valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
      // Emit a node for each operation.
      std::optional<Node> prevNode;
      for (Operation &op : block) {
        Node nextNode = processOperation(&op);
        if (opts.printControlFlowEdges && prevNode)
          emitEdgeStmt(*prevNode, nextNode, /*port=*/"", kLineStyleControlFlow);
        prevNode = nextNode;
      }
    });
  }

  /// Process an operation. If the operation has regions, emit a cluster.
  /// Otherwise, emit a node.
  Node processOperation(Operation *op) {
    Node node;
    if (op->getNumRegions() > 0) {
      // Emit cluster for op with regions.
      node = emitClusterStmt(
          [&]() {
            for (Region &region : op->getRegions())
              processRegion(region);
          },
          getClusterLabel(op));
    } else {
      node = emitNodeStmt(getRecordLabel(op), kShapeNode,
                          backgroundColors[op->getName()].second);
    }

    // Insert data flow edges originating from each operand.
    if (opts.printDataFlowEdges) {
      unsigned numOperands = op->getNumOperands();
      for (unsigned i = 0; i < numOperands; i++) {
        auto operand = op->getOperand(i);
        dataFlowEdges.push_back({operand, node, getValuePortName(operand)});
      }
    }

    for (Value result : op->getResults())
      valueToNode[result] = node;

    return node;
  }

  /// Process a region.
  void processRegion(Region &region) {
    for (Block &block : region.getBlocks())
      processBlock(block);
  }

  /// Truncate long strings.
  std::string truncateString(std::string str) {
    if (str.length() <= opts.maxLabelLen)
      return str;
    return str.substr(0, opts.maxLabelLen) + "...";
  }

  /// Printing configuration.
  OpGraphPrinterOptions opts;
  /// Output stream to write DOT file to.
  raw_indented_ostream os;
  /// Re-usable assembly printer state for efficient printing.
  AsmState asmState;
  /// A list of edges. For simplicity, should be emitted after all nodes were
  /// emitted.
  std::vector<std::string> edges;
  /// Mapping of SSA values to Graphviz nodes/clusters.
  DenseMap<Value, Node> valueToNode;
  /// Output for data flow edges is delayed until the end to handle cycles
  std::vector<DataFlowEdge> dataFlowEdges;
  /// Counter for generating unique node/subgraph identifiers.
  int counter = 0;

  DenseMap<OperationName, std::pair<int, std::string>> backgroundColors;
};

/// This pass generates a Graphviz dataflow visualization of an MLIR operation.
/// Note: See https://www.graphviz.org/doc/info/lang.html for more information
/// about the Graphviz DOT language.
class PrintOpPass : public impl::ViewOpGraphPassBase<PrintOpPass> {
public:
  PrintOpPass() : os(&llvm::errs()) {}
  explicit PrintOpPass(ViewOpGraphPassOptions options)
      : impl::ViewOpGraphPassBase<PrintOpPass>(std::move(options)),
        os(&llvm::errs()) {}
  PrintOpPass(raw_ostream &os) : os(&os) {}
  PrintOpPass(const PrintOpPass &other)
      : impl::ViewOpGraphPassBase<PrintOpPass>(other), os(other.os) {}

  void runOnOperation() override {
    OpGraphPrinterOptions opts;
    opts.maxLabelLen = maxLabelLen;
    opts.printAttrs = printAttrs;
    opts.printControlFlowEdges = printControlFlowEdges;
    opts.printDataFlowEdges = printDataFlowEdges;
    opts.printResultTypes = printResultTypes;
    OpGraphPrinter printer(opts, *os, getOperation(), OpPrintingFlags());
    printer.emitOperationGraph(*getOperation());
    markAllAnalysesPreserved();
  }

private:
  raw_ostream *os;
};
} // namespace

std::unique_ptr<Pass> mlir::createViewOpGraphPass(raw_ostream &os) {
  return std::make_unique<PrintOpPass>(os);
}

/// Generate a CFG for a region and show it in a window.
static void llvmViewGraph(Region &region, const Twine &name) {
  int fd;
  std::string filename = llvm::createGraphFilename(name.str(), fd);
  {
    llvm::raw_fd_ostream os(fd, /*shouldClose=*/true);
    if (fd == -1) {
      llvm::errs() << "error opening file '" << filename << "' for writing\n";
      return;
    }
    OpGraphPrinter printer(OpGraphPrinterOptions::cfgRegionDefaults(), os,
                           region.getParentOp());
    printer.emitRegionCFGGraph(region);
  }
  llvm::DisplayGraph(filename, /*wait=*/false, llvm::GraphProgram::DOT);
}

void mlir::Region::viewGraph(const Twine &regionName) {
  llvmViewGraph(*this, regionName);
}

void mlir::Region::viewGraph() { viewGraph("region"); }
