23 #ifndef LLVM_SUPPORT_GRAPHWRITER_H
24 #define LLVM_SUPPORT_GRAPHWRITER_H
42 namespace GraphProgram {
55 template<
typename GraphType>
60 typedef DOTGraphTraits<GraphType> DOTTraits;
61 typedef GraphTraits<GraphType> GTraits;
63 typedef typename GTraits::nodes_iterator node_iterator;
64 typedef typename GTraits::ChildIteratorType child_iterator;
67 static_assert(std::is_pointer<NodeRef>::value,
68 "FIXME: Currently GraphWriter requires the NodeRef type to be "
69 "a pointer.\nThe pointer usage should be moved to "
70 "DOTGraphTraits, and removed from GraphWriter itself.");
74 bool getEdgeSourceLabels(raw_ostream &O, NodeRef Node) {
75 child_iterator EI = GTraits::child_begin(Node);
76 child_iterator EE = GTraits::child_end(Node);
77 bool hasEdgeSourceLabels =
false;
79 for (
unsigned i = 0; EI != EE &&
i != 64; ++EI, ++
i) {
85 hasEdgeSourceLabels =
true;
93 if (EI != EE && hasEdgeSourceLabels)
94 O <<
"|<s64>truncated...";
96 return hasEdgeSourceLabels;
123 else if (!GraphName.empty())
126 O <<
"digraph unnamed {\n";
129 O <<
"\trankdir=\"BT\";\n";
133 else if (!GraphName.empty())
146 for (node_iterator
I = GTraits::nodes_begin(G),
E = GTraits::nodes_end(G);
159 O <<
"\tNode" <<
static_cast<const void*
>(Node) <<
" [shape=record,";
160 if (!NodeAttributes.empty()) O << NodeAttributes <<
",";
172 if (!NodeDesc.empty())
176 std::string edgeSourceLabels;
178 bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
180 if (hasEdgeSourceLabels) {
183 O <<
"{" << EdgeSourceLabels.
str() <<
"}";
197 if (!NodeDesc.empty())
205 for (; i != e && i != 64; ++
i) {
207 O <<
"<d" << i <<
">"
212 O <<
"|<d64>truncated...";
219 child_iterator EI = GTraits::child_begin(Node);
220 child_iterator EE = GTraits::child_end(Node);
221 for (
unsigned i = 0; EI != EE &&
i != 64; ++EI, ++
i)
224 for (; EI != EE; ++EI)
229 void writeEdge(NodeRef Node,
unsigned edgeidx, child_iterator EI) {
230 if (NodeRef TargetNode = *EI) {
237 (
unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
238 DestPort =
static_cast<int>(
Offset);
244 emitEdge(static_cast<const void*>(Node), edgeidx,
245 static_cast<const void*>(TargetNode), DestPort,
252 const std::string &Label,
unsigned NumEdgeSources = 0,
253 const std::vector<std::string> *EdgeSourceLabels =
nullptr) {
254 O <<
"\tNode" << ID <<
"[ ";
258 if (NumEdgeSources) O <<
"{";
260 if (NumEdgeSources) {
263 for (
unsigned i = 0;
i != NumEdgeSources; ++
i) {
265 O <<
"<s" <<
i <<
">";
274 void emitEdge(
const void *SrcNodeID,
int SrcNodePort,
275 const void *DestNodeID,
int DestNodePort,
276 const std::string &Attrs) {
277 if (SrcNodePort > 64)
return;
278 if (DestNodePort > 64) DestNodePort = 64;
280 O <<
"\tNode" << SrcNodeID;
281 if (SrcNodePort >= 0)
282 O <<
":s" << SrcNodePort;
283 O <<
" -> Node" << DestNodeID;
285 O <<
":d" << DestNodePort;
288 O <<
"[" << Attrs <<
"]";
299 template<
typename GraphType>
301 bool ShortNames =
false,
302 const Twine &Title =
"") {
307 W.writeGraph(Title.str());
314 template <
typename GraphType>
316 bool ShortNames =
false,
const Twine &Title =
"") {
319 std::string
N = Name.
str();
320 N = N.substr(0, std::min<std::size_t>(N.size(), 140));
325 errs() <<
"error opening file '" << Filename <<
"' for writing!\n";
330 errs() <<
" done. \n";
338 template<
typename GraphType>
340 bool ShortNames =
false,
const Twine &Title =
"",
344 if (Filename.empty())
static std::string getNodeDescription(const void *, const GraphType &)
static EdgeIter getEdgeTarget(const void *, EdgeIter I)
getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is called to determine which outgo...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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 getNodeIdentifierLabel(const void *, const GraphType &)
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
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...
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
std::string str() const
Return the twine contents as a std::string.
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 unsigned numEdgeDestLabels(const void *)
numEdgeDestLabels - If hasEdgeDestLabels, this function returns the number of incoming edge labels th...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static bool edgeTargetsEdgeSource(const void *, EdgeIter)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
GraphWriter(raw_ostream &o, const GraphType &g, bool SN)
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...
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
GraphType::UnknownGraphTypeError NodeRef
std::string EscapeString(const std::string &Label)
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.
bool isNodeHidden(NodeRef Node)
void writeNode(NodeRef Node)
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
std::string createGraphFilename(const Twine &Name, int &FD)
static std::string getEdgeDestLabel(const void *, unsigned)
getEdgeDestLabel - If hasEdgeDestLabels, this function returns the incoming edge label with the given...
static std::string getGraphProperties(const GraphType &)
getGraphProperties - Return any custom properties that should be included in the top level graph stru...
void writeHeader(const std::string &Title)
StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
static std::string getNodeAttributes(const void *, const GraphType &)
If you want to specify custom node attributes, this is the place to do so.
static bool isNodeHidden(const void *)
isNodeHidden - If the function returns true, the given node is not displayed in the graph...
void writeEdge(NodeRef Node, unsigned edgeidx, child_iterator EI)
A raw_ostream that writes to a file descriptor.
bool DisplayGraph(StringRef Filename, bool wait=true, GraphProgram::Name program=GraphProgram::DOT)
A raw_ostream that writes to an std::string.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
void writeGraph(const std::string &Title="")
static bool renderGraphFromBottomUp()
renderGraphFromBottomUp - If this function returns true, the graph is emitted bottom-up instead of to...
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
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...