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
10 # include "irgraph_t.h"
19 # include "type_or_entity.h"
21 # include "typewalk.h"
23 #define DEFAULT_NODE_ATTR ""
24 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
25 #define NODE2TYPE_EDGE_ATTR ""
26 #define DEFAULT_TYPE_ATTRIBUTE ""
27 #define TYPE_EDGE_ATTR ""
33 /*******************************************************************/
34 /* routines to dump information about a single node */
35 /*******************************************************************/
40 dump_node_opcode (ir_node *n)
43 if (n->op->code == iro_Const) {
44 xfprintf (F, "%v", n->attr.con);
46 } else if (n->op->code == iro_SymConst) {
47 if (get_SymConst_kind(n) == linkage_ptr_info) {
48 xfprintf (F, "%I", get_SymConst_ptrinfo(n));
50 assert(get_kind(get_SymConst_type(n)) == k_type_class);
51 assert(get_class_ident((type_class *)get_SymConst_type(n)));
52 xfprintf (F, "%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
53 if (get_SymConst_kind == type_tag)
60 xfprintf (F, "%I", n->op->name);
65 dump_node_mode (ir_node *n)
67 switch (n->op->code) {
84 xfprintf (F, "%I", n->mode->name);
91 dump_node_nodeattr (ir_node *n)
93 switch (n->op->code) {
95 if (n->in[1]->op->code == iro_Cmp) {
96 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
98 xfprintf (F, "%ld", n->attr.proj);
102 /*assert(n->attr.s.ent->kind == k_entity);*/
103 assert(get_kind(get_Sel_entity(n)) == k_entity);
104 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
106 /* xdoesn't work for some reason.
107 fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
114 dump_node_vcgattr (ir_node *n)
116 switch (n->op->code) {
119 xfprintf (F, "color: blue");
122 xfprintf (F, "color: lightyellow");
125 xfprintf (F, "color: green");
130 xfprintf (F, "color: yellow");
133 xfprintf (F, DEFAULT_NODE_ATTR);
138 dump_node (ir_node *n) {
141 xfprintf (F, "node: {title: \"%p\" label: \"", n);
145 dump_node_nodeattr(n);
147 xfprintf (F, " %ld", get_irn_node_nr(n));
150 dump_node_vcgattr(n);
155 dump_ir_node (ir_node *n)
158 xfprintf (F, "node: {title: \"%p\" label: ", n);
160 switch (n->op->code) { /* node label */
162 xfprintf (F, "\"%I\" color: blue ", n->op->name);
163 xfprintf (F, DEFAULT_NODE_ATTR);
166 xfprintf (F, "\"%I\" color: blue ", n->op->name);
167 xfprintf (F, DEFAULT_NODE_ATTR);
170 xfprintf (F, "\"%I\" color: lightyellow ", n->op->name);
171 xfprintf (F, DEFAULT_NODE_ATTR);
174 xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name);
175 if (n->mode->code == irm_M)
176 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
178 xfprintf (F, DEFAULT_NODE_ATTR);
181 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name);
182 xfprintf (F, DEFAULT_NODE_ATTR);
185 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
186 xfprintf (F, DEFAULT_NODE_ATTR);
189 if (n->in[1]->op->code == iro_Cmp) {
190 xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name,
191 get_pnc_string(n->attr.proj));
193 xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj);
195 xfprintf (F, DEFAULT_NODE_ATTR);
198 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
199 xfprintf (F, DEFAULT_NODE_ATTR);
202 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
203 xfprintf (F, DEFAULT_NODE_ATTR);
206 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
207 xfprintf (F, DEFAULT_NODE_ATTR);
210 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
211 xfprintf (F, DEFAULT_NODE_ATTR);
214 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
215 xfprintf (F, DEFAULT_NODE_ATTR);
218 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
219 xfprintf (F, DEFAULT_NODE_ATTR);
222 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
223 xfprintf (F, DEFAULT_NODE_ATTR);
226 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
227 xfprintf (F, DEFAULT_NODE_ATTR);
230 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
231 xfprintf (F, DEFAULT_NODE_ATTR);
234 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
235 xfprintf (F, DEFAULT_NODE_ATTR);
238 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
239 xfprintf (F, DEFAULT_NODE_ATTR);
242 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
243 xfprintf (F, DEFAULT_NODE_ATTR);
246 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
247 xfprintf (F, DEFAULT_NODE_ATTR);
250 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
251 xfprintf (F, DEFAULT_NODE_ATTR);
254 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
255 xfprintf (F, DEFAULT_NODE_ATTR);
258 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
259 xfprintf (F, DEFAULT_NODE_ATTR);
262 xfprintf (F, "\"%I\"", n->op->name);
263 xfprintf (F, DEFAULT_NODE_ATTR);
266 xfprintf (F, "\"%I\"", n->op->name);
267 xfprintf (F, DEFAULT_NODE_ATTR);
270 xfprintf (F, "\"%I\"", n->op->name);
271 xfprintf (F, DEFAULT_NODE_ATTR);
274 xfprintf (F, "\"%I\"", n->op->name);
275 xfprintf (F, DEFAULT_NODE_ATTR);
278 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
279 xfprintf (F, DEFAULT_NODE_ATTR);
283 xfprintf (F, "\"%R\"", n);
284 xfprintf (F, DEFAULT_NODE_ATTR);
287 xfprintf (F, "\"%I\" ", n->op->name);
288 xfprintf (F, DEFAULT_NODE_ATTR);
291 assert(get_kind(get_Sel_entity(n)) == k_entity);
292 /*assert(n->attr.s.ent->kind == k_entity);*/
293 xfprintf (F, "\"%I ", n->op->name);
294 /*xfprintf (F, "%s\" ", id_to_str(n->attr.s.ent->name));*/
295 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
296 /* xdoesn't work for some reason.
297 fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
298 xfprintf (F, DEFAULT_NODE_ATTR);
301 assert(get_kind(get_SymConst_type(n)) == k_type_class);
302 /* assert(n->attr.i.type->kind == k_type_class); */
303 assert(get_class_ident((type_class *)get_SymConst_type(n)));
304 /* assert(n->attr.i.type->clss->name); */
305 xfprintf (F, "\"%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
306 /* xfprintf (F, "\"%s ", id_to_str(n->attr.i.type->name)); */
307 /* doesn't work for some reason. */
308 /* xfprintf (F, "\"%N\" ", n->attr.i.type); */
309 switch (n->attr.i.num){
311 xfprintf (F, "tag\" ");
314 xfprintf (F, "size\" ");
320 xfprintf (F, DEFAULT_NODE_ATTR);
323 xfprintf (F, "\"%I\" ", n->op->name);
324 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
327 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
328 xfprintf (F, DEFAULT_NODE_ATTR);
331 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
333 xfprintf (F, "}\n"); /* footer */
337 /* dump the edge to the block this node belongs to */
339 dump_ir_block_edge(ir_node *n) {
341 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
342 BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
346 /* dump edges to our inputs */
348 dump_ir_data_edges(ir_node *n) {
351 for (i = 0; i < get_irn_arity(n); i++) {
352 assert(get_irn_n(n, i));
353 xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
355 fprintf (F, " label: \"%d\"", i+1);
360 /* dumps the edges between nodes and their type or entity attributes. */
361 void dump_node2type_edges (ir_node *n, void *env)
365 switch (get_irn_opcode(n)) {
367 if ( (get_SymConst_kind(n) == type_tag)
368 || (get_SymConst_kind(n) == size))
369 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
370 NODE2TYPE_EDGE_ATTR "}\n", n, get_SymConst_type(n));
373 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
374 NODE2TYPE_EDGE_ATTR "}\n", n, get_Sel_entity(n));
377 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
378 NODE2TYPE_EDGE_ATTR "}\n", n, get_Call_type(n));
381 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
382 NODE2TYPE_EDGE_ATTR "}\n", n, get_Alloc_type(n));
385 printf(" in irdum\n");
386 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
387 NODE2TYPE_EDGE_ATTR "}\n", n, get_Free_type(n));
395 /* dumps a type or entity and it's edges. */
397 dump_type_info (type_or_ent *tore, void *env) {
398 int i = 0; /* to shutup gcc */
400 /* dump this type or entity */
401 xfprintf (F, "node: {title: \"%p\" ", tore);
402 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
403 xfprintf (F, "label: ");
405 switch (get_kind(tore)) {
408 entity *ent = (entity *)tore;
409 xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
410 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
412 TYPE_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
413 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
415 TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
420 type_class *type = (type_class *)tore;
421 xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
427 type_strct *type = (type_strct *)tore;
428 xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
434 type_method *type = (type_method *)tore;
435 xfprintf (F, "\"meth %I\"}\n", get_method_ident(type));
436 for (i = 0; i < get_method_arity(type); i++)
437 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
438 " label: \"param %d\" " TYPE_EDGE_ATTR "}\n",
439 tore, get_method_param_type(type, i), i);
440 for (i = 0; i < get_method_n_res(type); i++)
441 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
442 " label: \"res %d\" " TYPE_EDGE_ATTR "}\n",
443 tore, get_method_res_type(type, i), i);
448 type_union *type = (type_union *)tore;
449 xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
455 type_array *type = (type_array *)tore;
456 xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
457 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
458 TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
461 case k_type_enumeration:
463 type_enumeration *type = (type_enumeration *)tore;
464 xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
469 type_pointer *type = (type_pointer *)tore;
470 xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
471 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
472 TYPE_EDGE_ATTR "}\n", tore,
473 get_pointer_points_to_type(type), i);
476 case k_type_primitive:
478 type_primitive *type = (type_primitive *)tore;
479 xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
480 get_mode_ident(get_primitive_mode(type)));
489 /************************************************************************/
490 /* open and close vcg file */
491 /************************************************************************/
493 void vcg_open (ir_graph *irg, char *suffix) {
494 char *fname; /* filename to put the vcg information in */
499 /** open file for vcg graph */
500 id = get_entity_ld_name (get_irg_ent(irg));
501 len = id_to_strlen (id);
503 fname = malloc (len + 5 + strlen(suffix));
504 strcpy (fname, cp); /* copy the filename */
505 strcat (fname, suffix); /* append file suffix */
506 strcat (fname, ".vcg"); /* append the .vcg suffix */
507 F = fopen (fname, "w"); /* open file for writing */
509 panic ("cannot open %s for writing (%m)", fname); /* not reached */
514 "graph: { title: \"ir graph of %s\"\n"
515 "display_edge_labels: yes\n"
516 "layoutalgorithm: mindepth\n"
517 "manhattan_edges: yes\n"
519 "orientation: bottom_to_top\n"
520 "classname 1: \"Data\"\n"
521 "classname 2: \"Block\"\n", cp);
523 xfprintf (F, "\n"); /* a separator */
526 void vcg_open_name (const char *name) {
527 char *fname; /* filename to put the vcg information in */
530 /** open file for vcg graph */
532 fname = malloc (len + 5);
533 strcpy (fname, name); /* copy the filename */
534 strcat (fname, ".vcg"); /* append the .vcg suffix */
535 F = fopen (fname, "w"); /* open file for writing */
537 panic ("cannot open %s for writing (%m)", fname); /* not reached */
542 "graph: { title: \"ir graph of %s\"\n"
543 "display_edge_labels: yes\n"
544 "layoutalgorithm: mindepth\n"
545 "manhattan_edges: yes\n"
547 "orientation: bottom_to_top\n"
548 "classname 1: \"Data\"\n"
549 "classname 2: \"Block\"\n", name);
551 xfprintf (F, "\n"); /* a separator */
556 xfprintf (F, "}\n"); /* print footer */
557 fclose (F); /* close vcg file */
560 /************************************************************************/
561 /* routines to dump a graph, blocks as conventional nodes. */
562 /************************************************************************/
565 dump_whole_node (ir_node *n, void* env) {
567 dump_ir_block_edge(n);
568 dump_ir_data_edges(n);
572 dump_ir_graph (ir_graph *irg)
575 rem = current_ir_graph;
576 current_ir_graph = irg;
580 /* walk over the graph */
581 irg_walk(irg->end, dump_whole_node, NULL, NULL);
585 current_ir_graph = rem;
588 /***********************************************************************/
589 /* the following routines dump the nodes as attached to the blocks. */
590 /***********************************************************************/
593 dump_ir_blocks_nodes (ir_node *n, void *env) {
594 ir_node *block = (ir_node *)env;
596 if (is_no_Block(n) && get_nodes_Block(n) == block) {
598 dump_ir_data_edges(n);
603 dump_ir_block (ir_node *block, void *env) {
604 ir_graph *irg = (ir_graph *)env;
606 if (get_irn_opcode(block) == iro_Block) {
608 /* This is a block. So dump the vcg information to make a block. */
609 xfprintf(F, "graph: { title: \"%p\" label: \"", block);
611 xfprintf (F, "%ld", get_irn_node_nr(block));
613 xfprintf (F, "%I", block->op->name);
615 xfprintf(F, "\" status:clustered color:lightyellow \n");
616 /* dump the blocks edges */
617 dump_ir_data_edges(block);
619 /* dump the nodes that go into the block */
620 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
622 /* Close the vcg information for the block */
623 xfprintf(F, "}\n\n");
628 dump_ir_block_graph (ir_graph *irg)
631 rem = current_ir_graph;
632 current_ir_graph = irg;
636 /* walk over the blocks in the graph */
637 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
640 current_ir_graph = rem;
644 /***********************************************************************/
645 /* the following routines dump a control flow graph */
646 /***********************************************************************/
650 dump_block_to_cfg (ir_node *block, void *env) {
654 if (get_irn_opcode(block) == iro_Block) {
655 /* This is a block. Dump a node for the block. */
656 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
659 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
660 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
661 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" }\n",
668 dump_cfg (ir_graph *irg)
670 vcg_open (irg, "-cfg");
672 /* walk over the blocks in the graph */
673 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
679 /***********************************************************************/
680 /* the following routine dumps all type information reachable from an */
682 /***********************************************************************/
686 dump_type_graph (ir_graph *irg)
689 rem = current_ir_graph;
690 current_ir_graph = irg;
692 vcg_open (irg, "-type");
694 /* walk over the blocks in the graph */
695 type_walk_irg(irg, dump_type_info, NULL, NULL);
698 current_ir_graph = rem;
701 /***********************************************************************/
702 /* the following routine dumps all type information */
703 /***********************************************************************/
707 dump_all_types (void)
709 vcg_open_name ("All_types");
710 type_walk(dump_type_info, NULL, NULL);
714 /***********************************************************************/
715 /* dumps a graph with type information */
716 /***********************************************************************/
720 dump_ir_graph_w_types (ir_graph *irg)
723 rem = current_ir_graph;
724 current_ir_graph = irg;
726 vcg_open (irg, "-all");
728 /* dump common ir graph */
729 /* irg_block_walk(irg->end, dump_ir_block, NULL, irg); */
730 irg_walk(irg->end, dump_whole_node, NULL, NULL);
732 type_walk_irg(irg, dump_type_info, NULL, NULL);
733 /* dump edges from graph to type info */
734 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
737 current_ir_graph = rem;