//===- ViewFunctionGraph.cpp - View/write graphviz graphs -----------------===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================

#include "mlir/Transforms/ViewFunctionGraph.h"
#include "mlir/IR/FunctionGraphTraits.h"
#include "mlir/Pass/Pass.h"

using namespace mlir;

namespace llvm {

// Specialize DOTGraphTraits to produce more readable output.
template <>
struct llvm::DOTGraphTraits<Function *> : public DefaultDOTGraphTraits {
  using DefaultDOTGraphTraits::DefaultDOTGraphTraits;

  static std::string getNodeLabel(Block *Block, Function *);
};

std::string llvm::DOTGraphTraits<Function *>::getNodeLabel(Block *Block,
                                                           Function *) {
  // Reuse the print output for the node labels.
  std::string outStreamStr;
  raw_string_ostream os(outStreamStr);
  Block->print(os);
  std::string &outStr = os.str();

  if (outStr[0] == '\n')
    outStr.erase(outStr.begin());

  // Process string output to left justify the block.
  for (unsigned i = 0; i != outStr.length(); ++i) {
    if (outStr[i] == '\n') {
      outStr[i] = '\\';
      outStr.insert(outStr.begin() + i + 1, 'l');
    }
  }

  return outStr;
}

} // end namespace llvm

void mlir::viewGraph(Function &function, const llvm::Twine &name,
                     bool shortNames, const llvm::Twine &title,
                     llvm::GraphProgram::Name program) {
  llvm::ViewGraph(&function, name, shortNames, title, program);
}

llvm::raw_ostream &mlir::writeGraph(llvm::raw_ostream &os, Function *function,
                                    bool shortNames, const llvm::Twine &title) {
  return llvm::WriteGraph(os, function, shortNames, title);
}

void mlir::Function::viewGraph() {
  ::mlir::viewGraph(*this, llvm::Twine("cfgfunc ") + getName().str());
}

namespace {
struct PrintCFGPass : public FunctionPass<PrintCFGPass> {
  PrintCFGPass(llvm::raw_ostream &os = llvm::errs(), bool shortNames = false,
               const llvm::Twine &title = "")
      : os(os), shortNames(shortNames), title(title) {}
  void runOnFunction() {
    mlir::writeGraph(os, getFunction(), shortNames, title);
  }

private:
  llvm::raw_ostream &os;
  bool shortNames;
  const llvm::Twine &title;
};
} // namespace

FunctionPassBase *mlir::createPrintCFGGraphPass(llvm::raw_ostream &os,
                                                bool shortNames,
                                                const llvm::Twine &title) {
  return new PrintCFGPass(os, shortNames, title);
}

static PassRegistration<PrintCFGPass> pass("print-cfg-graph",
                                           "Print CFG graph per function");
