LLVM: include/llvm/Support/GraphWriter.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef LLVM_SUPPORT_GRAPHWRITER_H
23#define LLVM_SUPPORT_GRAPHWRITER_H
24
32#include
33#include
34#include <type_traits>
35#include
36
37namespace llvm {
38
40
42
43
44
46
47}
48
60
63
64template <typename GraphType, typename Derived> class GraphWriterBase {
65protected:
69
76
77 static_assert(std::is_pointer_v,
78 "FIXME: Currently GraphWriterBase requires the NodeRef type to "
79 "be a pointer.\nThe pointer usage should be moved to "
80 "DOTGraphTraits, and removed from GraphWriterBase itself.");
81
82
83 Derived &getDerived() { return *static_cast<Derived *>(this); }
85 return *static_cast<const Derived *>(this);
86 }
87
88
89
93 bool hasEdgeSourceLabels = false;
94
96 O << "
97
98 for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
99 std::string label = DTraits.getEdgeSourceLabel(Node, EI);
100
101 if (label.empty())
102 continue;
103
104 hasEdgeSourceLabels = true;
105
107 O << "<td colspan=\"1\" port=\"s" << i << "\">" << label << "";
108 else {
109 if (i)
110 O << "|";
111
113 }
114 }
115
116 if (EI != EE && hasEdgeSourceLabels) {
118 O << "<td colspan=\"1\" port=\"s64\">truncated...";
119 else
120 O << "|truncated...";
121 }
122
123 return hasEdgeSourceLabels;
124 }
125
126public:
132
134
136
137
139
140
142
143
145 }
146
148 std::string GraphName(DTraits.getGraphName(G));
149
150 if (!Title.empty())
152 else if (!GraphName.empty())
154 else
155 O << "digraph unnamed {\n";
156
157 if (DTraits.renderGraphFromBottomUp())
158 O << "\trankdir=\"BT\";\n";
159
160 if (!Title.empty())
162 else if (!GraphName.empty())
164 O << DTraits.getGraphProperties(G);
165 O << "\n";
166 }
167
169
170 O << "}\n";
171 }
172
179
181
183 std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
184
185 O << "\tNode" << static_cast<const void *>(Node) << " [shape=";
187 O << "none,";
188 else
189 O << "record,";
190
191 if (!NodeAttributes.empty()) O << NodeAttributes << ",";
192 O << "label=";
193
195
196
197 unsigned ColSpan = 0;
200 for (; EI != EE && ColSpan != 64; ++EI, ++ColSpan)
201 ;
202 if (ColSpan == 0)
203 ColSpan = 1;
204
205 if (EI != EE)
206 ++ColSpan;
207 O << "<<table border=\"0\" cellborder=\"1\" cellspacing=\"0\""
208 << " cellpadding=\"0\">
209 << "\">";
210 } else {
211 O << "\"{";
212 }
213
214 if (.renderGraphFromBottomUp()) {
217 else
219
220
221 std::string Id = DTraits.getNodeIdentifierLabel(Node, G);
222 if (!Id.empty())
224
225 std::string NodeDesc = DTraits.getNodeDescription(Node, G);
226 if (!NodeDesc.empty())
228 }
229
230 std::string edgeSourceLabels;
233
234 if (hasEdgeSourceLabels) {
235 if (.renderGraphFromBottomUp())
237 O << "|";
238
240 O << edgeSourceLabels;
241 else
242 O << "{" << edgeSourceLabels << "}";
243
244 if (DTraits.renderGraphFromBottomUp())
246 O << "|";
247 }
248
249 if (DTraits.renderGraphFromBottomUp()) {
252 else
254
255
256 std::string Id = DTraits.getNodeIdentifierLabel(Node, G);
257 if (!Id.empty())
259
260 std::string NodeDesc = DTraits.getNodeDescription(Node, G);
261 if (!NodeDesc.empty())
263 }
264
265 if (DTraits.hasEdgeDestLabels()) {
266 O << "|{";
267
268 unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
269 for (; i != e && i != 64; ++i) {
270 if (i) O << "|";
271 O << "<d" << i << ">"
273 }
274
275 if (i != e)
276 O << "|truncated...";
277 O << "}";
278 }
279
281 O << ">";
282 else
283 O << "}\"";
284 O << "];\n";
285
286
289 for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
290 if (.isNodeHidden(*EI, G))
292 for (; EI != EE; ++EI)
293 if (.isNodeHidden(*EI, G))
295 }
296
298 if (NodeRef TargetNode = *EI) {
299 int DestPort = -1;
300 if (DTraits.edgeTargetsEdgeSource(Node, EI)) {
302
303
305 (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
306 DestPort = static_cast<int>(Offset);
307 }
308
309 if (DTraits.getEdgeSourceLabel(Node, EI).empty())
310 edgeidx = -1;
311
312 getDerived().emitEdge(static_cast<const void *>(Node), edgeidx,
313 static_cast<const void *>(TargetNode), DestPort,
315 }
316 }
317
318
320 const std::string &Label, unsigned NumEdgeSources = 0,
321 const std::vectorstd::string *EdgeSourceLabels = nullptr) {
322 O << "\tNode" << ID << "[ ";
323 if (!Attr.empty())
324 O << Attr << ",";
325 O << " label =\"";
326 if (NumEdgeSources) O << "{";
328 if (NumEdgeSources) {
329 O << "|{";
330
331 for (unsigned i = 0; i != NumEdgeSources; ++i) {
332 if (i) O << "|";
333 O << "<s" << i << ">";
334 if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]);
335 }
336 O << "}}";
337 }
338 O << "\"];\n";
339 }
340
341
342 void emitEdge(const void *SrcNodeID, int SrcNodePort,
343 const void *DestNodeID, int DestNodePort,
344 const std::string &Attrs) {
345 if (SrcNodePort > 64) return;
346 DestNodePort = std::min(DestNodePort, 64);
347
348 O << "\tNode" << SrcNodeID;
349 if (SrcNodePort >= 0)
350 O << ":s" << SrcNodePort;
351 O << " -> Node" << DestNodeID;
352 if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels())
353 O << ":d" << DestNodePort;
354
355 if (!Attrs.empty())
356 O << "[" << Attrs << "]";
357 O << ";\n";
358 }
359
360
361
365};
366
367template
374
375template
377 bool ShortNames = false, const Twine &Title = "") {
378
380
381
382 W.writeGraph(Title.str());
383
384 return O;
385}
386
388
389
390
391
392
393template
395 bool ShortNames = false,
396 const Twine &Title = "",
397 std::string Filename = "") {
398 int FD;
399 if (Filename.empty()) {
401 } else {
404
405
406 if (EC == std::errc::file_exists) {
407 errs() << "file exists, overwriting" << "\n";
408 } else if (EC) {
409 errs() << "error writing into file" << "\n";
410 return "";
411 } else {
412 errs() << "writing to the newly created file " << Filename << "\n";
413 }
414 }
416
417 if (FD == -1) {
418 errs() << "error opening file '" << Filename << "' for writing!\n";
419 return "";
420 }
421
423 errs() << " done. \n";
424
425 return Filename;
426}
427
428
429#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
430template
433 const Twine &Title, bool ShortNames = false,
434 const Twine &Name = "") {
436}
437#endif
438
439
440
441
442template
444 bool ShortNames = false, const Twine &Title = "",
446 std::string Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
447
448 if (Filename.empty())
449 return;
450
452}
453
454}
455
456#endif
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the little GraphTraits template class that should be specialized by classes that...
INLINE void g(uint32_t *state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y)
void writeEdge(NodeRef Node, unsigned edgeidx, child_iterator EI)
Definition GraphWriter.h:297
typename GTraits::ChildIteratorType child_iterator
Definition GraphWriter.h:74
bool getEdgeSourceLabels(raw_ostream &O, NodeRef Node)
Definition GraphWriter.h:90
DOTTraits DTraits
Definition GraphWriter.h:75
const Derived & getDerived() const
Definition GraphWriter.h:84
raw_ostream & O
Definition GraphWriter.h:66
bool isNodeHidden(NodeRef Node)
Definition GraphWriter.h:180
void writeHeader(const std::string &Title)
Definition GraphWriter.h:147
typename GTraits::NodeRef NodeRef
Definition GraphWriter.h:72
void writeGraph(const std::string &Title="")
Definition GraphWriter.h:133
void writeNode(NodeRef Node)
Definition GraphWriter.h:182
bool RenderUsingHTML
Definition GraphWriter.h:68
GraphWriterBase(raw_ostream &o, const GraphType &g, bool SN)
Definition GraphWriter.h:127
void writeNodes()
Definition GraphWriter.h:173
void emitSimpleNode(const void *ID, const std::string &Attr, const std::string &Label, unsigned NumEdgeSources=0, const std::vector< std::string > *EdgeSourceLabels=nullptr)
emitSimpleNode - Outputs a simple (non-record) node
Definition GraphWriter.h:319
void emitEdge(const void *SrcNodeID, int SrcNodePort, const void *DestNodeID, int DestNodePort, const std::string &Attrs)
emitEdge - Output an edge from a simple node into the graph...
Definition GraphWriter.h:342
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
Definition GraphWriter.h:362
Derived & getDerived()
Definition GraphWriter.h:83
const GraphType & G
Definition GraphWriter.h:67
virtual ~GraphWriterBase()=default
GraphTraits< GraphType > GTraits
Definition GraphWriter.h:71
typename GTraits::nodes_iterator node_iterator
Definition GraphWriter.h:73
void writeFooter()
Definition GraphWriter.h:168
DOTGraphTraits< GraphType > DOTTraits
Definition GraphWriter.h:70
Definition GraphWriter.h:368
GraphWriter(raw_ostream &o, const GraphType &g, bool SN)
Definition GraphWriter.h:370
~GraphWriter() override=default
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition GraphWriter.h:39
LLVM_ABI std::string EscapeString(const std::string &Label)
LLVM_ABI StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
Definition GraphWriter.h:49
Name
Definition GraphWriter.h:51
@ FDP
Definition GraphWriter.h:53
@ TWOPI
Definition GraphWriter.h:55
@ NEATO
Definition GraphWriter.h:54
@ DOT
Definition GraphWriter.h:52
@ CIRCO
Definition GraphWriter.h:56
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
@ CD_CreateAlways
CD_CreateAlways - When opening a file:
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< typename GraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
LLVM_ABI bool DisplayGraph(StringRef Filename, bool wait=true, GraphProgram::Name program=GraphProgram::DOT)
LLVM_DUMP_METHOD void dumpDotGraphToFile(const GraphType &G, const Twine &FileName, const Twine &Title, bool ShortNames=false, const Twine &Name="")
DumpDotGraph - Just dump a dot graph to the user-provided file name.
Definition GraphWriter.h:432
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition GraphWriter.h:376
LLVM_ABI std::string createGraphFilename(const Twine &Name, int &FD)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
Definition GraphWriter.h:443
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
static void addCustomGraphFeatures(const GraphType &, GraphWriter &)
addCustomGraphFeatures - If a graph is made up of more than just straight-forward nodes and edges,...
typename GraphType::UnknownGraphTypeError NodeRef