44 static inline std::string
47 std::stringstream stream;
66 if (
auto simpleNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*output))
81 auto f = map.find(elem);
93 auto f = map.find(elem);
108 if (
auto simpleNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*input))
124 +
" [shape=plaintext label=<\n"
125 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
127 " <TD PORT=\"default\" BORDER=\"1\" CELLPADDING=\"1\"><FONT "
144 return PortToDot(display_name, dot_name, color);
152 return PortToDot(display_name, dot_name, color);
160 return PortToDot(display_name, dot_name, color);
168 return PortToDot(display_name, dot_name, color);
175 std::unordered_map<rvsdg::Output *, ViewColors> & tailLabel,
176 bool back_edge =
false)
178 auto color =
"black";
183 +
" [style=\"\", arrowhead=\"normal\", color=" + color
184 +
", headlabel=<>, fontsize=15, labelangle=45, labeldistance=2.0, labelfontcolor=blue, "
190 +
" [style=\"\", arrowhead=\"normal\", color=" + color
191 +
", headlabel=<>, fontsize=15, labelangle=45, labeldistance=2.0, labelfontcolor=blue, "
192 "constraint=false, tooltip=\""
200 auto color =
"black";
202 +
" [style=\"\", arrowhead=\"normal\", color=" + color
203 +
", headlabel=<>, fontsize=10, labelangle=45, labeldistance=2.0, labelfontcolor=black, "
205 + output->
Type()->debug_string() +
"\"];\n";
211 if ((
'A' <= c && c <=
'Z') || (
'a' <= c && c <=
'z') || (
'0' <= c && c <=
'9') ||
'_' == c)
221 std::unordered_map<rvsdg::Output *, ViewColors> & outputColor,
222 std::unordered_map<rvsdg::Input *, ViewColors> & inputColor,
223 std::unordered_map<rvsdg::Output *, ViewColors> & tailLabel)
226 std::ostringstream dot;
227 dot <<
"subgraph cluster_sn" <<
hex((intptr_t)structuralNode) <<
" {\n";
228 dot <<
"color=\"#ff8080\"\n";
229 dot <<
"penwidth=6\n";
230 dot <<
"label=\"" << structuralNode->
DebugString() <<
"\"\n";
231 dot <<
"labeljust=l\n";
234 for (
size_t i = 0; i < structuralNode->
ninputs(); ++i)
237 structuralNode->
input(i),
238 GetDefaultColor<rvsdg::Input>(inputColor, structuralNode->
input(i)));
241 for (
size_t i = 0; i < structuralNode->
nsubregions(); ++i)
246 for (
size_t i = 0; i < structuralNode->
ninputs(); ++i)
255 for (
size_t i = 0; i < structuralNode->
noutputs(); ++i)
258 structuralNode->
output(i),
259 GetDefaultColor<rvsdg::Output>(outputColor, structuralNode->
output(i)));
274 std::unordered_map<rvsdg::Output *, ViewColors> & outputColor,
275 std::unordered_map<rvsdg::Input *, ViewColors> & inputColor)
277 auto SPACER =
" <TD WIDTH=\"10\"></TD>\n";
282 std::ostringstream inputs;
284 for (
size_t i = 0; i < simpleNode->
ninputs(); ++i)
286 auto color = GetDefaultColor<rvsdg::Input>(inputColor, simpleNode->
input(i));
291 inputs <<
" <TD PORT=\"i" <<
hex((intptr_t)simpleNode->
input(i))
292 <<
"\" BORDER=\"1\" CELLPADDING=\"1\" COLOR=\"" << color
293 <<
"\"><FONT POINT-SIZE=\"10\" COLOR=\"" << color <<
"\"> i" << i <<
"</FONT></TD>\n";
298 for (
size_t i = 0; i < simpleNode->
noutputs(); ++i)
300 auto color = GetDefaultColor<rvsdg::Output>(outputColor, simpleNode->
output(i));
306 <<
"\" BORDER=\"1\" CELLPADDING=\"1\" COLOR=\"" << color
307 <<
"\"><FONT POINT-SIZE=\"10\" COLOR=\"" << color <<
"\"> o" << i <<
"</FONT></TD>\n";
310 std::string color =
"black";
313 +
" [shape=plaintext label=<\n"
314 "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
317 " <TD BORDER=\"0\">\n"
318 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
320 " <TD WIDTH=\"20\"></TD>\n"
322 +
" <TD WIDTH=\"20\"></TD>\n"
328 " <TD BORDER=\"3\" STYLE=\"ROUNDED\" CELLPADDING=\"4\">"
329 + opname +
"<BR/><FONT POINT-SIZE=\"10\">" + name
333 " <TD BORDER=\"0\">\n"
334 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
336 " <TD WIDTH=\"20\"></TD>\n"
338 +
" <TD WIDTH=\"20\"></TD>\n"
345 + color +
" color=" + color +
"];\n";
352 std::unordered_map<rvsdg::Output *, ViewColors> & outputColor,
353 std::unordered_map<rvsdg::Input *, ViewColors> & inputColor,
354 std::unordered_map<rvsdg::Output *, ViewColors> & tailLabel)
356 std::ostringstream dot;
357 dot <<
"subgraph cluster_reg" <<
hex((intptr_t)region) <<
" {\n";
358 dot <<
"color=\"#80b3ff\"\n";
359 dot <<
"penwidth=6\n";
360 dot <<
"label=\"" << region->
index() <<
" - " <<
hex((intptr_t)region) <<
"\"\n";
363 dot <<
"{rank=source; ";
364 for (
size_t i = 0; i < region->
narguments(); ++i)
368 GetDefaultColor<rvsdg::Output>(outputColor, region->
argument(i)));
386 for (
size_t i = 0; i < node->ninputs(); ++i)
388 dot <<
Edge(node->input(i)->origin(), node->input(i), tailLabel);
393 dot <<
"{rank=sink; ";
394 for (
size_t i = 0; i < region->
nresults(); ++i)
398 GetDefaultColor<rvsdg::Input>(inputColor, region->
result(i)));
401 for (
size_t i = 0; i < region->
nresults(); ++i)
406 dot <<
Edge(be->argument(), be, tailLabel,
true);
410 && rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*region->
result(i)->
output()))
412 auto theta = rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*region->
result(i)->
output());
413 auto loopvar = theta->MapOutputLoopVar(*region->
result(i)->
output());
414 dot <<
Edge(loopvar.pre, loopvar.post, tailLabel,
true);
426 std::unordered_map<rvsdg::Output *, ViewColors> & outputColor,
427 std::unordered_map<rvsdg::Input *, ViewColors> & inputColor,
428 std::unordered_map<rvsdg::Output *, ViewColors> & tailLabel)
430 std::ostringstream dot;
431 dot <<
"digraph G {\n";
432 dot <<
RegionToDot(region, outputColor, inputColor, tailLabel);
441 std::unordered_map<rvsdg::Output *, ViewColors> & outputColor,
442 std::unordered_map<rvsdg::Input *, ViewColors> & inputColor,
443 std::unordered_map<rvsdg::Output *, ViewColors> & tailLabel)
445 fputs(
ToDot(region, outputColor, inputColor, tailLabel).c_str(), out);
452 std::unordered_map<rvsdg::Output *, ViewColors> outputColor;
453 std::unordered_map<rvsdg::Input *, ViewColors> inputColor;
454 std::unordered_map<rvsdg::Output *, ViewColors> tailLabel;
455 ViewDot(region, out, outputColor, inputColor, tailLabel);
467 const std::string & file_name,
468 std::unordered_map<rvsdg::Output *, ViewColors> outputColor,
469 std::unordered_map<rvsdg::Input *, ViewColors> inputColor,
470 std::unordered_map<rvsdg::Output *, ViewColors> tailLabel)
478 auto dot_file = fopen(file_name.c_str(),
"w");
486 const std::string & file_name,
487 std::unordered_map<rvsdg::Output *, ViewColors> outputColor,
488 std::unordered_map<rvsdg::Input *, ViewColors> inputColor,
489 std::unordered_map<rvsdg::Output *, ViewColors> tailLabel)
491 auto dot_file = fopen(file_name.c_str(),
"w");
492 ViewDot(region, dot_file, outputColor, inputColor, tailLabel);
499 auto cmd =
"dot -Tsvg -O " + file_name;
500 if (system(cmd.c_str()))
515 const auto file = statisticsCollector.
createOutputFile(
"rvsdg-graph.dot",
true);
Region & GetRootRegion() const noexcept
size_t ninputs() const noexcept
size_t noutputs() const noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
size_t index() const noexcept
Represents the argument of a region.
Represents the result of a region.
StructuralOutput * output() const noexcept
Represent acyclic RVSDG subgraphs.
RegionResult * result(size_t index) const noexcept
size_t nresults() const noexcept
size_t index() const noexcept
RegionArgument * argument(size_t index) const noexcept
size_t narguments() const noexcept
std::string DebugString() const override
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
std::string DebugString() const override
size_t nsubregions() const noexcept
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
#define JLM_UNREACHABLE(msg)
std::string GetDotName(rvsdg::Node *node)
ViewColors GetDefaultLabel(std::unordered_map< T *, ViewColors > &map, T *elem, ViewColors def=NONE)
std::string SymbolicEdge(rvsdg::Input *output, rvsdg::Output *input)
void DumpDot(llvm::LlvmRvsdgModule &rvsdgModule, const std::string &file_name)
std::string RegionToDot(rvsdg::Region *region, std::unordered_map< rvsdg::Output *, ViewColors > &outputColor, std::unordered_map< rvsdg::Input *, ViewColors > &inputColor, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel)
std::string ResultToDot(rvsdg::RegionResult *result, const ViewColors &color)
std::string PortToDot(const std::string &display_name, const std::string &dot_name, const ViewColors &color)
void DotToSvg(const std::string &file_name)
void ViewDot(rvsdg::Region *region, FILE *out, std::unordered_map< rvsdg::Output *, ViewColors > &outputColor, std::unordered_map< rvsdg::Input *, ViewColors > &inputColor, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel)
std::string Edge(jlm::rvsdg::Output *output, jlm::rvsdg::Input *input, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel, bool back_edge=false)
std::string StructuralOutputToDot(rvsdg::StructuralOutput *structuralOutput, const ViewColors &color)
ViewColors GetDefaultColor(std::unordered_map< T *, ViewColors > &map, T *elem, ViewColors def=BLACK)
std::string ToDot(rvsdg::Region *region, std::unordered_map< rvsdg::Output *, ViewColors > &outputColor, std::unordered_map< rvsdg::Input *, ViewColors > &inputColor, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel)
static std::string hex(size_t i)
std::string ArgumentToDot(rvsdg::RegionArgument *argument, const ViewColors &color)
std::string StructuralNodeToDot(rvsdg::StructuralNode *structuralNode, std::unordered_map< rvsdg::Output *, ViewColors > &outputColor, std::unordered_map< rvsdg::Input *, ViewColors > &inputColor, std::unordered_map< rvsdg::Output *, ViewColors > &tailLabel)
std::string StructuralInputToDot(rvsdg::StructuralInput *structuralInput, const ViewColors &color)
std::string ViewcolorToString(const ViewColors &color)
bool isForbiddenChar(char c)
std::string SimpleNodeToDot(rvsdg::SimpleNode *simpleNode, std::unordered_map< rvsdg::Output *, ViewColors > &outputColor, std::unordered_map< rvsdg::Input *, ViewColors > &inputColor)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
static std::string strfmt(Args... args)