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"
21 # include "entity_t.h"
26 # include "type_or_entity.h"
28 # include "typewalk.h"
31 # include "common_t.h"
33 /* Attributes of nodes */
34 #define DEFAULT_NODE_ATTR ""
35 #define DEFAULT_TYPE_ATTRIBUTE ""
37 /* Attributes of edges between Firm nodes */
38 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
39 #define CF_EDGE_ATTR "color: red"
40 #define MEM_EDGE_ATTR "color: blue"
41 #define DOMINATOR_EDGE_ATTR "color: red"
43 /* Attributes of edges between Firm nodes and type/entity nodes */
44 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
46 /* Attributes of edges in type/entity graphs. */
47 #define TYPE_METH_NODE_ATTR "color: lightyellow"
48 #define TYPE_CLASS_NODE_ATTR "color: green"
49 #define ENTITY_NODE_ATTR "color: yellow"
50 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
51 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
52 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
53 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
54 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
55 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
56 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
57 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
58 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
59 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
60 #define ENT_VALUE_EDGE_ATTR "label: \"value "
61 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
62 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
65 #if DEBUG_libfirm && NODEID_AS_LABEL
66 #define PRINT_NODEID(X) fprintf(F, "%d", get_irn_node_nr(X))
68 #define PRINT_NODEID(X) fprintf(F, "%p", X)
71 /* A suffix to manipulate the file name. */
72 char *dump_file_suffix = NULL;
77 /* A compiler option to turn off edge labels */
79 /* A compiler option to turn off dumping values of constant entities */
80 int const_entities = 1;
81 /* A compiler option to dump the keep alive edges */
82 int dump_keepalive = 0;
83 /* A compiler option to dump the out edges in dump_ir_graph */
84 int dump_out_edge_flag = 0;
85 int dump_dominator_information_flag = 0;
87 /* A global variable to record output of the Bad node. */
91 void dump_ir_blocks_nodes (ir_node *n, void *env);
92 void dump_whole_node (ir_node *n, void* env);
94 /*******************************************************************/
95 /* routines to dump information about a single node */
96 /*******************************************************************/
101 dump_node_opcode (ir_node *n)
105 if (n->op->code == iro_Const) {
106 xfprintf (F, "%v", n->attr.con);
109 } else if (n->op->code == iro_SymConst) {
110 if (get_SymConst_kind(n) == linkage_ptr_info) {
111 /* don't use get_SymConst_ptr_info as it mangles the name. */
112 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
114 assert(get_kind(get_SymConst_type(n)) == k_type);
115 assert(get_type_ident(get_SymConst_type(n)));
116 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
117 if (get_SymConst_kind == type_tag)
120 xfprintf (F, "size");
124 xfprintf (F, "%I", get_irn_opident(n));
129 dump_node_mode (ir_node *n)
131 switch (n->op->code) {
148 xfprintf (F, "%I", get_mode_ident(n->mode));
155 dump_node_nodeattr (ir_node *n)
157 switch (n->op->code) {
159 if (n->in[1]->op->code == iro_Cmp) {
160 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
162 xfprintf (F, "%ld", n->attr.proj);
166 assert(get_kind(get_Sel_entity(n)) == k_entity);
167 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
174 dump_node_vcgattr (ir_node *n)
176 switch (n->op->code) {
179 xfprintf (F, "color: blue");
182 xfprintf (F, "color: lightyellow");
185 xfprintf (F, "color: green");
190 xfprintf (F, "color: yellow");
193 xfprintf (F, DEFAULT_NODE_ATTR);
198 dump_node (ir_node *n) {
201 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
206 dump_node_nodeattr(n);
208 xfprintf (F, " %ld", get_irn_node_nr(n));
211 dump_node_vcgattr(n);
216 dump_ir_node (ir_node *n)
219 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
221 switch (n->op->code) { /* node label */
223 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
224 xfprintf (F, DEFAULT_NODE_ATTR);
227 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
228 xfprintf (F, DEFAULT_NODE_ATTR);
231 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
232 xfprintf (F, DEFAULT_NODE_ATTR);
235 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
236 if (get_irn_modecode(n) == irm_M)
237 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
239 xfprintf (F, DEFAULT_NODE_ATTR);
242 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
243 xfprintf (F, DEFAULT_NODE_ATTR);
246 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
247 xfprintf (F, DEFAULT_NODE_ATTR);
250 if (n->in[1]->op->code == iro_Cmp) {
251 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
252 get_pnc_string(n->attr.proj));
254 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
256 xfprintf (F, DEFAULT_NODE_ATTR);
259 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
260 xfprintf (F, DEFAULT_NODE_ATTR);
263 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
264 xfprintf (F, DEFAULT_NODE_ATTR);
267 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
268 xfprintf (F, DEFAULT_NODE_ATTR);
271 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
272 xfprintf (F, DEFAULT_NODE_ATTR);
275 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
276 xfprintf (F, DEFAULT_NODE_ATTR);
279 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
280 xfprintf (F, DEFAULT_NODE_ATTR);
283 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
284 xfprintf (F, DEFAULT_NODE_ATTR);
287 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
288 xfprintf (F, DEFAULT_NODE_ATTR);
291 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
292 xfprintf (F, DEFAULT_NODE_ATTR);
295 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
296 xfprintf (F, DEFAULT_NODE_ATTR);
299 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
300 xfprintf (F, DEFAULT_NODE_ATTR);
303 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
304 xfprintf (F, DEFAULT_NODE_ATTR);
307 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
308 xfprintf (F, DEFAULT_NODE_ATTR);
311 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
312 xfprintf (F, DEFAULT_NODE_ATTR);
315 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
316 xfprintf (F, DEFAULT_NODE_ATTR);
319 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
320 xfprintf (F, DEFAULT_NODE_ATTR);
323 xfprintf (F, "\"%I\"", get_irn_opident(n));
324 xfprintf (F, DEFAULT_NODE_ATTR);
327 xfprintf (F, "\"%I\"", get_irn_opident(n));
328 xfprintf (F, DEFAULT_NODE_ATTR);
331 xfprintf (F, "\"%I\"", get_irn_opident(n));
332 xfprintf (F, DEFAULT_NODE_ATTR);
335 xfprintf (F, "\"%I\"", get_irn_opident(n));
336 xfprintf (F, DEFAULT_NODE_ATTR);
339 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
340 xfprintf (F, DEFAULT_NODE_ATTR);
344 xfprintf (F, "\"%R\"", n);
345 xfprintf (F, DEFAULT_NODE_ATTR);
348 xfprintf (F, "\"%I\" ", get_irn_opident(n));
349 xfprintf (F, DEFAULT_NODE_ATTR);
352 assert(get_kind(get_Sel_entity(n)) == k_entity);
353 xfprintf (F, "\"%I ", get_irn_opident(n));
354 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
355 xfprintf (F, DEFAULT_NODE_ATTR);
358 assert(get_kind(get_SymConst_type(n)) == k_type);
359 assert(get_type_ident(get_SymConst_type(n)));
360 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
361 switch (n->attr.i.num){
363 xfprintf (F, "tag\" ");
366 xfprintf (F, "size\" ");
372 xfprintf (F, DEFAULT_NODE_ATTR);
375 xfprintf (F, "\"%I\" ", get_irn_opident(n));
376 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
379 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
380 xfprintf (F, DEFAULT_NODE_ATTR);
383 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
385 xfprintf (F, "}\n"); /* footer */
389 /* dump the edge to the block this node belongs to */
391 dump_ir_block_edge(ir_node *n) {
392 if (is_no_Block(n)) {
393 xfprintf (F, "edge: { sourcename: \"");
395 xfprintf (F, "\" targetname: \"");
396 PRINT_NODEID(get_nodes_Block(n));
397 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
401 void print_edge_vcgattr(ir_node *from, int to) {
404 switch (get_irn_opcode(from)) {
406 xfprintf (F, CF_EDGE_ATTR);
408 case iro_Start: break;
411 if (get_irn_mode(get_End_keepalive(from, to)) == mode_R)
412 xfprintf (F, CF_EDGE_ATTR);
413 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
414 xfprintf (F, MEM_EDGE_ATTR);
418 case iro_Cond: break;
421 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
423 case iro_Const: break;
424 case iro_SymConst:break;
427 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
431 case iro_Minus: break;
437 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
445 case iro_Shrs: break;
448 case iro_Conv: break;
450 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
456 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
459 xfprintf (F, MEM_EDGE_ATTR);
461 case iro_Tuple: break;
463 switch (get_irn_modecode(from)) {
465 xfprintf (F, CF_EDGE_ATTR);
468 xfprintf (F, MEM_EDGE_ATTR);
479 /* dump edges to our inputs */
481 dump_ir_data_edges(ir_node *n) {
484 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
487 for (i = 0; i < get_irn_arity(n); i++) {
488 assert(get_irn_n(n, i));
489 fprintf (F, "edge: {sourcename: \"");
491 fprintf (F, "\" targetname: \"");
492 PRINT_NODEID(get_irn_n(n, i));
494 fprintf (F, " label: \"%d\" ", i);
495 print_edge_vcgattr(n, i);
502 dump_out_edge (ir_node *n, void* env) {
504 for (i = 0; i < get_irn_n_outs(n); i++) {
505 assert(get_irn_out(n, i));
506 fprintf (F, "edge: {sourcename: \"");
508 fprintf (F, "\" targetname: \"");
509 PRINT_NODEID(get_irn_out(n, i));
510 fprintf (F, "\" color: red linestyle: dashed");
516 /* dumps the edges between nodes and their type or entity attributes. */
517 void dump_node2type_edges (ir_node *n, void *env)
521 switch (get_irn_opcode(n)) {
523 /* @@@ some consts have an entity */
526 if ( (get_SymConst_kind(n) == type_tag)
527 || (get_SymConst_kind(n) == size)) {
528 xfprintf (F, "edge: { sourcename: \"");
530 fprintf (F, "\" targetname: \"%p\" "
531 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
535 xfprintf (F, "edge: { sourcename: \"");
537 fprintf (F, "\" targetname: \"%p\" "
538 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
541 xfprintf (F, "edge: { sourcename: \"");
543 fprintf (F, "\" targetname: \"%p\" "
544 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
547 xfprintf (F, "edge: { sourcename: \"");
549 fprintf (F, "\" targetname: \"%p\" "
550 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
553 xfprintf (F, "edge: { sourcename: \"");
555 fprintf (F, "\" targetname: \"%p\" "
556 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
564 void dump_const_expression(ir_node *value) {
565 ir_graph *rem = current_ir_graph;
566 current_ir_graph = get_const_code_irg();
567 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
568 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
569 current_ir_graph = rem;
573 void print_type_info(type *tp) {
574 if (get_type_state(tp) == layout_undefined) {
575 xfprintf(F, "state: layout_undefined\n");
577 xfprintf(F, "state: layout_fixed,\n");
579 if (get_type_mode(tp))
580 xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
581 xfprintf(F, "size: %dB,\n", get_type_size(tp));
585 void print_typespecific_info(type *tp) {
586 switch (get_type_tpop_code(tp)) {
589 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
593 xfprintf (F, " " TYPE_METH_NODE_ATTR);
604 case tpo_enumeration:
617 void print_type_node(type *tp) {
618 xfprintf (F, "node: {title: \"%p\" ", tp);
619 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
620 xfprintf (F, "info1: \"");
623 print_typespecific_info(tp);
627 /* dumps a type or entity and it's edges. */
629 dump_type_info (type_or_ent *tore, void *env) {
630 int i = 0; /* to shutup gcc */
632 /* dump this type or entity */
634 switch (get_kind(tore)) {
637 entity *ent = (entity *)tore;
640 xfprintf (F, "node: {title: \"%p\" ", tore);
641 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
642 xfprintf (F, "label: ");
643 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
644 if(dynamic_allocated == get_entity_allocation(ent))
645 xfprintf (F, " info1:\"dynamic allocated\n");
647 xfprintf (F, " info1:\"static allocated\n");
648 switch (get_entity_visibility(ent)) {
649 case local: fprintf (F, "local\n"); break;
650 case external_visible: fprintf (F, "external_visible\n"); break;
651 case external_allocated: fprintf (F, "external_allocate\n");break;
653 switch (get_entity_variability(ent)) {
654 case uninitialized: fprintf (F, "uninitialized");break;
655 case initialized: fprintf (F, "initialized"); break;
656 case part_constant: fprintf (F, "part_constant");break;
657 case constant: fprintf (F, "constant"); break;
659 if (is_method_type(get_entity_type(ent)))
660 xfprintf (F, "\n irg = %p ", get_entity_irg(ent));
661 xfprintf(F, "\"}\n");
663 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
664 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
665 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
666 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
667 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
668 for(i = 0; i < get_entity_n_overwrites(ent); i++)
669 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
670 ENT_OVERWRITES_EDGE_ATTR "}\n", ent, get_entity_overwrites(ent, i));
671 /* attached subgraphs */
672 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
673 if (is_atomic_entity(ent)) {
674 value = get_atomic_ent_value(ent);
675 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
677 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
678 dump_const_expression(value);
680 if (is_compound_entity(ent)) {
681 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
682 value = get_compound_ent_value(ent, i);
683 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
685 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
686 dump_const_expression(value);
687 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
688 ENT_CORR_EDGE_ATTR "}\n", ent,
689 get_compound_ent_value_member(ent, i), i);
696 type *tp = (type *)tore;
698 /* and now the edges */
699 switch (get_type_tpop_code(tp)) {
702 for (i=0; i < get_class_n_supertype(tp); i++)
703 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
704 TYPE_SUPER_EDGE_ATTR "}\n",
705 tp, get_class_supertype(tp, i));
706 for (i=0; i < get_class_n_member(tp); i++)
707 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
708 TYPE_MEMBER_EDGE_ATTR "}\n",
709 tp, get_class_member(tp, i));
713 for (i=0; i < get_struct_n_member(tp); i++)
714 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
715 TYPE_MEMBER_EDGE_ATTR "}\n",
716 tp, get_struct_member(tp, i));
720 for (i = 0; i < get_method_n_params(tp); i++)
721 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
722 METH_PAR_EDGE_ATTR "}\n",
723 tp, get_method_param_type(tp, i), i);
724 for (i = 0; i < get_method_n_res(tp); i++)
725 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
726 METH_RES_EDGE_ATTR "}\n",
727 tp, get_method_res_type(tp, i), i);
731 for (i = 0; i < get_union_n_members(tp); i++)
732 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
733 "label: \"\"f" UNION_EDGE_ATTR "}\n",
734 tp, get_union_member(tp, i));
738 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
739 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
740 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
741 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
743 case tpo_enumeration:
748 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
749 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
750 get_pointer_points_to_type(tp), i);
758 break; /* case k_type */
761 printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
763 } /* switch kind_or_entity */
766 /************************************************************************/
767 /* open and close vcg file */
768 /************************************************************************/
770 void vcg_open (ir_graph *irg, char *suffix) {
771 char *fname; /* filename to put the vcg information in */
778 /** open file for vcg graph */
779 ent = get_irg_ent(irg);
780 id = ent->ld_name ? ent->ld_name : ent->name;
781 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
782 len = id_to_strlen (id);
784 if (dump_file_suffix)
785 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
787 fname = malloc (len + 5 + strlen(suffix));
788 strncpy (fname, cp, len); /* copy the filename */
790 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
791 strcat (fname, suffix); /* append file suffix */
792 strcat (fname, ".vcg"); /* append the .vcg suffix */
793 F = fopen (fname, "w"); /* open file for writing */
795 panic ("cannot open %s for writing (%m)", fname); /* not reached */
799 strcpy(label, "yes");
801 strcpy (label, "no");
806 "graph: { title: \"ir graph of %s\"\n"
807 "display_edge_labels: %s\n"
808 "layoutalgorithm: mindepth\n"
809 "manhattan_edges: yes\n"
811 "orientation: bottom_to_top\n"
812 "classname 1: \"Data\"\n"
813 "classname 2: \"Block\"\n"
814 "classname 3: \"Entity type\""
815 "classname 4: \"Entity owner\""
816 "classname 5: \"Method Param\""
817 "classname 6: \"Method Res\""
818 "classname 7: \"Super\""
819 "classname 8: \"Union\""
820 "classname 9: \"Points-to\""
821 "classname 10: \"Array Element Type\""
822 "classname 11: \"Overwrites\""
823 "classname 12: \"Member\""
826 xfprintf (F, "\n"); /* a separator */
829 void vcg_open_name (const char *name) {
830 char *fname; /* filename to put the vcg information in */
834 /** open file for vcg graph */
836 fname = malloc (len + 5);
837 strcpy (fname, name); /* copy the filename */
838 strcat (fname, ".vcg"); /* append the .vcg suffix */
839 F = fopen (fname, "w"); /* open file for writing */
841 panic ("cannot open %s for writing (%m)", fname); /* not reached */
845 strcpy(label, "yes");
847 strcpy (label, "no");
852 "graph: { title: \"ir graph of %s\"\n"
853 "display_edge_labels: %s\n"
854 "layoutalgorithm: mindepth\n"
855 "manhattan_edges: yes\n"
857 "orientation: bottom_to_top\n"
858 "classname 1: \"Data\"\n"
859 "classname 2: \"Block\"\n"
860 "classname 3: \"Entity type\"\n"
861 "classname 4: \"Entity owner\"\n"
862 "classname 5: \"Method Param\"\n"
863 "classname 6: \"Method Res\"\n"
864 "classname 7: \"Super\"\n"
865 "classname 8: \"Union\"\n"
866 "classname 9: \"Points-to\"\n"
867 "classname 10: \"Array Element Type\"\n"
868 "classname 11: \"Overwrites\"\n"
869 "classname 12: \"Member\"\n"
872 xfprintf (F, "\n"); /* a separator */
877 xfprintf (F, "}\n"); /* print footer */
878 fclose (F); /* close vcg file */
881 /************************************************************************/
882 /* routines to dump a graph, blocks as conventional nodes. */
883 /************************************************************************/
886 dump_whole_node (ir_node *n, void* env) {
888 if (!node_floats(n)) dump_ir_block_edge(n);
889 dump_ir_data_edges(n);
893 dump_ir_graph (ir_graph *irg)
896 rem = current_ir_graph;
897 current_ir_graph = irg;
901 /* walk over the graph */
902 irg_walk(irg->end, dump_whole_node, NULL, NULL);
904 /* dump the out edges in a separate walk */
905 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
906 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
911 current_ir_graph = rem;
914 /***********************************************************************/
915 /* the following routines dump the nodes as attached to the blocks. */
916 /***********************************************************************/
918 int node_floats(ir_node *n) {
920 return ((get_op_pinned(get_irn_op(n)) == floats) &&
921 (get_irg_pinned(current_ir_graph) == floats));
925 dump_ir_blocks_nodes (ir_node *n, void *env) {
926 ir_node *block = (ir_node *)env;
928 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
930 dump_ir_data_edges(n);
932 if (get_irn_op(n) == op_Bad)
937 dump_ir_block (ir_node *block, void *env) {
938 ir_graph *irg = (ir_graph *)env;
940 if (get_irn_opcode(block) == iro_Block) {
942 /* This is a block. So dump the vcg information to make a block. */
943 xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \"");
945 xfprintf (F, "%ld", get_irn_node_nr(block));
947 xfprintf (F, "%I", block->op->name);
949 xfprintf(F, "\" status:clustered color:%s \n",
950 get_Block_matured (block) ? "yellow" : "red");
951 /* dump the blocks edges */
952 dump_ir_data_edges(block);
954 /* dump the nodes that go into the block */
955 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
957 /* Close the vcg information for the block */
958 xfprintf(F, "}\n\n");
964 dump_blockless_nodes (ir_node *n, void *env) {
965 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
967 dump_ir_data_edges(n);
968 dump_ir_block_edge(n);
969 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
972 if (node_floats(n)) {
974 dump_ir_data_edges(n);
975 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
979 void dump_ir_block_graph_2 (ir_graph *irg)
982 /* walk over the blocks in the graph */
983 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
985 /* dump all nodes that are not in a Block */
986 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
988 /* dump the Bad node */
990 dump_node(get_irg_bad(irg));
994 dump_ir_block_graph (ir_graph *irg)
997 rem = current_ir_graph;
998 current_ir_graph = irg;
1002 dump_ir_block_graph_2 (irg);
1005 current_ir_graph = rem;
1009 /***********************************************************************/
1010 /* the following routines dump a control flow graph */
1011 /***********************************************************************/
1015 dump_block_to_cfg (ir_node *block, void *env) {
1019 if (get_irn_opcode(block) == iro_Block) {
1020 /* This is a block. Dump a node for the block. */
1021 xfprintf (F, "node: {title:\""); PRINT_NODEID(block);
1022 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1023 xfprintf (F, "\" ");
1024 if (dump_dominator_information_flag)
1025 xfprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1026 xfprintf (F, "}\n");
1027 /* Dump the edges */
1028 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1029 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1030 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1031 xfprintf (F, "edge: { sourcename: \"");
1032 PRINT_NODEID(block);
1033 fprintf (F, "\" targetname: \"");
1035 fprintf (F, "\" }\n");
1038 /* Dump dominator edge */
1039 if (dump_dominator_information_flag && get_Block_idom(block)) {
1040 pred = get_Block_idom(block);
1041 xfprintf (F, "edge: { sourcename: \"");
1042 PRINT_NODEID(block);
1043 fprintf (F, "\" targetname: \"");
1045 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1051 dump_cfg (ir_graph *irg)
1053 ir_graph *rem = current_ir_graph;
1054 int ddif = dump_dominator_information_flag;
1055 current_ir_graph = irg;
1056 vcg_open (irg, "-cfg");
1058 if (get_irg_dom_state(irg) != dom_consistent)
1059 dump_dominator_information_flag = 0;
1061 /* walk over the blocks in the graph */
1062 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1063 dump_ir_node (irg->bad);
1065 dump_dominator_information_flag = ddif;
1067 current_ir_graph = rem;
1071 /***********************************************************************/
1072 /* the following routine dumps all type information reachable from an */
1074 /***********************************************************************/
1078 dump_type_graph (ir_graph *irg)
1081 rem = current_ir_graph;
1082 current_ir_graph = irg;
1084 vcg_open (irg, "-type");
1086 /* walk over the blocks in the graph */
1087 type_walk_irg(irg, dump_type_info, NULL, NULL);
1088 /* The walker for the const code can be called several times for the
1089 same (sub) experssion. So that no nodes are dumped several times
1090 we decrease the visited flag of the corresponding graph after each
1091 walk. So now increase it finally. */
1092 inc_irg_visited(get_const_code_irg());
1095 current_ir_graph = rem;
1098 /***********************************************************************/
1099 /* the following routine dumps all type information */
1100 /***********************************************************************/
1104 dump_all_types (void)
1106 vcg_open_name ("All_types");
1107 type_walk(dump_type_info, NULL, NULL);
1108 inc_irg_visited(get_const_code_irg());
1112 /***********************************************************************/
1113 /* dumps a graph with type information */
1114 /***********************************************************************/
1118 dump_ir_graph_w_types (ir_graph *irg)
1121 rem = current_ir_graph;
1122 current_ir_graph = irg;
1124 vcg_open (irg, "-all");
1126 /* dump common ir graph */
1127 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1128 /* dump type info */
1129 type_walk_irg(irg, dump_type_info, NULL, NULL);
1130 inc_irg_visited(get_const_code_irg());
1131 /* dump edges from graph to type info */
1132 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1135 current_ir_graph = rem;
1139 dump_ir_block_graph_w_types (ir_graph *irg)
1142 rem = current_ir_graph;
1143 current_ir_graph = irg;
1145 vcg_open (irg, "-all");
1147 /* dump common blocked ir graph */
1148 dump_ir_block_graph_2(irg);
1149 /* dump type info */
1150 type_walk_irg(irg, dump_type_info, NULL, NULL);
1151 inc_irg_visited(get_const_code_irg());
1152 /* dump edges from graph to type info */
1153 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1156 current_ir_graph = rem;
1159 /***********************************************************************/
1160 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1162 /* dump_ir_block_graph */
1164 /* dump_type_graph */
1165 /* dump_ir_graph_w_types */
1166 /***********************************************************************/
1167 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1169 for (i=0; i < get_irp_n_irgs(); i++) {
1170 dump_graph(get_irp_irg(i));
1175 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1176 abort with a segmentation fault. */
1177 void turn_off_edge_labels() {
1181 void turn_off_constant_entity_values() {
1185 void dump_keepalive_edges() {
1189 void dump_out_edges() {
1190 dump_out_edge_flag = 1;
1193 void dump_dominator_information() {
1194 dump_dominator_information_flag = 1;