22#ifndef LLVM_SUPPORT_GRAPHWRITER_H
23#define LLVM_SUPPORT_GRAPHWRITER_H
49namespace GraphProgram {
77 static_assert(std::is_pointer_v<NodeRef>,
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.");
83 Derived &
getDerived() {
return *
static_cast<Derived *
>(
this); }
85 return *
static_cast<const Derived *
>(
this);
93 bool hasEdgeSourceLabels =
false;
98 for (
unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
104 hasEdgeSourceLabels =
true;
107 O <<
"<td colspan=\"1\" port=\"s" << i <<
"\">" << label <<
"</td>";
116 if (EI != EE && hasEdgeSourceLabels) {
118 O <<
"<td colspan=\"1\" port=\"s64\">truncated...</td>";
120 O <<
"|<s64>truncated...";
123 return hasEdgeSourceLabels;
152 else if (!GraphName.empty())
155 O <<
"digraph unnamed {\n";
158 O <<
"\trankdir=\"BT\";\n";
162 else if (!GraphName.empty())
175 for (
const auto Node : nodes<GraphType>(
G))
185 O <<
"\tNode" <<
static_cast<const void *
>(
Node) <<
" [shape=";
191 if (!NodeAttributes.empty())
O << NodeAttributes <<
",";
197 unsigned ColSpan = 0;
200 for (; EI != EE && ColSpan != 64; ++EI, ++ColSpan)
207 O <<
"<<table border=\"0\" cellborder=\"1\" cellspacing=\"0\""
208 <<
" cellpadding=\"0\"><tr><td align=\"text\" colspan=\"" << ColSpan
226 if (!NodeDesc.empty())
230 std::string edgeSourceLabels;
234 if (hasEdgeSourceLabels) {
240 O << edgeSourceLabels;
242 O <<
"{" << edgeSourceLabels <<
"}";
261 if (!NodeDesc.empty())
269 for (; i != e && i != 64; ++i) {
271 O <<
"<d" << i <<
">"
276 O <<
"|<d64>truncated...";
281 O <<
"</tr></table>>";
289 for (
unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
292 for (; EI != EE; ++EI)
298 if (
NodeRef TargetNode = *EI) {
305 (
unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
306 DestPort =
static_cast<int>(
Offset);
313 static_cast<const void *
>(TargetNode), DestPort,
320 const std::string &Label,
unsigned NumEdgeSources = 0,
321 const std::vector<std::string> *EdgeSourceLabels =
nullptr) {
322 O <<
"\tNode" <<
ID <<
"[ ";
326 if (NumEdgeSources)
O <<
"{";
328 if (NumEdgeSources) {
331 for (
unsigned i = 0; i != NumEdgeSources; ++i) {
333 O <<
"<s" << i <<
">";
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 if (DestNodePort > 64) DestNodePort = 64;
348 O <<
"\tNode" << SrcNodeID;
349 if (SrcNodePort >= 0)
350 O <<
":s" << SrcNodePort;
351 O <<
" -> Node" << DestNodeID;
353 O <<
":d" << DestNodePort;
356 O <<
"[" << Attrs <<
"]";
367template <
typename GraphType>
375template <
typename GraphType>
377 bool ShortNames =
false,
const Twine &Title =
"") {
382 W.writeGraph(Title.str());
393template <
typename GraphType>
395 bool ShortNames =
false,
396 const Twine &Title =
"",
397 std::string Filename =
"") {
399 if (Filename.empty()) {
406 if (EC == std::errc::file_exists) {
407 errs() <<
"file exists, overwriting" <<
"\n";
409 errs() <<
"error writing into file" <<
"\n";
412 errs() <<
"writing to the newly created file " << Filename <<
"\n";
418 errs() <<
"error opening file '" << Filename <<
"' for writing!\n";
423 errs() <<
" done. \n";
429#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
430template <
typename GraphType>
433 const Twine &Title,
bool ShortNames =
false,
442template<
typename GraphType>
444 bool ShortNames =
false,
const Twine &Title =
"",
448 if (Filename.empty())
#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<X> 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)
typename GTraits::ChildIteratorType child_iterator
bool getEdgeSourceLabels(raw_ostream &O, NodeRef Node)
const Derived & getDerived() const
bool isNodeHidden(NodeRef Node)
void writeHeader(const std::string &Title)
typename GTraits::NodeRef NodeRef
void writeGraph(const std::string &Title="")
void writeNode(NodeRef Node)
GraphWriterBase(raw_ostream &o, const GraphType &g, bool SN)
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
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...
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
virtual ~GraphWriterBase()
typename GTraits::nodes_iterator node_iterator
DOTGraphTraits< GraphType > DOTTraits
GraphWriter(raw_ostream &o, const GraphType &g, bool SN)
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.
LLVM_ABI std::string EscapeString(const std::string &Label)
LLVM_ABI StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
@ 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.
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.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
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.
static std::string getNodeIdentifierLabel(const void *, const GraphType &)
static bool isNodeHidden(const void *, const GraphType &)
isNodeHidden - If the function returns true, the given node is not displayed in the graph.
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
static EdgeIter getEdgeTarget(const void *, EdgeIter I)
getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is called to determine which outgo...
static std::string getGraphProperties(const GraphType &)
getGraphProperties - Return any custom properties that should be included in the top level graph stru...
static std::string getEdgeAttributes(const void *, EdgeIter, const GraphType &)
If you want to override the dot attributes printed for a particular edge, override this method.
std::string getNodeLabel(const void *, const GraphType &)
getNodeLabel - Given a node and a pointer to the top level graph, return the label to print in the no...
static bool edgeTargetsEdgeSource(const void *, EdgeIter)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
static bool renderGraphFromBottomUp()
renderGraphFromBottomUp - If this function returns true, the graph is emitted bottom-up instead of to...
static std::string getEdgeDestLabel(const void *, unsigned)
getEdgeDestLabel - If hasEdgeDestLabels, this function returns the incoming edge label with the given...
static std::string getEdgeSourceLabel(const void *, EdgeIter)
getEdgeSourceLabel - If you want to label the edge source itself, implement this method.
static bool hasEdgeDestLabels()
hasEdgeDestLabels - If this function returns true, the graph is able to provide labels for edge desti...
static bool renderNodesUsingHTML()
static void addCustomGraphFeatures(const GraphType &, GraphWriter &)
addCustomGraphFeatures - If a graph is made up of more than just straight-forward nodes and edges,...
static std::string getNodeDescription(const void *, const GraphType &)
static std::string getNodeAttributes(const void *, const GraphType &)
If you want to specify custom node attributes, this is the place to do so.
static unsigned numEdgeDestLabels(const void *)
numEdgeDestLabels - If hasEdgeDestLabels, this function returns the number of incoming edge labels th...
typename GraphType::UnknownGraphTypeError NodeRef