Path: blob/main/contrib/llvm-project/llvm/lib/Analysis/DDGPrinter.cpp
35233 views
//===- DDGPrinter.cpp - DOT printer for the data dependence graph ----------==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78//===----------------------------------------------------------------------===//9//10// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format11// in a file named `ddg.<graph-name>.dot` for each loop in a function.12//===----------------------------------------------------------------------===//1314#include "llvm/Analysis/DDGPrinter.h"15#include "llvm/Support/CommandLine.h"16#include "llvm/Support/GraphWriter.h"1718using namespace llvm;1920static cl::opt<bool> DotOnly("dot-ddg-only", cl::Hidden,21cl::desc("simple ddg dot graph"));22static cl::opt<std::string> DDGDotFilenamePrefix(23"dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden,24cl::desc("The prefix used for the DDG dot file names."));2526static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);2728//===--------------------------------------------------------------------===//29// Implementation of DDG DOT Printer for a loop30//===--------------------------------------------------------------------===//31PreservedAnalyses DDGDotPrinterPass::run(Loop &L, LoopAnalysisManager &AM,32LoopStandardAnalysisResults &AR,33LPMUpdater &U) {34writeDDGToDotFile(*AM.getResult<DDGAnalysis>(L, AR), DotOnly);35return PreservedAnalyses::all();36}3738static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly) {39std::string Filename =40Twine(DDGDotFilenamePrefix + "." + G.getName() + ".dot").str();41errs() << "Writing '" << Filename << "'...";4243std::error_code EC;44raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);4546if (!EC)47// We only provide the constant verson of the DOTGraphTrait specialization,48// hence the conversion to const pointer49WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);50else51errs() << " error opening file for writing!";52errs() << "\n";53}5455//===--------------------------------------------------------------------===//56// DDG DOT Printer Implementation57//===--------------------------------------------------------------------===//58std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,59const DataDependenceGraph *Graph) {60if (isSimple())61return getSimpleNodeLabel(Node, Graph);62else63return getVerboseNodeLabel(Node, Graph);64}6566std::string DDGDotGraphTraits::getEdgeAttributes(67const DDGNode *Node, GraphTraits<const DDGNode *>::ChildIteratorType I,68const DataDependenceGraph *G) {69const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());70if (isSimple())71return getSimpleEdgeAttributes(Node, E, G);72else73return getVerboseEdgeAttributes(Node, E, G);74}7576bool DDGDotGraphTraits::isNodeHidden(const DDGNode *Node,77const DataDependenceGraph *Graph) {78if (isSimple() && isa<RootDDGNode>(Node))79return true;80assert(Graph && "expected a valid graph pointer");81return Graph->getPiBlock(*Node) != nullptr;82}8384std::string85DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,86const DataDependenceGraph *G) {87std::string Str;88raw_string_ostream OS(Str);89if (isa<SimpleDDGNode>(Node))90for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())91OS << *II << "\n";92else if (isa<PiBlockDDGNode>(Node))93OS << "pi-block\nwith\n"94<< cast<PiBlockDDGNode>(Node)->getNodes().size() << " nodes\n";95else if (isa<RootDDGNode>(Node))96OS << "root\n";97else98llvm_unreachable("Unimplemented type of node");99return OS.str();100}101102std::string103DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,104const DataDependenceGraph *G) {105std::string Str;106raw_string_ostream OS(Str);107OS << "<kind:" << Node->getKind() << ">\n";108if (isa<SimpleDDGNode>(Node))109for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())110OS << *II << "\n";111else if (isa<PiBlockDDGNode>(Node)) {112OS << "--- start of nodes in pi-block ---\n";113unsigned Count = 0;114const auto &PNodes = cast<PiBlockDDGNode>(Node)->getNodes();115for (auto *PN : PNodes) {116OS << getVerboseNodeLabel(PN, G);117if (++Count != PNodes.size())118OS << "\n";119}120OS << "--- end of nodes in pi-block ---\n";121} else if (isa<RootDDGNode>(Node))122OS << "root\n";123else124llvm_unreachable("Unimplemented type of node");125return OS.str();126}127128std::string DDGDotGraphTraits::getSimpleEdgeAttributes(129const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {130std::string Str;131raw_string_ostream OS(Str);132DDGEdge::EdgeKind Kind = Edge->getKind();133OS << "label=\"[" << Kind << "]\"";134return OS.str();135}136137std::string DDGDotGraphTraits::getVerboseEdgeAttributes(138const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {139std::string Str;140raw_string_ostream OS(Str);141DDGEdge::EdgeKind Kind = Edge->getKind();142OS << "label=\"[";143if (Kind == DDGEdge::EdgeKind::MemoryDependence)144OS << G->getDependenceString(*Src, Edge->getTargetNode());145else146OS << Kind;147OS << "]\"";148return OS.str();149}150151152