Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Analysis/DDGPrinter.cpp
35233 views
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
15
#include "llvm/Analysis/DDGPrinter.h"
16
#include "llvm/Support/CommandLine.h"
17
#include "llvm/Support/GraphWriter.h"
18
19
using namespace llvm;
20
21
static cl::opt<bool> DotOnly("dot-ddg-only", cl::Hidden,
22
cl::desc("simple ddg dot graph"));
23
static 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
27
static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);
28
29
//===--------------------------------------------------------------------===//
30
// Implementation of DDG DOT Printer for a loop
31
//===--------------------------------------------------------------------===//
32
PreservedAnalyses 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
39
static 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
//===--------------------------------------------------------------------===//
59
std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,
60
const DataDependenceGraph *Graph) {
61
if (isSimple())
62
return getSimpleNodeLabel(Node, Graph);
63
else
64
return getVerboseNodeLabel(Node, Graph);
65
}
66
67
std::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
else
74
return getVerboseEdgeAttributes(Node, E, G);
75
}
76
77
bool 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
85
std::string
86
DDGDotGraphTraits::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
else
99
llvm_unreachable("Unimplemented type of node");
100
return OS.str();
101
}
102
103
std::string
104
DDGDotGraphTraits::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
else
125
llvm_unreachable("Unimplemented type of node");
126
return OS.str();
127
}
128
129
std::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
138
std::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
else
147
OS << Kind;
148
OS << "]\"";
149
return OS.str();
150
}
151
152