brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 6b5acd2 Raw
151 lines · cpp
1//===- DDGPrinter.cpp - DOT printer for the data dependence graph ----------==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9//===----------------------------------------------------------------------===//10//11// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format12// in a file named `ddg.<graph-name>.dot` for each loop  in a function.13//===----------------------------------------------------------------------===//14 15#include "llvm/Analysis/DDGPrinter.h"16#include "llvm/Support/CommandLine.h"17#include "llvm/Support/GraphWriter.h"18 19using namespace llvm;20 21static cl::opt<bool> DotOnly("dot-ddg-only", cl::Hidden,22                             cl::desc("simple ddg dot graph"));23static cl::opt<std::string> DDGDotFilenamePrefix(24    "dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden,25    cl::desc("The prefix used for the DDG dot file names."));26 27static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);28 29//===--------------------------------------------------------------------===//30// Implementation of DDG DOT Printer for a loop31//===--------------------------------------------------------------------===//32PreservedAnalyses DDGDotPrinterPass::run(Loop &L, LoopAnalysisManager &AM,33                                         LoopStandardAnalysisResults &AR,34                                         LPMUpdater &U) {35  writeDDGToDotFile(*AM.getResult<DDGAnalysis>(L, AR), DotOnly);36  return PreservedAnalyses::all();37}38 39static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly) {40  std::string Filename =41      Twine(DDGDotFilenamePrefix + "." + G.getName() + ".dot").str();42  errs() << "Writing '" << Filename << "'...";43 44  std::error_code EC;45  raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);46 47  if (!EC)48    // We only provide the constant verson of the DOTGraphTrait specialization,49    // hence the conversion to const pointer50    WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);51  else52    errs() << "  error opening file for writing!";53  errs() << "\n";54}55 56//===--------------------------------------------------------------------===//57// DDG DOT Printer Implementation58//===--------------------------------------------------------------------===//59std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,60                                            const DataDependenceGraph *Graph) {61  if (isSimple())62    return getSimpleNodeLabel(Node, Graph);63  else64    return getVerboseNodeLabel(Node, Graph);65}66 67std::string DDGDotGraphTraits::getEdgeAttributes(68    const DDGNode *Node, GraphTraits<const DDGNode *>::ChildIteratorType I,69    const DataDependenceGraph *G) {70  const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());71  if (isSimple())72    return getSimpleEdgeAttributes(Node, E, G);73  else74    return getVerboseEdgeAttributes(Node, E, G);75}76 77bool DDGDotGraphTraits::isNodeHidden(const DDGNode *Node,78                                     const DataDependenceGraph *Graph) {79  if (isSimple() && isa<RootDDGNode>(Node))80    return true;81  assert(Graph && "expected a valid graph pointer");82  return Graph->getPiBlock(*Node) != nullptr;83}84 85std::string86DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,87                                      const DataDependenceGraph *G) {88  std::string Str;89  raw_string_ostream OS(Str);90  if (isa<SimpleDDGNode>(Node))91    for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())92      OS << *II << "\n";93  else if (isa<PiBlockDDGNode>(Node))94    OS << "pi-block\nwith\n"95       << cast<PiBlockDDGNode>(Node)->getNodes().size() << " nodes\n";96  else if (isa<RootDDGNode>(Node))97    OS << "root\n";98  else99    llvm_unreachable("Unimplemented type of node");100  return OS.str();101}102 103std::string104DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,105                                       const DataDependenceGraph *G) {106  std::string Str;107  raw_string_ostream OS(Str);108  OS << "<kind:" << Node->getKind() << ">\n";109  if (isa<SimpleDDGNode>(Node))110    for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())111      OS << *II << "\n";112  else if (isa<PiBlockDDGNode>(Node)) {113    OS << "--- start of nodes in pi-block ---\n";114    unsigned Count = 0;115    const auto &PNodes = cast<PiBlockDDGNode>(Node)->getNodes();116    for (auto *PN : PNodes) {117      OS << getVerboseNodeLabel(PN, G);118      if (++Count != PNodes.size())119        OS << "\n";120    }121    OS << "--- end of nodes in pi-block ---\n";122  } else if (isa<RootDDGNode>(Node))123    OS << "root\n";124  else125    llvm_unreachable("Unimplemented type of node");126  return OS.str();127}128 129std::string DDGDotGraphTraits::getSimpleEdgeAttributes(130    const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {131  std::string Str;132  raw_string_ostream OS(Str);133  DDGEdge::EdgeKind Kind = Edge->getKind();134  OS << "label=\"[" << Kind << "]\"";135  return OS.str();136}137 138std::string DDGDotGraphTraits::getVerboseEdgeAttributes(139    const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {140  std::string Str;141  raw_string_ostream OS(Str);142  DDGEdge::EdgeKind Kind = Edge->getKind();143  OS << "label=\"[";144  if (Kind == DDGEdge::EdgeKind::MemoryDependence)145    OS << G->getDependenceString(*Src, Edge->getTargetNode());146  else147    OS << Kind;148  OS << "]\"";149  return OS.str();150}151