//===- GraphPrinter.cpp - Create a DOT output describing the Scop. --------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Create a DOT output describing the Scop.
//
// For each function a dot file is created that shows the control flow graph of
// the function and highlights the detected Scops.
//
//===----------------------------------------------------------------------===//

#include "polly/ScopGraphPrinter.h"
#include "polly/LinkAllPasses.h"
#include "polly/ScopDetection.h"
#include "llvm/Support/CommandLine.h"

using namespace polly;
using namespace llvm;
static cl::opt<std::string>
    ViewFilter("polly-view-only",
               cl::desc("Only view functions that match this pattern"),
               cl::Hidden, cl::init(""));

static cl::opt<bool> ViewAll("polly-view-all",
                             cl::desc("Also show functions without any scops"),
                             cl::Hidden, cl::init(false));

namespace llvm {

std::string DOTGraphTraits<ScopDetection *>::getEdgeAttributes(
    RegionNode *srcNode, GraphTraits<RegionInfo *>::ChildIteratorType CI,
    ScopDetection *SD) {
  RegionNode *destNode = *CI;

  if (srcNode->isSubRegion() || destNode->isSubRegion())
    return "";

  // In case of a backedge, do not use it to define the layout of the nodes.
  BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
  BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();

  RegionInfo *RI = SD->getRI();
  Region *R = RI->getRegionFor(destBB);

  while (R && R->getParent())
    if (R->getParent()->getEntry() == destBB)
      R = R->getParent();
    else
      break;

  if (R && R->getEntry() == destBB && R->contains(srcBB))
    return "constraint=false";

  return "";
}

std::string
DOTGraphTraits<ScopDetection *>::escapeString(llvm::StringRef String) {
  std::string Escaped;

  for (const auto &C : String) {
    if (C == '"')
      Escaped += '\\';

    Escaped += C;
  }
  return Escaped;
}

void DOTGraphTraits<ScopDetection *>::printRegionCluster(ScopDetection *SD,
                                                         const Region *R,
                                                         raw_ostream &O,
                                                         unsigned depth) {
  O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
                      << " {\n";
  unsigned LineBegin, LineEnd;
  std::string FileName;

  getDebugLocation(R, LineBegin, LineEnd, FileName);

  std::string Location;
  if (LineBegin != (unsigned)-1) {
    Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
                            std::to_string(LineEnd) + "\n");
  }

  std::string ErrorMessage = SD->regionIsInvalidBecause(R);
  ErrorMessage = escapeString(ErrorMessage);
  O.indent(2 * (depth + 1))
      << "label = \"" << Location << ErrorMessage << "\";\n";

  if (SD->isMaxRegionInScop(*R)) {
    O.indent(2 * (depth + 1)) << "style = filled;\n";

    // Set color to green.
    O.indent(2 * (depth + 1)) << "color = 3";
  } else {
    O.indent(2 * (depth + 1)) << "style = solid;\n";

    int color = (R->getDepth() * 2 % 12) + 1;

    // We do not want green again.
    if (color == 3)
      color = 6;

    O.indent(2 * (depth + 1)) << "color = " << color << "\n";
  }

  for (const auto &SubRegion : *R)
    printRegionCluster(SD, SubRegion.get(), O, depth + 1);

  RegionInfo *RI = R->getRegionInfo();

  for (BasicBlock *BB : R->blocks())
    if (RI->getRegionFor(BB) == R)
      O.indent(2 * (depth + 1))
          << "Node"
          << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
          << ";\n";

  O.indent(2 * depth) << "}\n";
}

void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
    ScopDetection *SD, GraphWriter<ScopDetection *> &GW) {
  raw_ostream &O = GW.getOStream();
  O << "\tcolorscheme = \"paired12\"\n";
  printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
}

} // namespace llvm

struct ScopDetectionAnalysisGraphTraits {
  static ScopDetection *getGraph(ScopDetectionWrapperPass *Analysis) {
    return &Analysis->getSD();
  }
};

struct ScopViewerWrapperPass
    : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
                                      ScopDetection *,
                                      ScopDetectionAnalysisGraphTraits> {
  static char ID;
  ScopViewerWrapperPass()
      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
                                        ScopDetection *,
                                        ScopDetectionAnalysisGraphTraits>(
            "scops", ID) {}
  bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
    if (ViewFilter != "" && !F.getName().count(ViewFilter))
      return false;

    if (ViewAll)
      return true;

    // Check that at least one scop was detected.
    return std::distance(SD.getSD().begin(), SD.getSD().end()) > 0;
  }
};
char ScopViewerWrapperPass::ID = 0;

struct ScopOnlyViewerWrapperPass
    : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
                                      ScopDetection *,
                                      ScopDetectionAnalysisGraphTraits> {
  static char ID;
  ScopOnlyViewerWrapperPass()
      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
                                        ScopDetection *,
                                        ScopDetectionAnalysisGraphTraits>(
            "scopsonly", ID) {}
};
char ScopOnlyViewerWrapperPass::ID = 0;

struct ScopPrinterWrapperPass
    : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
                                       ScopDetection *,
                                       ScopDetectionAnalysisGraphTraits> {
  static char ID;
  ScopPrinterWrapperPass()
      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
                                         ScopDetection *,
                                         ScopDetectionAnalysisGraphTraits>(
            "scops", ID) {}
};
char ScopPrinterWrapperPass::ID = 0;

struct ScopOnlyPrinterWrapperPass
    : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
                                       ScopDetection *,
                                       ScopDetectionAnalysisGraphTraits> {
  static char ID;
  ScopOnlyPrinterWrapperPass()
      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
                                         ScopDetection *,
                                         ScopDetectionAnalysisGraphTraits>(
            "scopsonly", ID) {}
};
char ScopOnlyPrinterWrapperPass::ID = 0;

static RegisterPass<ScopViewerWrapperPass> X("view-scops",
                                             "Polly - View Scops of function");

static RegisterPass<ScopOnlyViewerWrapperPass>
    Y("view-scops-only",
      "Polly - View Scops of function (with no function bodies)");

static RegisterPass<ScopPrinterWrapperPass>
    M("dot-scops", "Polly - Print Scops of function");

static RegisterPass<ScopOnlyPrinterWrapperPass>
    N("dot-scops-only",
      "Polly - Print Scops of function (with no function bodies)");

Pass *polly::createDOTViewerWrapperPass() {
  return new ScopViewerWrapperPass();
}

Pass *polly::createDOTOnlyViewerWrapperPass() {
  return new ScopOnlyViewerWrapperPass();
}

Pass *polly::createDOTPrinterWrapperPass() {
  return new ScopPrinterWrapperPass();
}

Pass *polly::createDOTOnlyPrinterWrapperPass() {
  return new ScopOnlyPrinterWrapperPass();
}

bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
  if (ViewFilter != "" && !F.getName().count(ViewFilter))
    return false;

  if (ViewAll)
    return true;

  // Check that at least one scop was detected.
  return std::distance(SD.begin(), SD.end()) > 0;
}
