35 +
" [shape=plaintext label=<\n"
36 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
38 " <TD BORDER=\"1\" CELLPADDING=\"1\"><FONT POINT-SIZE=\"10\">"
54 +
" [shape=plaintext label=<\n"
55 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
57 " <TD BORDER=\"1\" CELLPADDING=\"1\"><FONT POINT-SIZE=\"10\">"
69 auto SPACER =
" <TD WIDTH=\"10\"></TD>\n";
75 for (
size_t i = 0; i < node->
ninputs(); ++i)
82 inputs +=
" <TD PORT=\"" + in
83 +
"\" BORDER=\"1\" CELLPADDING=\"1\"><FONT POINT-SIZE=\"10\">" + in +
"</FONT></TD>\n";
87 for (
size_t i = 0; i < node->
noutputs(); ++i)
95 +
"\" BORDER=\"1\" CELLPADDING=\"1\"><FONT POINT-SIZE=\"10\">" + out
99 std::string color =
"black";
100 if (jlm::rvsdg::is<BufferOperation>(node))
104 else if (jlm::rvsdg::is<ForkOperation>(node))
108 else if (jlm::rvsdg::is<SinkOperation>(node))
112 else if (jlm::rvsdg::is<BranchOperation>(node))
116 else if (jlm::rvsdg::is<MuxOperation>(node))
120 else if (jlm::rvsdg::is<TriggerOperation>(node) ||
is_constant(node))
129 +
" [shape=plaintext label=<\n"
130 "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
133 " <TD BORDER=\"0\">\n"
134 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
136 " <TD WIDTH=\"20\"></TD>\n"
138 +
" <TD WIDTH=\"20\"></TD>\n"
144 " <TD BORDER=\"3\" STYLE=\"ROUNDED\" CELLPADDING=\"4\">"
145 + opname +
"<BR/><FONT POINT-SIZE=\"10\">" + name
149 " <TD BORDER=\"0\">\n"
150 " <TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n"
152 " <TD WIDTH=\"20\"></TD>\n"
154 +
" <TD WIDTH=\"20\"></TD>\n"
161 + color +
" color=" + color +
"];\n";
168 auto color =
"black";
180 return src +
" -> " + snk +
" [style=\"\", arrowhead=\"normal\", color=" + color
181 +
", headlabel=<>, fontsize=10, labelangle=45, labeldistance=2.0, "
182 "labelfontcolor=black, penwidth=3];\n";
185 return src +
" -> " + snk +
" [style=\"\", arrowhead=\"normal\", color=" + color
186 +
", headlabel=<>, fontsize=10, labelangle=45, labeldistance=2.0, labelfontcolor=black, "
187 "penwidth=3, constraint=false];\n";
197 std::ostringstream dot;
198 dot <<
"subgraph cluster_loop_" <<
loop_ctr++ <<
" {\n";
199 dot <<
"color=\"#ff8080\"\n";
201 std::set<jlm::rvsdg::Output *> back_outputs;
202 std::set<rvsdg::Node *> top_nodes;
203 for (
size_t i = 0; i < sr->narguments(); ++i)
205 auto arg = sr->argument(i);
207 if (arg->input() ==
nullptr)
209 back_outputs.insert(arg);
218 if (top_nodes.count(node))
220 dot <<
"{rank=source; \n";
229 else if (
auto ln =
dynamic_cast<LoopNode *
>(node))
238 throw util::Error(
"Unimplemented op (unexpected structural node) : " + node->DebugString());
243 dot <<
"{rank=same ";
246 auto mx =
dynamic_cast<const MuxOperation *
>(&node->GetOperation());
248 if ((mx && !mx->discarding && mx->loop) || lc)
255 dot <<
"{rank=same ";
258 auto br =
dynamic_cast<const BranchOperation *
>(&node->GetOperation());
272 auto mx =
dynamic_cast<const MuxOperation *
>(&node->GetOperation());
274 for (
size_t i = 0; i < node->ninputs(); ++i)
276 auto in_name = node_name +
":" +
get_port_name(node->input(i));
278 auto origin =
output_map[node->input(i)->origin()];
280 bool back = mx && !mx->discarding && mx->loop
282 auto origin_out_node = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*node->input(i)->origin());
289 dot <<
edge(origin, in_name, *node->input(i)->Type(), back);
308 for (
size_t i = 0; i < node->noutputs(); ++i)
313 else if (
auto oln =
dynamic_cast<LoopNode *
>(node))
319 throw util::Error(
"Unimplemented op (unexpected structural node) : " + node->DebugString());
322 for (
size_t i = 0; i < sr->narguments(); ++i)
324 auto arg = sr->argument(i);
334 auto result = ba->result();
340 for (
size_t i = 0; i < ln->
noutputs(); ++i)
351 std::ostringstream dot;
352 dot <<
"digraph G {\n";
358 dot <<
"{rank=source; ";
367 dot <<
"[style = invis]}";
369 for (
size_t i = 0; i < sr->
nresults(); ++i)
373 dot <<
"subgraph cluster_sub {\n";
374 dot <<
"color=\"#80b3ff\"\n";
375 dot <<
"penwidth=6\n";
390 for (
size_t i = 0; i < node->ninputs(); ++i)
392 auto in_name = node_name +
":" +
get_port_name(node->input(i));
394 auto origin =
output_map[node->input(i)->origin()];
395 dot <<
edge(origin, in_name, *node->input(i)->Type());
397 for (
size_t i = 0; i < node->noutputs(); ++i)
402 else if (
auto ln =
dynamic_cast<LoopNode *
>(node))
410 throw util::Error(
"Unimplemented op (unexpected structural node) : " + node->DebugString());
414 for (
size_t i = 0; i < sr->
nresults(); ++i)
static std::string get_port_name(jlm::rvsdg::Input *port)
std::unordered_map< jlm::rvsdg::Output *, std::string > output_map
const rvsdg::LambdaNode * get_hls_lambda(llvm::LlvmRvsdgModule &rm)
std::string get_node_name(const rvsdg::Node *node)
std::string edge(std::string src, std::string snk, const jlm::rvsdg::Type &type, bool back=false)
std::string loop_to_dot(LoopNode *ln)
void prepare_loop_out_port(LoopNode *ln)
std::string result_to_dot(rvsdg::RegionResult *port)
std::string node_to_dot(const rvsdg::Node *node)
std::string argument_to_dot(rvsdg::RegionArgument *port)
std::string subregion_to_dot(rvsdg::Region *sr)
std::string GetText(llvm::LlvmRvsdgModule &rm) override
std::string extension() override
rvsdg::Region * subregion() const noexcept
virtual std::string DebugString() const =0
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
size_t ninputs() const noexcept
size_t noutputs() const noexcept
Represents the argument of a region.
Represents the result of a region.
Represent acyclic RVSDG subgraphs.
RegionResult * result(size_t index) const noexcept
size_t nresults() const noexcept
RegionArgument * argument(size_t index) const noexcept
size_t narguments() const noexcept
StructuralOutput * output(size_t index) const noexcept
static bool is_constant(const rvsdg::Node *node)
bool isForbiddenChar(char c)
static std::string type(const Node *n)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)