LLVM 20.0.0git
DDGPrinter.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9//===----------------------------------------------------------------------===//
10//
11// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format
12// in a file named `ddg.<graph-name>.dot` for each loop in a function.
13//===----------------------------------------------------------------------===//
14
18
19using namespace llvm;
20
21static cl::opt<bool> DotOnly("dot-ddg-only", cl::Hidden,
22 cl::desc("simple ddg dot graph"));
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 loop
31//===--------------------------------------------------------------------===//
34 LPMUpdater &U) {
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 pointer
50 WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);
51 else
52 errs() << " error opening file for writing!";
53 errs() << "\n";
54}
55
56//===--------------------------------------------------------------------===//
57// DDG DOT Printer Implementation
58//===--------------------------------------------------------------------===//
60 const DataDependenceGraph *Graph) {
61 if (isSimple())
62 return getSimpleNodeLabel(Node, Graph);
63 else
64 return getVerboseNodeLabel(Node, Graph);
65}
66
69 const DataDependenceGraph *G) {
70 const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());
71 if (isSimple())
72 return getSimpleEdgeAttributes(Node, E, G);
73 else
74 return getVerboseEdgeAttributes(Node, E, G);
75}
76
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::string
86DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,
87 const DataDependenceGraph *G) {
88 std::string 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 else
99 llvm_unreachable("Unimplemented type of node");
100 return OS.str();
101}
102
103std::string
104DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,
105 const DataDependenceGraph *G) {
106 std::string 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 else
125 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;
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;
143 OS << "label=\"[";
145 OS << G->getDependenceString(*Src, Edge->getTargetNode());
146 else
147 OS << Kind;
148 OS << "]\"";
149 return OS.str();
150}
static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly=false)
Definition: DDGPrinter.cpp:39
static cl::opt< bool > DotOnly("dot-ddg-only", cl::Hidden, cl::desc("simple ddg dot graph"))
static cl::opt< std::string > DDGDotFilenamePrefix("dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden, cl::desc("The prefix used for the DDG dot file names."))
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Kind getKind() const
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
Analysis pass that builds the DDG for a loop.
Definition: DDG.h:414
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Definition: DDGPrinter.cpp:32
Data Dependency Graph Edge.
Definition: DDG.h:213
EdgeKind getKind() const
Get the edge kind.
Definition: DDG.h:237
EdgeKind
The kind of edge in the DDG.
Definition: DDG.h:216
Data Dependence Graph Node The graph can represent the following types of nodes:
Definition: DDG.h:44
const NodeType & getTargetNode() const
Retrieve the target node this edge connects to.
Definition: DirectedGraph.h:48
Data Dependency Graph.
Definition: DDG.h:306
const PiBlockDDGNode * getPiBlock(const NodeType &N) const
If node N belongs to a pi-block return a pointer to the pi-block, otherwise return null.
Definition: DDG.cpp:243
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:39
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
Subclass of DDGNode representing single or multi-instruction nodes.
Definition: DDG.h:108
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:460
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
Definition: FileSystem.h:758
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:359
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isNodeHidden(const DDGNode *Node, const DataDependenceGraph *G)
Do not print nodes that are part of a pi-block separately.
Definition: DDGPrinter.cpp:77
std::string getNodeLabel(const DDGNode *Node, const DataDependenceGraph *Graph)
Print a DDG node either in concise form (-ddg-dot-only) or verbose mode (-ddg-dot).
Definition: DDGPrinter.cpp:59
std::string getEdgeAttributes(const DDGNode *Node, GraphTraits< const DDGNode * >::ChildIteratorType I, const DataDependenceGraph *G)
Print attributes of an edge in the DDG graph.
Definition: DDGPrinter.cpp:67
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...