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
15 # include "irnode_t.h"
16 # include "irgraph_t.h"
26 # include "type_or_entity.h"
28 # include "typewalk.h"
30 /* Attributes of nodes */
31 #define DEFAULT_NODE_ATTR ""
32 #define DEFAULT_TYPE_ATTRIBUTE ""
34 /* Attributes of edges between Firm nodes */
35 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
36 #define CF_EDGE_ATTR "color: red"
37 #define MEM_EDGE_ATTR "color: blue"
39 /* Attributes of edges between Firm nodes and type/entity nodes */
40 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
42 /* Attributes of edges in type/entity graphs. */
43 #define TYPE_METH_NODE_ATTR "color: lightyellow"
44 #define TYPE_CLASS_NODE_ATTR "color: green"
45 #define ENTITY_NODE_ATTR "color: yellow"
46 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
47 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
48 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
49 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
50 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
51 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
52 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
53 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
54 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
55 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
56 #define ENT_VALUE_EDGE_ATTR "label: \"value "
57 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
58 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
61 #if DEBUG_libfirm && NODEID_AS_LABEL
62 #define PRINT_NODEID(X) fprintf(F, "%d", get_irn_node_nr(X))
64 #define PRINT_NODEID(X) fprintf(F, "%p", X)
70 /* A compiler option to turn off edge labels */
72 /* A compiler option to turn off dumping values of constant entities */
73 int const_entities = 1;
74 /* A compiler option to dump the keep alive edges */
75 int dump_keepalive = 1;
77 /* A global variable to record output of the Bad node. */
81 void dump_ir_blocks_nodes (ir_node *n, void *env);
82 void dump_whole_node (ir_node *n, void* env);
84 /*******************************************************************/
85 /* routines to dump information about a single node */
86 /*******************************************************************/
91 dump_node_opcode (ir_node *n)
95 if (n->op->code == iro_Const) {
96 xfprintf (F, "%v", n->attr.con);
99 } else if (n->op->code == iro_SymConst) {
100 if (get_SymConst_kind(n) == linkage_ptr_info) {
101 xfprintf (F, "%I", get_SymConst_ptrinfo(n));
103 assert(get_kind(get_SymConst_type(n)) == k_type);
104 assert(get_type_ident(get_SymConst_type(n)));
105 xfprintf (F, "%s ", id_to_str(get_type_ident(get_SymConst_type(n))));
106 if (get_SymConst_kind == type_tag)
109 xfprintf (F, "size");
113 xfprintf (F, "%I", get_irn_opident(n));
118 dump_node_mode (ir_node *n)
120 switch (n->op->code) {
137 xfprintf (F, "%I", get_mode_ident(n->mode));
144 dump_node_nodeattr (ir_node *n)
146 switch (n->op->code) {
148 if (n->in[1]->op->code == iro_Cmp) {
149 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
151 xfprintf (F, "%ld", n->attr.proj);
155 assert(get_kind(get_Sel_entity(n)) == k_entity);
156 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
163 dump_node_vcgattr (ir_node *n)
165 switch (n->op->code) {
168 xfprintf (F, "color: blue");
171 xfprintf (F, "color: lightyellow");
174 xfprintf (F, "color: green");
179 xfprintf (F, "color: yellow");
182 xfprintf (F, DEFAULT_NODE_ATTR);
187 dump_node (ir_node *n) {
190 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
195 dump_node_nodeattr(n);
197 xfprintf (F, " %ld", get_irn_node_nr(n));
200 dump_node_vcgattr(n);
205 dump_ir_node (ir_node *n)
208 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
210 switch (n->op->code) { /* node label */
212 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
213 xfprintf (F, DEFAULT_NODE_ATTR);
216 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
217 xfprintf (F, DEFAULT_NODE_ATTR);
220 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
221 xfprintf (F, DEFAULT_NODE_ATTR);
224 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
225 if (get_irn_modecode(n) == irm_M)
226 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
228 xfprintf (F, DEFAULT_NODE_ATTR);
231 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
232 xfprintf (F, DEFAULT_NODE_ATTR);
235 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
236 xfprintf (F, DEFAULT_NODE_ATTR);
239 if (n->in[1]->op->code == iro_Cmp) {
240 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
241 get_pnc_string(n->attr.proj));
243 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
245 xfprintf (F, DEFAULT_NODE_ATTR);
248 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
249 xfprintf (F, DEFAULT_NODE_ATTR);
252 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
253 xfprintf (F, DEFAULT_NODE_ATTR);
256 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
257 xfprintf (F, DEFAULT_NODE_ATTR);
260 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
261 xfprintf (F, DEFAULT_NODE_ATTR);
264 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
265 xfprintf (F, DEFAULT_NODE_ATTR);
268 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
269 xfprintf (F, DEFAULT_NODE_ATTR);
272 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
273 xfprintf (F, DEFAULT_NODE_ATTR);
276 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
277 xfprintf (F, DEFAULT_NODE_ATTR);
280 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
281 xfprintf (F, DEFAULT_NODE_ATTR);
284 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
285 xfprintf (F, DEFAULT_NODE_ATTR);
288 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
289 xfprintf (F, DEFAULT_NODE_ATTR);
292 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
293 xfprintf (F, DEFAULT_NODE_ATTR);
296 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
297 xfprintf (F, DEFAULT_NODE_ATTR);
300 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
301 xfprintf (F, DEFAULT_NODE_ATTR);
304 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
305 xfprintf (F, DEFAULT_NODE_ATTR);
308 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
309 xfprintf (F, DEFAULT_NODE_ATTR);
312 xfprintf (F, "\"%I\"", get_irn_opident(n));
313 xfprintf (F, DEFAULT_NODE_ATTR);
316 xfprintf (F, "\"%I\"", get_irn_opident(n));
317 xfprintf (F, DEFAULT_NODE_ATTR);
320 xfprintf (F, "\"%I\"", get_irn_opident(n));
321 xfprintf (F, DEFAULT_NODE_ATTR);
324 xfprintf (F, "\"%I\"", get_irn_opident(n));
325 xfprintf (F, DEFAULT_NODE_ATTR);
328 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
329 xfprintf (F, DEFAULT_NODE_ATTR);
333 xfprintf (F, "\"%R\"", n);
334 xfprintf (F, DEFAULT_NODE_ATTR);
337 xfprintf (F, "\"%I\" ", get_irn_opident(n));
338 xfprintf (F, DEFAULT_NODE_ATTR);
341 assert(get_kind(get_Sel_entity(n)) == k_entity);
342 xfprintf (F, "\"%I ", get_irn_opident(n));
343 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
344 xfprintf (F, DEFAULT_NODE_ATTR);
347 assert(get_kind(get_SymConst_type(n)) == k_type);
348 assert(get_type_ident(get_SymConst_type(n)));
349 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
350 switch (n->attr.i.num){
352 xfprintf (F, "tag\" ");
355 xfprintf (F, "size\" ");
361 xfprintf (F, DEFAULT_NODE_ATTR);
364 xfprintf (F, "\"%I\" ", get_irn_opident(n));
365 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
368 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
369 xfprintf (F, DEFAULT_NODE_ATTR);
372 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
374 xfprintf (F, "}\n"); /* footer */
378 /* dump the edge to the block this node belongs to */
380 dump_ir_block_edge(ir_node *n) {
381 if (is_no_Block(n)) {
382 xfprintf (F, "edge: { sourcename: \"");
384 xfprintf (F, "\" targetname: \"");
385 PRINT_NODEID(get_nodes_Block(n));
386 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
390 void print_edge_vcgattr(ir_node *from, int to) {
393 switch (get_irn_opcode(from)) {
395 xfprintf (F, CF_EDGE_ATTR);
397 case iro_Start: break;
400 case iro_Cond: break;
403 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
405 case iro_Const: break;
406 case iro_SymConst:break;
409 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
413 case iro_Minus: break;
419 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
427 case iro_Shrs: break;
430 case iro_Conv: break;
432 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
438 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
441 xfprintf (F, MEM_EDGE_ATTR);
443 case iro_Tuple: break;
445 switch (get_irn_modecode(from)) {
447 xfprintf (F, CF_EDGE_ATTR);
450 xfprintf (F, MEM_EDGE_ATTR);
461 /* dump edges to our inputs */
463 dump_ir_data_edges(ir_node *n) {
466 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
469 for (i = 0; i < get_irn_arity(n); i++) {
470 assert(get_irn_n(n, i));
471 fprintf (F, "edge: {sourcename: \"");
473 fprintf (F, "\" targetname: \"");
474 PRINT_NODEID(get_irn_n(n, i));
476 fprintf (F, " label: \"%d\" ", i);
477 print_edge_vcgattr(n, i);
482 /* dumps the edges between nodes and their type or entity attributes. */
483 void dump_node2type_edges (ir_node *n, void *env)
487 switch (get_irn_opcode(n)) {
489 /* @@@ some consts have an entity */
492 if ( (get_SymConst_kind(n) == type_tag)
493 || (get_SymConst_kind(n) == size)) {
494 xfprintf (F, "edge: { sourcename: \"");
496 fprintf (F, "\" targetname: \"%p\" "
497 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
501 xfprintf (F, "edge: { sourcename: \"");
503 fprintf (F, "\" targetname: \"%p\" "
504 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
507 xfprintf (F, "edge: { sourcename: \"");
509 fprintf (F, "\" targetname: \"%p\" "
510 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
513 xfprintf (F, "edge: { sourcename: \"");
515 fprintf (F, "\" targetname: \"%p\" "
516 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
519 xfprintf (F, "edge: { sourcename: \"");
521 fprintf (F, "\" targetname: \"%p\" "
522 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
530 void dump_const_expression(ir_node *value) {
531 ir_graph *rem = current_ir_graph;
532 current_ir_graph = get_const_code_irg();
533 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
534 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
535 current_ir_graph = rem;
539 void print_type_info(type *tp) {
540 if (get_type_state(tp) == layout_undefined) {
541 xfprintf(F, "state: layout_undefined\n");
543 xfprintf(F, "state: layout_fixed,\n");
545 if (get_type_mode(tp))
546 xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
547 xfprintf(F, "size: %dB,\n", get_type_size(tp));
551 void print_typespecific_info(type *tp) {
552 switch (get_type_tpop_code(tp)) {
555 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
559 xfprintf (F, " " TYPE_METH_NODE_ATTR);
570 case tpo_enumeration:
583 void print_type_node(type *tp) {
584 xfprintf (F, "node: {title: \"%p\" ", tp);
585 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
586 xfprintf (F, "info1: \"");
589 print_typespecific_info(tp);
593 /* dumps a type or entity and it's edges. */
595 dump_type_info (type_or_ent *tore, void *env) {
596 int i = 0; /* to shutup gcc */
598 /* dump this type or entity */
600 switch (get_kind(tore)) {
603 entity *ent = (entity *)tore;
606 xfprintf (F, "node: {title: \"%p\" ", tore);
607 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
608 xfprintf (F, "label: ");
609 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
610 if(dynamic_allocated == get_entity_allocation(ent))
611 xfprintf (F, " info1:\"dynamic allocated\n");
613 xfprintf (F, " info1:\"static allocated\n");
614 switch (get_entity_visibility(ent)) {
615 case local: fprintf (F, "local\n"); break;
616 case external_visible: fprintf (F, "external_visible\n"); break;
617 case external_allocated: fprintf (F, "external_allocate\nd");break;
619 switch (get_entity_variability(ent)) {
620 case uninitialized: fprintf (F, "uninitialized");break;
621 case initialized: fprintf (F, "initialized"); break;
622 case part_constant: fprintf (F, "part_constant");break;
623 case constant: fprintf (F, "constant"); break;
625 xfprintf(F, "\"}\n");
627 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
628 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));
629 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
630 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
631 for(i = 0; i < get_entity_n_overwrites(ent); i++)
632 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
633 ENT_OVERWRITES_EDGE_ATTR "}\n", ent, get_entity_overwrites(ent, i));
634 /* attached subgraphs */
635 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
636 if (is_atomic_entity(ent)) {
637 value = get_atomic_ent_value(ent);
638 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
640 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
641 dump_const_expression(value);
643 if (is_compound_entity(ent)) {
644 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
645 value = get_compound_ent_value(ent, i);
646 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
648 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
649 dump_const_expression(value);
650 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
651 ENT_CORR_EDGE_ATTR "}\n", ent,
652 get_compound_ent_value_member(ent, i), i);
659 type *tp = (type *)tore;
661 /* and now the edges */
662 switch (get_type_tpop_code(tp)) {
665 for (i=0; i < get_class_n_supertype(tp); i++)
666 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
667 TYPE_SUPER_EDGE_ATTR "}\n",
668 tp, get_class_supertype(tp, i));
669 for (i=0; i < get_class_n_member(tp); i++)
670 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
671 TYPE_MEMBER_EDGE_ATTR "}\n",
672 tp, get_class_member(tp, i));
676 for (i=0; i < get_struct_n_member(tp); i++)
677 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
678 TYPE_MEMBER_EDGE_ATTR "}\n",
679 tp, get_struct_member(tp, i));
683 for (i = 0; i < get_method_n_params(tp); i++)
684 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
685 METH_PAR_EDGE_ATTR "}\n",
686 tp, get_method_param_type(tp, i), i);
687 for (i = 0; i < get_method_n_res(tp); i++)
688 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
689 METH_RES_EDGE_ATTR "}\n",
690 tp, get_method_res_type(tp, i), i);
694 for (i = 0; i < get_union_n_members(tp); i++)
695 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
696 "label: \"\"f" UNION_EDGE_ATTR "}\n",
697 tp, get_union_member(tp, i));
701 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
702 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
703 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
704 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
706 case tpo_enumeration:
711 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
712 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
713 get_pointer_points_to_type(tp), i);
721 break; /* case k_type */
724 printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
726 } /* switch kind_or_entity */
729 /************************************************************************/
730 /* open and close vcg file */
731 /************************************************************************/
733 void vcg_open (ir_graph *irg, char *suffix) {
734 char *fname; /* filename to put the vcg information in */
741 /** open file for vcg graph */
742 ent = get_irg_ent(irg);
743 id = get_entity_ld_ident (ent);
744 len = id_to_strlen (id);
746 fname = malloc (len + 5 + strlen(suffix));
747 strncpy (fname, cp, len); /* copy the filename */
749 strcat (fname, suffix); /* append file suffix */
751 fname = malloc (len + 5 + strlen(suffix));
752 strncpy (fname, cp, len); /* copy the filename */
753 fname[len] = '\0'; /* ensure string termination */
754 /*strcpy (fname, cp); * copy the filename *
755 this produces wrong, too long strings in conjuction with the
756 jocca frontend. The \0 seems to be missing. */
757 strcat (fname, suffix); /* append file suffix */
758 strcat (fname, ".vcg"); /* append the .vcg suffix */
759 F = fopen (fname, "w"); /* open file for writing */
761 panic ("cannot open %s for writing (%m)", fname); /* not reached */
765 strcpy(label, "yes");
767 strcpy (label, "no");
772 "graph: { title: \"ir graph of %s\"\n"
773 "display_edge_labels: %s\n"
774 "layoutalgorithm: mindepth\n"
775 "manhattan_edges: yes\n"
777 "orientation: bottom_to_top\n"
778 "classname 1: \"Data\"\n"
779 "classname 2: \"Block\"\n"
780 "classname 3: \"Entity type\""
781 "classname 4: \"Entity owner\""
782 "classname 5: \"Method Param\""
783 "classname 6: \"Method Res\""
784 "classname 7: \"Super\""
785 "classname 8: \"Union\""
786 "classname 9: \"Points-to\""
787 "classname 10: \"Array Element Type\""
788 "classname 11: \"Overwrites\""
789 "classname 12: \"Member\""
792 xfprintf (F, "\n"); /* a separator */
795 void vcg_open_name (const char *name) {
796 char *fname; /* filename to put the vcg information in */
800 /** open file for vcg graph */
802 fname = malloc (len + 5);
803 strcpy (fname, name); /* copy the filename */
804 strcat (fname, ".vcg"); /* append the .vcg suffix */
805 F = fopen (fname, "w"); /* open file for writing */
807 panic ("cannot open %s for writing (%m)", fname); /* not reached */
811 strcpy(label, "yes");
813 strcpy (label, "no");
818 "graph: { title: \"ir graph of %s\"\n"
819 "display_edge_labels: %s\n"
820 "layoutalgorithm: mindepth\n"
821 "manhattan_edges: yes\n"
823 "orientation: bottom_to_top\n"
824 "classname 1: \"Data\"\n"
825 "classname 2: \"Block\"\n"
826 "classname 3: \"Entity type\"\n"
827 "classname 4: \"Entity owner\"\n"
828 "classname 5: \"Method Param\"\n"
829 "classname 6: \"Method Res\"\n"
830 "classname 7: \"Super\"\n"
831 "classname 8: \"Union\"\n"
832 "classname 9: \"Points-to\"\n"
833 "classname 10: \"Array Element Type\"\n"
834 "classname 11: \"Overwrites\"\n"
835 "classname 12: \"Member\"\n"
838 xfprintf (F, "\n"); /* a separator */
843 xfprintf (F, "}\n"); /* print footer */
844 fclose (F); /* close vcg file */
847 /************************************************************************/
848 /* routines to dump a graph, blocks as conventional nodes. */
849 /************************************************************************/
852 dump_whole_node (ir_node *n, void* env) {
854 dump_ir_block_edge(n);
855 dump_ir_data_edges(n);
859 dump_ir_graph (ir_graph *irg)
862 rem = current_ir_graph;
863 current_ir_graph = irg;
867 /* walk over the graph */
868 irg_walk(irg->end, dump_whole_node, NULL, NULL);
872 current_ir_graph = rem;
875 /***********************************************************************/
876 /* the following routines dump the nodes as attached to the blocks. */
877 /***********************************************************************/
880 dump_ir_blocks_nodes (ir_node *n, void *env) {
881 ir_node *block = (ir_node *)env;
883 if (is_no_Block(n) && get_nodes_Block(n) == block) {
885 dump_ir_data_edges(n);
887 if (get_irn_op(n) == op_Bad)
892 dump_ir_block (ir_node *block, void *env) {
893 ir_graph *irg = (ir_graph *)env;
895 if (get_irn_opcode(block) == iro_Block) {
897 /* This is a block. So dump the vcg information to make a block. */
898 xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \"");
900 xfprintf (F, "%ld", get_irn_node_nr(block));
902 xfprintf (F, "%I", block->op->name);
904 xfprintf(F, "\" status:clustered color:lightyellow \n");
905 /* dump the blocks edges */
906 dump_ir_data_edges(block);
908 /* dump the nodes that go into the block */
909 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
911 /* Close the vcg information for the block */
912 xfprintf(F, "}\n\n");
918 dump_blockless_nodes (ir_node *n, void *env) {
919 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
921 dump_ir_data_edges(n);
922 dump_ir_block_edge(n);
924 if (get_irn_op(n) == op_Bad)
928 void dump_ir_block_graph_2 (ir_graph *irg)
931 /* walk over the blocks in the graph */
932 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
934 /* dump all nodes that are not in a Block */
935 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
937 /* dump the Bad node */
939 dump_node(get_irg_bad(irg));
943 dump_ir_block_graph (ir_graph *irg)
946 rem = current_ir_graph;
947 current_ir_graph = irg;
951 dump_ir_block_graph_2 (irg);
954 current_ir_graph = rem;
958 /***********************************************************************/
959 /* the following routines dump a control flow graph */
960 /***********************************************************************/
964 dump_block_to_cfg (ir_node *block, void *env) {
968 if (get_irn_opcode(block) == iro_Block) {
969 /* This is a block. Dump a node for the block. */
970 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
973 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
974 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
975 xfprintf (F, "edge: { sourcename: \"");
977 fprintf (F, "\" targetname: \"");
979 fprintf (F, "\" }\n");
985 dump_cfg (ir_graph *irg)
987 vcg_open (irg, "-cfg");
989 /* walk over the blocks in the graph */
990 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
996 /***********************************************************************/
997 /* the following routine dumps all type information reachable from an */
999 /***********************************************************************/
1003 dump_type_graph (ir_graph *irg)
1006 rem = current_ir_graph;
1007 current_ir_graph = irg;
1009 vcg_open (irg, "-type");
1011 /* walk over the blocks in the graph */
1012 type_walk_irg(irg, dump_type_info, NULL, NULL);
1013 /* The walker for the const code can be called several times for the
1014 same (sub) experssion. So that no nodes are dumped several times
1015 we decrease the visited flag of the corresponding graph after each
1016 walk. So now increase it finally. */
1017 inc_irg_visited(get_const_code_irg());
1020 current_ir_graph = rem;
1023 /***********************************************************************/
1024 /* the following routine dumps all type information */
1025 /***********************************************************************/
1029 dump_all_types (void)
1031 vcg_open_name ("All_types");
1032 type_walk(dump_type_info, NULL, NULL);
1033 inc_irg_visited(get_const_code_irg());
1037 /***********************************************************************/
1038 /* dumps a graph with type information */
1039 /***********************************************************************/
1043 dump_ir_graph_w_types (ir_graph *irg)
1046 rem = current_ir_graph;
1047 current_ir_graph = irg;
1049 vcg_open (irg, "-all");
1051 /* dump common ir graph */
1052 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1053 /* dump type info */
1054 type_walk_irg(irg, dump_type_info, NULL, NULL);
1055 inc_irg_visited(get_const_code_irg());
1056 /* dump edges from graph to type info */
1057 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1060 current_ir_graph = rem;
1064 dump_ir_block_graph_w_types (ir_graph *irg)
1067 rem = current_ir_graph;
1068 current_ir_graph = irg;
1070 vcg_open (irg, "-all");
1072 /* dump common blocked ir graph */
1073 dump_ir_block_graph_2(irg);
1074 /* dump type info */
1075 type_walk_irg(irg, dump_type_info, NULL, NULL);
1076 inc_irg_visited(get_const_code_irg());
1077 /* dump edges from graph to type info */
1078 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1081 current_ir_graph = rem;
1084 /***********************************************************************/
1085 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1087 /* dump_ir_block_graph */
1089 /* dump_type_graph */
1090 /* dump_ir_graph_w_types */
1091 /***********************************************************************/
1092 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1094 for (i=0; i < get_irp_n_irgs(); i++) {
1095 dump_graph(get_irp_irg(i));
1100 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1101 abort with a segmentation fault. */
1102 void turn_of_edge_labels() {
1106 void dump_constant_entity_values() {
1110 void dump_keepalive_edges() {