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

39namespace DOT {

40

42

43

44

46

47}

48

60

63

64template <typename GraphType, typename Derived> class GraphWriterBase {

65protected:

67 const GraphType &G;

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\"><td align=\"text\" colspan=\"" << ColSpan

209 << "\">";

210 } else {

211 O << "\"{";

212 }

213

214 if (DTraits.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 (DTraits.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 (DTraits.isNodeHidden(*EI, G))

292 for (; EI != EE; ++EI)

293 if (DTraits.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