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"
31 /* Attributes of nodes */
32 #define DEFAULT_NODE_ATTR ""
33 #define DEFAULT_TYPE_ATTRIBUTE ""
35 /* Attributes of edges between Firm nodes */
36 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
37 #define CF_EDGE_ATTR "color: red"
38 #define MEM_EDGE_ATTR "color: blue"
40 /* Attributes of edges between Firm nodes and type/entity nodes */
41 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
43 /* Attributes of edges in type/entity graphs. */
44 #define TYPE_METH_NODE_ATTR "color: lightyellow"
45 #define TYPE_CLASS_NODE_ATTR "color: green"
46 #define ENTITY_NODE_ATTR "color: yellow"
47 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
48 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
49 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
50 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
51 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
52 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
53 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
54 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
55 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
56 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
57 #define ENT_VALUE_EDGE_ATTR "label: \"value "
58 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
59 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
62 #if DEBUG_libfirm && NODEID_AS_LABEL
63 #define PRINT_NODEID(X) fprintf(F, "%d", get_irn_node_nr(X))
65 #define PRINT_NODEID(X) fprintf(F, "%p", X)
71 /* A compiler option to turn off edge labels */
73 /* A compiler option to turn off dumping values of constant entities */
74 int const_entities = 1;
75 /* A compiler option to dump the keep alive edges */
76 int dump_keepalive = 0;
77 /* A compiler option to dump the out edges in dump_ir_graph */
78 int dump_out_edge_flag = 0;
81 /* A global variable to record output of the Bad node. */
85 void dump_ir_blocks_nodes (ir_node *n, void *env);
86 void dump_whole_node (ir_node *n, void* env);
88 /*******************************************************************/
89 /* routines to dump information about a single node */
90 /*******************************************************************/
95 dump_node_opcode (ir_node *n)
99 if (n->op->code == iro_Const) {
100 xfprintf (F, "%v", n->attr.con);
103 } else if (n->op->code == iro_SymConst) {
104 if (get_SymConst_kind(n) == linkage_ptr_info) {
105 xfprintf (F, "%I", get_SymConst_ptrinfo(n));
107 assert(get_kind(get_SymConst_type(n)) == k_type);
108 assert(get_type_ident(get_SymConst_type(n)));
109 xfprintf (F, "%s ", id_to_str(get_type_ident(get_SymConst_type(n))));
110 if (get_SymConst_kind == type_tag)
113 xfprintf (F, "size");
117 xfprintf (F, "%I", get_irn_opident(n));
122 dump_node_mode (ir_node *n)
124 switch (n->op->code) {
141 xfprintf (F, "%I", get_mode_ident(n->mode));
148 dump_node_nodeattr (ir_node *n)
150 switch (n->op->code) {
152 if (n->in[1]->op->code == iro_Cmp) {
153 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
155 xfprintf (F, "%ld", n->attr.proj);
159 assert(get_kind(get_Sel_entity(n)) == k_entity);
160 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
167 dump_node_vcgattr (ir_node *n)
169 switch (n->op->code) {
172 xfprintf (F, "color: blue");
175 xfprintf (F, "color: lightyellow");
178 xfprintf (F, "color: green");
183 xfprintf (F, "color: yellow");
186 xfprintf (F, DEFAULT_NODE_ATTR);
191 dump_node (ir_node *n) {
194 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
199 dump_node_nodeattr(n);
201 xfprintf (F, " %ld", get_irn_node_nr(n));
204 dump_node_vcgattr(n);
209 dump_ir_node (ir_node *n)
212 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
214 switch (n->op->code) { /* node label */
216 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
217 xfprintf (F, DEFAULT_NODE_ATTR);
220 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
221 xfprintf (F, DEFAULT_NODE_ATTR);
224 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
225 xfprintf (F, DEFAULT_NODE_ATTR);
228 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
229 if (get_irn_modecode(n) == irm_M)
230 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
232 xfprintf (F, DEFAULT_NODE_ATTR);
235 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
236 xfprintf (F, DEFAULT_NODE_ATTR);
239 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
240 xfprintf (F, DEFAULT_NODE_ATTR);
243 if (n->in[1]->op->code == iro_Cmp) {
244 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
245 get_pnc_string(n->attr.proj));
247 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
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%I\"", get_irn_opident(n), get_irn_modeident(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\"", get_irn_opident(n));
329 xfprintf (F, DEFAULT_NODE_ATTR);
332 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
333 xfprintf (F, DEFAULT_NODE_ATTR);
337 xfprintf (F, "\"%R\"", n);
338 xfprintf (F, DEFAULT_NODE_ATTR);
341 xfprintf (F, "\"%I\" ", get_irn_opident(n));
342 xfprintf (F, DEFAULT_NODE_ATTR);
345 assert(get_kind(get_Sel_entity(n)) == k_entity);
346 xfprintf (F, "\"%I ", get_irn_opident(n));
347 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
348 xfprintf (F, DEFAULT_NODE_ATTR);
351 assert(get_kind(get_SymConst_type(n)) == k_type);
352 assert(get_type_ident(get_SymConst_type(n)));
353 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
354 switch (n->attr.i.num){
356 xfprintf (F, "tag\" ");
359 xfprintf (F, "size\" ");
365 xfprintf (F, DEFAULT_NODE_ATTR);
368 xfprintf (F, "\"%I\" ", get_irn_opident(n));
369 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
372 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
373 xfprintf (F, DEFAULT_NODE_ATTR);
376 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
378 xfprintf (F, "}\n"); /* footer */
382 /* dump the edge to the block this node belongs to */
384 dump_ir_block_edge(ir_node *n) {
385 if (is_no_Block(n)) {
386 xfprintf (F, "edge: { sourcename: \"");
388 xfprintf (F, "\" targetname: \"");
389 PRINT_NODEID(get_nodes_Block(n));
390 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
394 void print_edge_vcgattr(ir_node *from, int to) {
397 switch (get_irn_opcode(from)) {
399 xfprintf (F, CF_EDGE_ATTR);
401 case iro_Start: break;
404 case iro_Cond: break;
407 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
409 case iro_Const: break;
410 case iro_SymConst:break;
413 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
417 case iro_Minus: break;
423 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
431 case iro_Shrs: break;
434 case iro_Conv: break;
436 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
442 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
445 xfprintf (F, MEM_EDGE_ATTR);
447 case iro_Tuple: break;
449 switch (get_irn_modecode(from)) {
451 xfprintf (F, CF_EDGE_ATTR);
454 xfprintf (F, MEM_EDGE_ATTR);
465 /* dump edges to our inputs */
467 dump_ir_data_edges(ir_node *n) {
470 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
473 for (i = 0; i < get_irn_arity(n); i++) {
474 assert(get_irn_n(n, i));
475 fprintf (F, "edge: {sourcename: \"");
477 fprintf (F, "\" targetname: \"");
478 PRINT_NODEID(get_irn_n(n, i));
480 fprintf (F, " label: \"%d\" ", i);
481 print_edge_vcgattr(n, i);
488 dump_out_edge (ir_node *n, void* env) {
490 for (i = 0; i < get_irn_n_outs(n); i++) {
491 assert(get_irn_out(n, i));
492 fprintf (F, "edge: {sourcename: \"");
494 fprintf (F, "\" targetname: \"");
495 PRINT_NODEID(get_irn_out(n, i));
496 fprintf (F, "\" color: red linestyle: dashed");
502 /* dumps the edges between nodes and their type or entity attributes. */
503 void dump_node2type_edges (ir_node *n, void *env)
507 switch (get_irn_opcode(n)) {
509 /* @@@ some consts have an entity */
512 if ( (get_SymConst_kind(n) == type_tag)
513 || (get_SymConst_kind(n) == size)) {
514 xfprintf (F, "edge: { sourcename: \"");
516 fprintf (F, "\" targetname: \"%p\" "
517 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
521 xfprintf (F, "edge: { sourcename: \"");
523 fprintf (F, "\" targetname: \"%p\" "
524 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
527 xfprintf (F, "edge: { sourcename: \"");
529 fprintf (F, "\" targetname: \"%p\" "
530 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
533 xfprintf (F, "edge: { sourcename: \"");
535 fprintf (F, "\" targetname: \"%p\" "
536 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
539 xfprintf (F, "edge: { sourcename: \"");
541 fprintf (F, "\" targetname: \"%p\" "
542 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
550 void dump_const_expression(ir_node *value) {
551 ir_graph *rem = current_ir_graph;
552 current_ir_graph = get_const_code_irg();
553 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
554 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
555 current_ir_graph = rem;
559 void print_type_info(type *tp) {
560 if (get_type_state(tp) == layout_undefined) {
561 xfprintf(F, "state: layout_undefined\n");
563 xfprintf(F, "state: layout_fixed,\n");
565 if (get_type_mode(tp))
566 xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
567 xfprintf(F, "size: %dB,\n", get_type_size(tp));
571 void print_typespecific_info(type *tp) {
572 switch (get_type_tpop_code(tp)) {
575 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
579 xfprintf (F, " " TYPE_METH_NODE_ATTR);
590 case tpo_enumeration:
603 void print_type_node(type *tp) {
604 xfprintf (F, "node: {title: \"%p\" ", tp);
605 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
606 xfprintf (F, "info1: \"");
609 print_typespecific_info(tp);
613 /* dumps a type or entity and it's edges. */
615 dump_type_info (type_or_ent *tore, void *env) {
616 int i = 0; /* to shutup gcc */
618 /* dump this type or entity */
620 switch (get_kind(tore)) {
623 entity *ent = (entity *)tore;
626 xfprintf (F, "node: {title: \"%p\" ", tore);
627 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
628 xfprintf (F, "label: ");
629 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
630 if(dynamic_allocated == get_entity_allocation(ent))
631 xfprintf (F, " info1:\"dynamic allocated\n");
633 xfprintf (F, " info1:\"static allocated\n");
634 switch (get_entity_visibility(ent)) {
635 case local: fprintf (F, "local\n"); break;
636 case external_visible: fprintf (F, "external_visible\n"); break;
637 case external_allocated: fprintf (F, "external_allocate\nd");break;
639 switch (get_entity_variability(ent)) {
640 case uninitialized: fprintf (F, "uninitialized");break;
641 case initialized: fprintf (F, "initialized"); break;
642 case part_constant: fprintf (F, "part_constant");break;
643 case constant: fprintf (F, "constant"); break;
645 xfprintf(F, "\"}\n");
647 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
648 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));
649 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
650 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
651 for(i = 0; i < get_entity_n_overwrites(ent); i++)
652 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
653 ENT_OVERWRITES_EDGE_ATTR "}\n", ent, get_entity_overwrites(ent, i));
654 /* attached subgraphs */
655 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
656 if (is_atomic_entity(ent)) {
657 value = get_atomic_ent_value(ent);
658 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
660 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
661 dump_const_expression(value);
663 if (is_compound_entity(ent)) {
664 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
665 value = get_compound_ent_value(ent, i);
666 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
668 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
669 dump_const_expression(value);
670 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
671 ENT_CORR_EDGE_ATTR "}\n", ent,
672 get_compound_ent_value_member(ent, i), i);
679 type *tp = (type *)tore;
681 /* and now the edges */
682 switch (get_type_tpop_code(tp)) {
685 for (i=0; i < get_class_n_supertype(tp); i++)
686 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
687 TYPE_SUPER_EDGE_ATTR "}\n",
688 tp, get_class_supertype(tp, i));
689 for (i=0; i < get_class_n_member(tp); i++)
690 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
691 TYPE_MEMBER_EDGE_ATTR "}\n",
692 tp, get_class_member(tp, i));
696 for (i=0; i < get_struct_n_member(tp); i++)
697 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
698 TYPE_MEMBER_EDGE_ATTR "}\n",
699 tp, get_struct_member(tp, i));
703 for (i = 0; i < get_method_n_params(tp); i++)
704 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
705 METH_PAR_EDGE_ATTR "}\n",
706 tp, get_method_param_type(tp, i), i);
707 for (i = 0; i < get_method_n_res(tp); i++)
708 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
709 METH_RES_EDGE_ATTR "}\n",
710 tp, get_method_res_type(tp, i), i);
714 for (i = 0; i < get_union_n_members(tp); i++)
715 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
716 "label: \"\"f" UNION_EDGE_ATTR "}\n",
717 tp, get_union_member(tp, i));
721 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
722 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
723 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
724 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
726 case tpo_enumeration:
731 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
732 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
733 get_pointer_points_to_type(tp), i);
741 break; /* case k_type */
744 printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
746 } /* switch kind_or_entity */
749 /************************************************************************/
750 /* open and close vcg file */
751 /************************************************************************/
753 void vcg_open (ir_graph *irg, char *suffix) {
754 char *fname; /* filename to put the vcg information in */
761 /** open file for vcg graph */
762 ent = get_irg_ent(irg);
763 id = get_entity_ld_ident (ent);
764 len = id_to_strlen (id);
766 fname = malloc (len + 5 + strlen(suffix));
767 strncpy (fname, cp, len); /* copy the filename */
769 strcat (fname, suffix); /* append file suffix */
771 fname = malloc (len + 5 + strlen(suffix));
772 strncpy (fname, cp, len); /* copy the filename */
773 fname[len] = '\0'; /* ensure string termination */
774 /*strcpy (fname, cp); * copy the filename *
775 this produces wrong, too long strings in conjuction with the
776 jocca frontend. The \0 seems to be missing. */
777 strcat (fname, suffix); /* append file suffix */
778 strcat (fname, ".vcg"); /* append the .vcg suffix */
779 F = fopen (fname, "w"); /* open file for writing */
781 panic ("cannot open %s for writing (%m)", fname); /* not reached */
785 strcpy(label, "yes");
787 strcpy (label, "no");
792 "graph: { title: \"ir graph of %s\"\n"
793 "display_edge_labels: %s\n"
794 "layoutalgorithm: mindepth\n"
795 "manhattan_edges: yes\n"
797 "orientation: bottom_to_top\n"
798 "classname 1: \"Data\"\n"
799 "classname 2: \"Block\"\n"
800 "classname 3: \"Entity type\""
801 "classname 4: \"Entity owner\""
802 "classname 5: \"Method Param\""
803 "classname 6: \"Method Res\""
804 "classname 7: \"Super\""
805 "classname 8: \"Union\""
806 "classname 9: \"Points-to\""
807 "classname 10: \"Array Element Type\""
808 "classname 11: \"Overwrites\""
809 "classname 12: \"Member\""
812 xfprintf (F, "\n"); /* a separator */
815 void vcg_open_name (const char *name) {
816 char *fname; /* filename to put the vcg information in */
820 /** open file for vcg graph */
822 fname = malloc (len + 5);
823 strcpy (fname, name); /* copy the filename */
824 strcat (fname, ".vcg"); /* append the .vcg suffix */
825 F = fopen (fname, "w"); /* open file for writing */
827 panic ("cannot open %s for writing (%m)", fname); /* not reached */
831 strcpy(label, "yes");
833 strcpy (label, "no");
838 "graph: { title: \"ir graph of %s\"\n"
839 "display_edge_labels: %s\n"
840 "layoutalgorithm: mindepth\n"
841 "manhattan_edges: yes\n"
843 "orientation: bottom_to_top\n"
844 "classname 1: \"Data\"\n"
845 "classname 2: \"Block\"\n"
846 "classname 3: \"Entity type\"\n"
847 "classname 4: \"Entity owner\"\n"
848 "classname 5: \"Method Param\"\n"
849 "classname 6: \"Method Res\"\n"
850 "classname 7: \"Super\"\n"
851 "classname 8: \"Union\"\n"
852 "classname 9: \"Points-to\"\n"
853 "classname 10: \"Array Element Type\"\n"
854 "classname 11: \"Overwrites\"\n"
855 "classname 12: \"Member\"\n"
858 xfprintf (F, "\n"); /* a separator */
863 xfprintf (F, "}\n"); /* print footer */
864 fclose (F); /* close vcg file */
867 /************************************************************************/
868 /* routines to dump a graph, blocks as conventional nodes. */
869 /************************************************************************/
872 dump_whole_node (ir_node *n, void* env) {
874 if (!node_floats(n)) dump_ir_block_edge(n);
875 dump_ir_data_edges(n);
879 dump_ir_graph (ir_graph *irg)
882 rem = current_ir_graph;
883 current_ir_graph = irg;
887 /* walk over the graph */
888 irg_walk(irg->end, dump_whole_node, NULL, NULL);
890 /* dump the out edges in a separate walk */
891 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
892 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
897 current_ir_graph = rem;
900 /***********************************************************************/
901 /* the following routines dump the nodes as attached to the blocks. */
902 /***********************************************************************/
904 int node_floats(ir_node *n) {
905 return ((get_op_pinned(get_irn_op(n)) == floats) &&
906 (get_irg_pinned(current_ir_graph) == floats));
910 dump_ir_blocks_nodes (ir_node *n, void *env) {
911 ir_node *block = (ir_node *)env;
913 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
915 dump_ir_data_edges(n);
917 if (get_irn_op(n) == op_Bad)
922 dump_ir_block (ir_node *block, void *env) {
923 ir_graph *irg = (ir_graph *)env;
925 if (get_irn_opcode(block) == iro_Block) {
927 /* This is a block. So dump the vcg information to make a block. */
928 xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \"");
930 xfprintf (F, "%ld", get_irn_node_nr(block));
932 xfprintf (F, "%I", block->op->name);
934 xfprintf(F, "\" status:clustered color:%s \n",
935 get_Block_matured (block) ? "yellow" : "red");
936 /* dump the blocks edges */
937 dump_ir_data_edges(block);
939 /* dump the nodes that go into the block */
940 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
942 /* Close the vcg information for the block */
943 xfprintf(F, "}\n\n");
949 dump_blockless_nodes (ir_node *n, void *env) {
950 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
952 dump_ir_data_edges(n);
953 dump_ir_block_edge(n);
954 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
957 if (node_floats(n)) {
959 dump_ir_data_edges(n);
960 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
964 void dump_ir_block_graph_2 (ir_graph *irg)
967 /* walk over the blocks in the graph */
968 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
970 /* dump all nodes that are not in a Block */
971 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
973 /* dump the Bad node */
975 dump_node(get_irg_bad(irg));
979 dump_ir_block_graph (ir_graph *irg)
982 rem = current_ir_graph;
983 current_ir_graph = irg;
987 dump_ir_block_graph_2 (irg);
990 current_ir_graph = rem;
994 /***********************************************************************/
995 /* the following routines dump a control flow graph */
996 /***********************************************************************/
1000 dump_block_to_cfg (ir_node *block, void *env) {
1004 if (get_irn_opcode(block) == iro_Block) {
1005 /* This is a block. Dump a node for the block. */
1006 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
1008 /* Dump the edges */
1009 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
1010 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1011 xfprintf (F, "edge: { sourcename: \"");
1012 PRINT_NODEID(block);
1013 fprintf (F, "\" targetname: \"");
1015 fprintf (F, "\" }\n");
1021 dump_cfg (ir_graph *irg)
1023 vcg_open (irg, "-cfg");
1025 /* walk over the blocks in the graph */
1026 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1032 /***********************************************************************/
1033 /* the following routine dumps all type information reachable from an */
1035 /***********************************************************************/
1039 dump_type_graph (ir_graph *irg)
1042 rem = current_ir_graph;
1043 current_ir_graph = irg;
1045 vcg_open (irg, "-type");
1047 /* walk over the blocks in the graph */
1048 type_walk_irg(irg, dump_type_info, NULL, NULL);
1049 /* The walker for the const code can be called several times for the
1050 same (sub) experssion. So that no nodes are dumped several times
1051 we decrease the visited flag of the corresponding graph after each
1052 walk. So now increase it finally. */
1053 inc_irg_visited(get_const_code_irg());
1056 current_ir_graph = rem;
1059 /***********************************************************************/
1060 /* the following routine dumps all type information */
1061 /***********************************************************************/
1065 dump_all_types (void)
1067 vcg_open_name ("All_types");
1068 type_walk(dump_type_info, NULL, NULL);
1069 inc_irg_visited(get_const_code_irg());
1073 /***********************************************************************/
1074 /* dumps a graph with type information */
1075 /***********************************************************************/
1079 dump_ir_graph_w_types (ir_graph *irg)
1082 rem = current_ir_graph;
1083 current_ir_graph = irg;
1085 vcg_open (irg, "-all");
1087 /* dump common ir graph */
1088 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1089 /* dump type info */
1090 type_walk_irg(irg, dump_type_info, NULL, NULL);
1091 inc_irg_visited(get_const_code_irg());
1092 /* dump edges from graph to type info */
1093 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1096 current_ir_graph = rem;
1100 dump_ir_block_graph_w_types (ir_graph *irg)
1103 rem = current_ir_graph;
1104 current_ir_graph = irg;
1106 vcg_open (irg, "-all");
1108 /* dump common blocked ir graph */
1109 dump_ir_block_graph_2(irg);
1110 /* dump type info */
1111 type_walk_irg(irg, dump_type_info, NULL, NULL);
1112 inc_irg_visited(get_const_code_irg());
1113 /* dump edges from graph to type info */
1114 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1117 current_ir_graph = rem;
1120 /***********************************************************************/
1121 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1123 /* dump_ir_block_graph */
1125 /* dump_type_graph */
1126 /* dump_ir_graph_w_types */
1127 /***********************************************************************/
1128 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1130 for (i=0; i < get_irp_n_irgs(); i++) {
1131 dump_graph(get_irp_irg(i));
1136 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1137 abort with a segmentation fault. */
1138 void turn_of_edge_labels() {
1142 void dump_constant_entity_values() {
1146 void dump_keepalive_edges() {
1150 void dump_out_edges() {
1151 dump_out_edge_flag = 1;