1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Martin Trapp, Christian Schaefer
6 ** irdump.h: dumping of an intermediate representation graph
18 # include "type_or_entity.h"
20 # include "typewalk.h"
22 #define DEFAULT_NODE_ATTR ""
23 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
24 #define NODE2TYPE_EDGE_ATTR ""
25 #define DEFAULT_TYPE_ATTRIBUTE ""
26 #define TYPE_EDGE_ATTR ""
32 /*******************************************************************/
33 /* routines to dump information about a single node */
34 /*******************************************************************/
37 dump_ir_node (ir_node *n)
40 xfprintf (F, "node: {title: \"%p\" label: ", n);
42 switch (n->op->code) { /* node label */
44 xfprintf (F, "\"%I\" color: blue ", n->op->name);
45 xfprintf (F, DEFAULT_NODE_ATTR);
48 xfprintf (F, "\"%I\" color: blue ", n->op->name);
49 xfprintf (F, DEFAULT_NODE_ATTR);
52 xfprintf (F, "\"%I\" color: lightyellow ", n->op->name);
53 xfprintf (F, DEFAULT_NODE_ATTR);
56 xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name);
57 if (n->mode->code == irm_M)
58 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
60 xfprintf (F, DEFAULT_NODE_ATTR);
63 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name);
64 xfprintf (F, DEFAULT_NODE_ATTR);
67 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
68 xfprintf (F, DEFAULT_NODE_ATTR);
71 if (n->in[1]->op->code == iro_Cmp) {
72 xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name,
73 get_pnc_string(n->attr.proj));
75 xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj);
77 xfprintf (F, DEFAULT_NODE_ATTR);
80 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
81 xfprintf (F, DEFAULT_NODE_ATTR);
84 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
85 xfprintf (F, DEFAULT_NODE_ATTR);
88 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
89 xfprintf (F, DEFAULT_NODE_ATTR);
92 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
93 xfprintf (F, DEFAULT_NODE_ATTR);
96 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
97 xfprintf (F, DEFAULT_NODE_ATTR);
100 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
101 xfprintf (F, DEFAULT_NODE_ATTR);
104 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
105 xfprintf (F, DEFAULT_NODE_ATTR);
108 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
109 xfprintf (F, DEFAULT_NODE_ATTR);
112 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
113 xfprintf (F, DEFAULT_NODE_ATTR);
116 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
117 xfprintf (F, DEFAULT_NODE_ATTR);
120 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
121 xfprintf (F, DEFAULT_NODE_ATTR);
124 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
125 xfprintf (F, DEFAULT_NODE_ATTR);
128 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
129 xfprintf (F, DEFAULT_NODE_ATTR);
132 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
133 xfprintf (F, DEFAULT_NODE_ATTR);
136 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
137 xfprintf (F, DEFAULT_NODE_ATTR);
140 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
141 xfprintf (F, DEFAULT_NODE_ATTR);
144 xfprintf (F, "\"%I\"", n->op->name);
145 xfprintf (F, DEFAULT_NODE_ATTR);
148 xfprintf (F, "\"%I\"", n->op->name);
149 xfprintf (F, DEFAULT_NODE_ATTR);
152 xfprintf (F, "\"%I\"", n->op->name);
153 xfprintf (F, DEFAULT_NODE_ATTR);
156 xfprintf (F, "\"%I\"", n->op->name);
157 xfprintf (F, DEFAULT_NODE_ATTR);
160 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
161 xfprintf (F, DEFAULT_NODE_ATTR);
165 xfprintf (F, "\"%R\"", n);
166 xfprintf (F, DEFAULT_NODE_ATTR);
169 xfprintf (F, "\"%I\" ", n->op->name);
170 xfprintf (F, DEFAULT_NODE_ATTR);
173 assert(n->attr.s.ent->kind == k_entity);
174 xfprintf (F, "\"%I ", n->op->name);
175 xfprintf (F, "%s\" ", id_to_str(n->attr.s.ent->name));
176 /* xdoesn't work for some reason.
177 fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
178 xfprintf (F, DEFAULT_NODE_ATTR);
181 assert(get_kind(get_SymConst_type(n)) == k_type_class);
182 /* assert(n->attr.i.type->kind == k_type_class); */
183 assert(get_class_ident((type_class *)get_SymConst_type(n)));
184 /* assert(n->attr.i.type->clss->name); */
185 xfprintf (F, "\"%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
186 /* xfprintf (F, "\"%s ", id_to_str(n->attr.i.type->name)); */
187 /* doesn't work for some reason. */
188 /* xfprintf (F, "\"%N\" ", n->attr.i.type); */
189 switch (n->attr.i.num){
191 xfprintf (F, "tag\" ");
194 xfprintf (F, "size\" ");
200 xfprintf (F, DEFAULT_NODE_ATTR);
203 xfprintf (F, "\"%I\" ", n->op->name);
204 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
207 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
208 xfprintf (F, DEFAULT_NODE_ATTR);
211 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
213 xfprintf (F, "}\n"); /* footer */
217 /* dump the edge to the block this node belongs to */
219 dump_ir_block_edge(ir_node *n) {
221 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
222 BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
226 /* dump edges to our inputs */
228 dump_ir_data_edges(ir_node *n) {
231 for (i = 0; i < get_irn_arity(n); i++) {
232 assert(get_irn_n(n, i));
233 xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
235 fprintf (F, " label: \"%d\"", i+1);
240 /* dumps the edges between nodes and their type or entity attributes. */
241 void dump_node2type_edges (ir_node *n, void *env)
245 switch (get_irn_opcode(n)) {
247 if ( (get_SymConst_kind(n) == type_tag)
248 || (get_SymConst_kind(n) == size))
249 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
250 NODE2TYPE_EDGE_ATTR "}\n", n, get_SymConst_type(n));
253 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
254 NODE2TYPE_EDGE_ATTR "}\n", n, get_Sel_entity(n));
257 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
258 NODE2TYPE_EDGE_ATTR "}\n", n, get_Call_type(n));
261 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
262 NODE2TYPE_EDGE_ATTR "}\n", n, get_Alloc_type(n));
265 printf(" in irdum\n");
266 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
267 NODE2TYPE_EDGE_ATTR "}\n", n, get_Free_type(n));
275 /* dumps a type or entity and it's edges. */
277 dump_type_info (type_or_ent *tore, void *env) {
278 int i = 0; /* to shutup gcc */
280 /* dump this type or entity */
281 xfprintf (F, "node: {title: \"%p\" ", tore);
282 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
283 xfprintf (F, "label: ");
285 switch (get_kind(tore)) {
288 entity *ent = (entity *)tore;
289 xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
290 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
292 TYPE_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
293 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
295 TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
300 type_class *type = (type_class *)tore;
301 xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
307 type_strct *type = (type_strct *)tore;
308 xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
314 type_method *type = (type_method *)tore;
315 xfprintf (F, "\"meth %I\"}\n", get_method_ident(type));
316 for (i = 0; i < get_method_arity(type); i++)
317 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
318 " label: \"param %d\" " TYPE_EDGE_ATTR "}\n",
319 tore, get_method_param_type(type, i), i);
320 for (i = 0; i < get_method_n_res(type); i++)
321 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
322 " label: \"res %d\" " TYPE_EDGE_ATTR "}\n",
323 tore, get_method_res_type(type, i), i);
328 type_union *type = (type_union *)tore;
329 xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
335 type_array *type = (type_array *)tore;
336 xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
337 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
338 TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
341 case k_type_enumeration:
343 type_enumeration *type = (type_enumeration *)tore;
344 xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
349 type_pointer *type = (type_pointer *)tore;
350 xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
351 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
352 TYPE_EDGE_ATTR "}\n", tore,
353 get_pointer_points_to_type(type), i);
356 case k_type_primitive:
358 type_primitive *type = (type_primitive *)tore;
359 xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
360 get_mode_ident(get_primitive_mode(type)));
369 /************************************************************************/
370 /* open and close vcg file */
371 /************************************************************************/
373 void vcg_open (ir_graph *irg, char *suffix) {
374 char *fname; /* filename to put the vcg information in */
379 /** open file for vcg graph */
380 id = get_entity_ld_name (irg->ent);
382 len = id_to_strlen (id);
384 fname = malloc (len + 5 + strlen(suffix));
385 strcpy (fname, cp); /* copy the filename */
386 strcat (fname, suffix); /* append file suffix */
387 strcat (fname, ".vcg"); /* append the .vcg suffix */
389 F = fopen (fname, "w"); /* open file for writing */
391 panic ("cannot open %s for writing (%m)", fname); /* not reached */
396 "graph: { title: \"ir graph of %s\"\n"
397 "display_edge_labels: yes\n"
398 "layoutalgorithm: mindepth\n"
399 "manhattan_edges: yes\n"
401 "orientation: bottom_to_top\n"
402 "classname 1: \"Data\"\n"
403 "classname 2: \"Block\"\n", cp);
405 xfprintf (F, "\n"); /* a separator */
410 xfprintf (F, "}\n"); /* print footer */
411 fclose (F); /* close vcg file */
416 /************************************************************************/
417 /* routines to dump a graph, blocks as conventional nodes. */
418 /************************************************************************/
421 dump_whole_node (ir_node *n, void* env) {
423 dump_ir_block_edge(n);
424 dump_ir_data_edges(n);
428 dump_ir_graph (ir_graph *irg)
432 /* walk over the graph */
433 irg_walk(irg->end, dump_whole_node, NULL, NULL);
438 /***********************************************************************/
439 /* the following routines dump the nodes as attached to the blocks. */
440 /***********************************************************************/
443 dump_ir_blocks_nodes (ir_node *n, void *env) {
444 ir_node *block = (ir_node *)env;
446 if (is_no_Block(n) && get_nodes_Block(n) == block) {
448 dump_ir_data_edges(n);
454 dump_ir_block (ir_node *block, void *env) {
455 ir_graph *irg = (ir_graph *)env;
457 if (get_irn_opcode(block) == iro_Block) {
458 /* This is a block. So dump the vcg information to make a block. */
459 xfprintf(F, "graph: { title: \"%p\" status:clustered color:lightyellow \n",
461 /* dump the blocks edges */
462 dump_ir_data_edges(block);
464 /* dump the nodes that go into the block */
465 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
467 /* Close the vcg information for the block */
468 xfprintf(F, "}\n\n");
473 dump_ir_block_graph (ir_graph *irg)
477 /* walk over the blocks in the graph */
478 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
484 /***********************************************************************/
485 /* the following routines dump a control flow graph */
486 /***********************************************************************/
490 dump_block_to_cfg (ir_node *block, void *env) {
494 if (get_irn_opcode(block) == iro_Block) {
495 /* This is a block. Dump a node for the block. */
496 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
499 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
500 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
501 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" }\n",
508 dump_cfg (ir_graph *irg)
510 vcg_open (irg, "-cfg");
512 /* walk over the blocks in the graph */
513 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
519 /***********************************************************************/
520 /* the following routine dumps all type information */
521 /***********************************************************************/
525 dump_type_graph (ir_graph *irg)
527 vcg_open (irg, "-type");
529 /* walk over the blocks in the graph */
530 type_walk(irg, dump_type_info, NULL, NULL);
536 /***********************************************************************/
537 /* dumps a graph with type information */
538 /***********************************************************************/
542 dump_ir_graph_w_types (ir_graph *irg)
544 vcg_open (irg, "-all");
546 /* dump common ir graph */
547 /* irg_block_walk(irg->end, dump_ir_block, NULL, irg); */
548 irg_walk(irg->end, dump_whole_node, NULL, NULL);
550 type_walk(irg, dump_type_info, NULL, NULL);
551 /* dump edges from graph to type info */
552 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);