Jlm
view.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010 2011 2012 Helge Bahmann <hcb@chaoticmind.net>
3  * Copyright 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
7 #include <jlm/rvsdg/gamma.hpp>
8 #include <jlm/rvsdg/theta.hpp>
10 #include <jlm/rvsdg/view.hpp>
11 
12 namespace jlm::rvsdg
13 {
14 
15 static std::string
17  const rvsdg::Region * region,
18  size_t depth,
19  std::unordered_map<const Output *, std::string> &);
20 
21 static std::string
22 indent(size_t depth)
23 {
24  return std::string(depth * 2, ' ');
25 }
26 
27 static std::string
29  const jlm::rvsdg::Output * port,
30  std::unordered_map<const Output *, std::string> & map)
31 {
32  std::string name = dynamic_cast<const rvsdg::RegionArgument *>(port) ? "a" : "o";
33  name += jlm::util::strfmt(map.size());
34  return name;
35 }
36 
37 static std::string
39  const Node * node,
40  size_t depth,
41  std::unordered_map<const Output *, std::string> & map)
42 {
43  std::string s(indent(depth));
44  for (size_t n = 0; n < node->noutputs(); n++)
45  {
46  auto name = create_port_name(node->output(n), map);
47  map[node->output(n)] = name;
48  s = s + name + " ";
49  }
50 
51  s += ":= " + node->DebugString() + " ";
52 
53  for (size_t n = 0; n < node->ninputs(); n++)
54  {
55  s += map[node->input(n)->origin()];
56  if (n <= node->ninputs() - 1)
57  s += " ";
58  }
59  s += "\n";
60 
61  if (auto snode = dynamic_cast<const rvsdg::StructuralNode *>(node))
62  {
63  for (size_t n = 0; n < snode->nsubregions(); n++)
64  s += region_to_string(snode->subregion(n), depth + 1, map);
65  }
66 
67  return s;
68 }
69 
70 static std::string
71 region_header(const rvsdg::Region * region, std::unordered_map<const Output *, std::string> & map)
72 {
73  std::string header("[");
74  for (size_t n = 0; n < region->narguments(); n++)
75  {
76  auto argument = region->argument(n);
77  auto pname = create_port_name(argument, map);
78  map[argument] = pname;
79 
80  header += pname;
81  if (argument->input())
82  header += jlm::util::strfmt(" <= ", map[argument->input()->origin()]);
83 
84  if (n < region->narguments() - 1)
85  header += ", ";
86  }
87  header += "]{";
88 
89  return header;
90 }
91 
92 static std::string
94  const Region * region,
95  const size_t depth,
96  std::unordered_map<const Output *, std::string> & map)
97 {
98  std::string body;
99  for (const auto node : TopDownConstTraverser(region))
100  {
101  body += node_to_string(node, depth, map);
102  }
103 
104  return body;
105 }
106 
107 static std::string
108 region_footer(const rvsdg::Region * region, std::unordered_map<const Output *, std::string> & map)
109 {
110  std::string footer("}[");
111  for (size_t n = 0; n < region->nresults(); n++)
112  {
113  auto result = region->result(n);
114  auto pname = map[result->origin()];
115 
116  if (result->output())
117  footer += map[result->output()] + " <= ";
118  footer += pname;
119 
120  if (n < region->nresults() - 1)
121  footer += ", ";
122  }
123  footer += "]";
124 
125  return footer;
126 }
127 
128 static std::string
130  const rvsdg::Region * region,
131  size_t depth,
132  std::unordered_map<const Output *, std::string> & map)
133 {
134  std::string s;
135  s = indent(depth) + region_header(region, map) + "\n";
136  s = s + region_body(region, depth + 1, map);
137  s = s + indent(depth) + region_footer(region, map) + "\n";
138  return s;
139 }
140 
141 std::string
142 view(const rvsdg::Region * region)
143 {
144  std::unordered_map<const Output *, std::string> map;
145  return view(region, map);
146 }
147 
148 std::string
149 view(const rvsdg::Region * region, std::unordered_map<const Output *, std::string> & map)
150 {
151  return region_to_string(region, 0, map);
152 }
153 
154 void
155 view(const rvsdg::Region * region, FILE * out)
156 {
157  fputs(view(region).c_str(), out);
158  fflush(out);
159 }
160 
161 /* xml */
162 
163 static inline std::string
165 {
166  return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
167  "<rvsdg>\n";
168 }
169 
170 static inline std::string
172 {
173  return "</rvsdg>\n";
174 }
175 
176 static inline std::string
177 id(const jlm::rvsdg::Output * port)
178 {
179  return jlm::util::strfmt("o", (intptr_t)port);
180 }
181 
182 static inline std::string
183 id(const jlm::rvsdg::Input * port)
184 {
185  return jlm::util::strfmt("i", (intptr_t)port);
186 }
187 
188 static inline std::string
189 id(const Node * node)
190 {
191  return jlm::util::strfmt("n", (intptr_t)node);
192 }
193 
194 static inline std::string
195 id(const rvsdg::Region * region)
196 {
197  return jlm::util::strfmt("r", (intptr_t)region);
198 }
199 
200 static inline std::string
201 argument_tag(const std::string & id)
202 {
203  return "<argument id=\"" + id + "\"/>\n";
204 }
205 
206 static inline std::string
207 result_tag(const std::string & id)
208 {
209  return "<result id=\"" + id + "\"/>\n";
210 }
211 
212 static inline std::string
213 input_tag(const std::string & id)
214 {
215  return "<input id=\"" + id + "\"/>\n";
216 }
217 
218 static inline std::string
219 output_tag(const std::string & id)
220 {
221  return "<output id=\"" + id + "\"/>\n";
222 }
223 
224 static inline std::string
225 node_starttag(const std::string & id, const std::string & name, const std::string & type)
226 {
227  return "<node id=\"" + id + "\" name=\"" + name + "\" type=\"" + type + "\">\n";
228 }
229 
230 static inline std::string
232 {
233  return "</node>\n";
234 }
235 
236 static inline std::string
237 region_starttag(const std::string & id)
238 {
239  return "<region id=\"" + id + "\">\n";
240 }
241 
242 static inline std::string
243 region_endtag(const std::string &)
244 {
245  return "</region>\n";
246 }
247 
248 static inline std::string
249 edge_tag(const std::string & srcid, const std::string & dstid)
250 {
251  return "<edge source=\"" + srcid + "\" target=\"" + dstid + "\"/>\n";
252 }
253 
254 static inline std::string
255 type(const Node * n)
256 {
257  if (dynamic_cast<const GammaNode *>(n))
258  return "gamma";
259 
260  if (dynamic_cast<const ThetaNode *>(n))
261  return "theta";
262 
263  return "";
264 }
265 
266 static std::string
267 convert_region(const jlm::rvsdg::Region * region);
268 
269 static inline std::string
271 {
272  std::string s;
273 
274  s += node_starttag(id(node), node->DebugString(), "");
275  for (size_t n = 0; n < node->ninputs(); n++)
276  s += input_tag(id(node->input(n)));
277  for (size_t n = 0; n < node->noutputs(); n++)
278  s += output_tag(id(node->output(n)));
279  s += node_endtag();
280 
281  for (size_t n = 0; n < node->noutputs(); n++)
282  {
283  auto output = node->output(n);
284  for (const auto & user : output->Users())
285  s += edge_tag(id(output), id(&user));
286  }
287 
288  return s;
289 }
290 
291 static inline std::string
293 {
294  std::string s;
295  s += node_starttag(id(node), "", type(node));
296 
297  for (size_t n = 0; n < node->ninputs(); n++)
298  s += input_tag(id(node->input(n)));
299  for (size_t n = 0; n < node->noutputs(); n++)
300  s += output_tag(id(node->output(n)));
301 
302  for (size_t n = 0; n < node->nsubregions(); n++)
303  s += convert_region(node->subregion(n));
304  s += node_endtag();
305 
306  for (size_t n = 0; n < node->noutputs(); n++)
307  {
308  auto output = node->output(n);
309  for (const auto & user : output->Users())
310  s += edge_tag(id(output), id(&user));
311  }
312 
313  return s;
314 }
315 
316 static inline std::string
317 convert_node(const Node * node)
318 {
319  if (auto n = dynamic_cast<const SimpleNode *>(node))
320  return convert_simple_node(n);
321 
322  if (auto n = dynamic_cast<const StructuralNode *>(node))
323  return convert_structural_node(n);
324 
325  JLM_ASSERT(0);
326  return "";
327 }
328 
329 static inline std::string
331 {
332  std::string s;
333  s += region_starttag(id(region));
334 
335  for (size_t n = 0; n < region->narguments(); n++)
336  s += argument_tag(id(region->argument(n)));
337 
338  for (const auto & node : region->Nodes())
339  s += convert_node(&node);
340 
341  for (size_t n = 0; n < region->nresults(); n++)
342  s += result_tag(id(region->result(n)));
343 
344  for (size_t n = 0; n < region->narguments(); n++)
345  {
346  auto argument = region->argument(n);
347  for (const auto & user : argument->Users())
348  s += edge_tag(id(argument), id(&user));
349  }
350 
351  s += region_endtag(id(region));
352 
353  return s;
354 }
355 
356 std::string
357 to_xml(const rvsdg::Region * region)
358 {
359  std::string s;
360  s += xml_header();
361 
362  s += convert_region(region);
363 
364  s += xml_footer();
365  return s;
366 }
367 
368 void
369 view_xml(const rvsdg::Region * region, FILE * out)
370 {
371  fputs(to_xml(region).c_str(), out);
372  fflush(out);
373 }
374 
375 }
Conditional operator / pattern matching.
Definition: gamma.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
virtual std::string DebugString() const =0
NodeInput * input(size_t index) const noexcept
Definition: node.hpp:615
NodeOutput * output(size_t index) const noexcept
Definition: node.hpp:650
size_t ninputs() const noexcept
Definition: node.hpp:609
size_t noutputs() const noexcept
Definition: node.hpp:644
Represents the argument of a region.
Definition: region.hpp:41
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
RegionResult * result(size_t index) const noexcept
Definition: region.hpp:471
size_t nresults() const noexcept
Definition: region.hpp:465
RegionArgument * argument(size_t index) const noexcept
Definition: region.hpp:437
NodeRange Nodes() noexcept
Definition: region.hpp:328
size_t narguments() const noexcept
Definition: region.hpp:431
std::string DebugString() const override
Definition: simple-node.cpp:79
NodeInput * input(size_t index) const noexcept
Definition: simple-node.hpp:82
NodeOutput * output(size_t index) const noexcept
Definition: simple-node.hpp:88
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
#define JLM_ASSERT(x)
Definition: common.hpp:16
static std::string convert_node(const Node *node)
Definition: view.cpp:317
static std::string region_header(const rvsdg::Region *region, std::unordered_map< const Output *, std::string > &map)
Definition: view.cpp:71
static std::string indent(size_t depth)
Definition: view.cpp:22
static std::string node_endtag()
Definition: view.cpp:231
static std::string node_to_string(const Node *node, size_t depth, std::unordered_map< const Output *, std::string > &map)
Definition: view.cpp:38
static std::string region_starttag(const std::string &id)
Definition: view.cpp:237
static std::string region_footer(const rvsdg::Region *region, std::unordered_map< const Output *, std::string > &map)
Definition: view.cpp:108
static std::string output_tag(const std::string &id)
Definition: view.cpp:219
static std::string region_to_string(const rvsdg::Region *region, size_t depth, std::unordered_map< const Output *, std::string > &)
Definition: view.cpp:129
static std::string input_tag(const std::string &id)
Definition: view.cpp:213
static std::string type(const Node *n)
Definition: view.cpp:255
detail::TopDownTraverserGeneric< true > TopDownConstTraverser
Traverser for visiting every node in a const region in a top down order.
Definition: traverser.hpp:314
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142
static std::string node_starttag(const std::string &id, const std::string &name, const std::string &type)
Definition: view.cpp:225
static std::string region_body(const Region *region, const size_t depth, std::unordered_map< const Output *, std::string > &map)
Definition: view.cpp:93
static std::string id(const jlm::rvsdg::Output *port)
Definition: view.cpp:177
static std::string convert_simple_node(const jlm::rvsdg::SimpleNode *node)
Definition: view.cpp:270
static std::string convert_region(const jlm::rvsdg::Region *region)
Definition: view.cpp:330
std::string to_xml(const rvsdg::Region *region)
Definition: view.cpp:357
static std::string argument_tag(const std::string &id)
Definition: view.cpp:201
static std::string xml_header()
Definition: view.cpp:164
static std::string result_tag(const std::string &id)
Definition: view.cpp:207
static std::string region_endtag(const std::string &)
Definition: view.cpp:243
size_t ninputs(const rvsdg::Region *region) noexcept
Definition: region.cpp:682
static std::string edge_tag(const std::string &srcid, const std::string &dstid)
Definition: view.cpp:249
static std::string xml_footer()
Definition: view.cpp:171
static std::string convert_structural_node(const rvsdg::StructuralNode *node)
Definition: view.cpp:292
void view_xml(const rvsdg::Region *region, FILE *out)
Definition: view.cpp:369
static std::string create_port_name(const jlm::rvsdg::Output *port, std::unordered_map< const Output *, std::string > &map)
Definition: view.cpp:28
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35