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;
75 /* A global variable to record output of the Bad node. */
79 void dump_ir_blocks_nodes (ir_node *n, void *env);
80 void dump_whole_node (ir_node *n, void* env);
82 /*******************************************************************/
83 /* routines to dump information about a single node */
84 /*******************************************************************/
89 dump_node_opcode (ir_node *n)
93 if (n->op->code == iro_Const) {
94 xfprintf (F, "%v", n->attr.con);
97 } else if (n->op->code == iro_SymConst) {
98 if (get_SymConst_kind(n) == linkage_ptr_info) {
99 xfprintf (F, "%I", get_SymConst_ptrinfo(n));
101 assert(get_kind(get_SymConst_type(n)) == k_type);
102 assert(get_type_ident(get_SymConst_type(n)));
103 xfprintf (F, "%s ", id_to_str(get_type_ident(get_SymConst_type(n))));
104 if (get_SymConst_kind == type_tag)
107 xfprintf (F, "size");
111 xfprintf (F, "%I", get_irn_opident(n));
116 dump_node_mode (ir_node *n)
118 switch (n->op->code) {
135 xfprintf (F, "%I", get_mode_ident(n->mode));
142 dump_node_nodeattr (ir_node *n)
144 switch (n->op->code) {
146 if (n->in[1]->op->code == iro_Cmp) {
147 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
149 xfprintf (F, "%ld", n->attr.proj);
153 assert(get_kind(get_Sel_entity(n)) == k_entity);
154 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
161 dump_node_vcgattr (ir_node *n)
163 switch (n->op->code) {
166 xfprintf (F, "color: blue");
169 xfprintf (F, "color: lightyellow");
172 xfprintf (F, "color: green");
177 xfprintf (F, "color: yellow");
180 xfprintf (F, DEFAULT_NODE_ATTR);
185 dump_node (ir_node *n) {
188 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
193 dump_node_nodeattr(n);
195 xfprintf (F, " %ld", get_irn_node_nr(n));
198 dump_node_vcgattr(n);
203 dump_ir_node (ir_node *n)
206 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
208 switch (n->op->code) { /* node label */
210 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
211 xfprintf (F, DEFAULT_NODE_ATTR);
214 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
215 xfprintf (F, DEFAULT_NODE_ATTR);
218 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
219 xfprintf (F, DEFAULT_NODE_ATTR);
222 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
223 if (get_irn_modecode(n) == irm_M)
224 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
226 xfprintf (F, DEFAULT_NODE_ATTR);
229 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
230 xfprintf (F, DEFAULT_NODE_ATTR);
233 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
234 xfprintf (F, DEFAULT_NODE_ATTR);
237 if (n->in[1]->op->code == iro_Cmp) {
238 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
239 get_pnc_string(n->attr.proj));
241 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
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 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
251 xfprintf (F, DEFAULT_NODE_ATTR);
254 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
255 xfprintf (F, DEFAULT_NODE_ATTR);
258 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
259 xfprintf (F, DEFAULT_NODE_ATTR);
262 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
263 xfprintf (F, DEFAULT_NODE_ATTR);
266 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
267 xfprintf (F, DEFAULT_NODE_ATTR);
270 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
271 xfprintf (F, DEFAULT_NODE_ATTR);
274 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
275 xfprintf (F, DEFAULT_NODE_ATTR);
278 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
279 xfprintf (F, DEFAULT_NODE_ATTR);
282 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
283 xfprintf (F, DEFAULT_NODE_ATTR);
286 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
287 xfprintf (F, DEFAULT_NODE_ATTR);
290 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
291 xfprintf (F, DEFAULT_NODE_ATTR);
294 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
295 xfprintf (F, DEFAULT_NODE_ATTR);
298 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
299 xfprintf (F, DEFAULT_NODE_ATTR);
302 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
303 xfprintf (F, DEFAULT_NODE_ATTR);
306 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
307 xfprintf (F, DEFAULT_NODE_ATTR);
310 xfprintf (F, "\"%I\"", get_irn_opident(n));
311 xfprintf (F, DEFAULT_NODE_ATTR);
314 xfprintf (F, "\"%I\"", get_irn_opident(n));
315 xfprintf (F, DEFAULT_NODE_ATTR);
318 xfprintf (F, "\"%I\"", get_irn_opident(n));
319 xfprintf (F, DEFAULT_NODE_ATTR);
322 xfprintf (F, "\"%I\"", get_irn_opident(n));
323 xfprintf (F, DEFAULT_NODE_ATTR);
326 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
327 xfprintf (F, DEFAULT_NODE_ATTR);
331 xfprintf (F, "\"%R\"", n);
332 xfprintf (F, DEFAULT_NODE_ATTR);
335 xfprintf (F, "\"%I\" ", get_irn_opident(n));
336 xfprintf (F, DEFAULT_NODE_ATTR);
339 assert(get_kind(get_Sel_entity(n)) == k_entity);
340 xfprintf (F, "\"%I ", get_irn_opident(n));
341 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
342 xfprintf (F, DEFAULT_NODE_ATTR);
345 assert(get_kind(get_SymConst_type(n)) == k_type);
346 assert(get_type_ident(get_SymConst_type(n)));
347 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
348 switch (n->attr.i.num){
350 xfprintf (F, "tag\" ");
353 xfprintf (F, "size\" ");
359 xfprintf (F, DEFAULT_NODE_ATTR);
362 xfprintf (F, "\"%I\" ", get_irn_opident(n));
363 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
366 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
367 xfprintf (F, DEFAULT_NODE_ATTR);
370 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
372 xfprintf (F, "}\n"); /* footer */
376 /* dump the edge to the block this node belongs to */
378 dump_ir_block_edge(ir_node *n) {
379 if (is_no_Block(n)) {
380 xfprintf (F, "edge: { sourcename: \"");
382 xfprintf (F, "\" targetname: \"");
383 PRINT_NODEID(get_nodes_Block(n));
384 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
388 void print_edge_vcgattr(ir_node *from, int to) {
391 switch (get_irn_opcode(from)) {
393 xfprintf (F, CF_EDGE_ATTR);
395 case iro_Start: break;
398 case iro_Cond: break;
401 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
403 case iro_Const: break;
404 case iro_SymConst:break;
407 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
411 case iro_Minus: break;
417 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
425 case iro_Shrs: break;
428 case iro_Conv: break;
430 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
436 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
439 xfprintf (F, MEM_EDGE_ATTR);
441 case iro_Tuple: break;
443 switch (get_irn_modecode(from)) {
445 xfprintf (F, CF_EDGE_ATTR);
448 xfprintf (F, MEM_EDGE_ATTR);
459 /* dump edges to our inputs */
461 dump_ir_data_edges(ir_node *n) {
464 for (i = 0; i < get_irn_arity(n); i++) {
465 assert(get_irn_n(n, i));
466 fprintf (F, "edge: {sourcename: \"");
468 fprintf (F, "\" targetname: \"");
469 PRINT_NODEID(get_irn_n(n, i));
471 fprintf (F, " label: \"%d\" ", i);
472 print_edge_vcgattr(n, i);
477 /* dumps the edges between nodes and their type or entity attributes. */
478 void dump_node2type_edges (ir_node *n, void *env)
482 switch (get_irn_opcode(n)) {
484 /* @@@ some consts have an entity */
487 if ( (get_SymConst_kind(n) == type_tag)
488 || (get_SymConst_kind(n) == size)) {
489 xfprintf (F, "edge: { sourcename: \"");
491 fprintf (F, "\" targetname: \"%p\" "
492 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
496 xfprintf (F, "edge: { sourcename: \"");
498 fprintf (F, "\" targetname: \"%p\" "
499 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
502 xfprintf (F, "edge: { sourcename: \"");
504 fprintf (F, "\" targetname: \"%p\" "
505 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
508 xfprintf (F, "edge: { sourcename: \"");
510 fprintf (F, "\" targetname: \"%p\" "
511 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
514 xfprintf (F, "edge: { sourcename: \"");
516 fprintf (F, "\" targetname: \"%p\" "
517 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
525 void dump_const_expression(ir_node *value) {
526 ir_graph *rem = current_ir_graph;
527 current_ir_graph = get_const_code_irg();
528 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
529 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
530 current_ir_graph = rem;
534 void print_type_info(type *tp) {
535 if (get_type_state(tp) == layout_undefined) {
536 xfprintf(F, "state: layout_undefined\n");
538 xfprintf(F, "state: layout_fixed,\n");
540 if (get_type_mode(tp))
541 xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
542 xfprintf(F, "size: %dB,\n", get_type_size(tp));
546 void print_typespecific_info(type *tp) {
547 switch (get_type_tpop_code(tp)) {
550 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
554 xfprintf (F, " " TYPE_METH_NODE_ATTR);
565 case tpo_enumeration:
578 void print_type_node(type *tp) {
579 xfprintf (F, "node: {title: \"%p\" ", tp);
580 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
581 xfprintf (F, "info1: \"");
584 print_typespecific_info(tp);
588 /* dumps a type or entity and it's edges. */
590 dump_type_info (type_or_ent *tore, void *env) {
591 int i = 0; /* to shutup gcc */
593 /* dump this type or entity */
595 switch (get_kind(tore)) {
598 entity *ent = (entity *)tore;
601 xfprintf (F, "node: {title: \"%p\" ", tore);
602 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
603 xfprintf (F, "label: ");
604 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
605 if(dynamic_allocated == get_entity_allocation(ent))
606 xfprintf (F, " info1:\"dynamic allocated\n");
608 xfprintf (F, " info1:\"static allocated\n");
609 switch (get_entity_visibility(ent)) {
610 case local: fprintf (F, "local\n"); break;
611 case external_visible: fprintf (F, "external_visible\n"); break;
612 case external_allocated: fprintf (F, "external_allocate\nd");break;
614 switch (get_entity_variability(ent)) {
615 case uninitialized: fprintf (F, "uninitialized");break;
616 case initialized: fprintf (F, "initialized"); break;
617 case part_constant: fprintf (F, "part_constant");break;
618 case constant: fprintf (F, "constant"); break;
620 xfprintf(F, "\"}\n");
622 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
623 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));
624 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
625 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
626 for(i = 0; i < get_entity_n_overwrites(ent); i++)
627 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
628 ENT_OVERWRITES_EDGE_ATTR "}\n", ent, get_entity_overwrites(ent, i));
629 /* attached subgraphs */
630 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
631 if (is_atomic_entity(ent)) {
632 value = get_atomic_ent_value(ent);
633 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
635 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
636 dump_const_expression(value);
638 if (is_compound_entity(ent)) {
639 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
640 value = get_compound_ent_value(ent, i);
641 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
643 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
644 dump_const_expression(value);
645 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
646 ENT_CORR_EDGE_ATTR "}\n", ent,
647 get_compound_ent_value_member(ent, i), i);
654 type *tp = (type *)tore;
656 /* and now the edges */
657 switch (get_type_tpop_code(tp)) {
660 for (i=0; i < get_class_n_supertype(tp); i++)
661 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
662 TYPE_SUPER_EDGE_ATTR "}\n",
663 tp, get_class_supertype(tp, i));
664 for (i=0; i < get_class_n_member(tp); i++)
665 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
666 TYPE_MEMBER_EDGE_ATTR "}\n",
667 tp, get_class_member(tp, i));
671 for (i=0; i < get_struct_n_member(tp); i++)
672 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
673 TYPE_MEMBER_EDGE_ATTR "}\n",
674 tp, get_struct_member(tp, i));
678 for (i = 0; i < get_method_n_params(tp); i++)
679 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
680 METH_PAR_EDGE_ATTR "}\n",
681 tp, get_method_param_type(tp, i), i);
682 for (i = 0; i < get_method_n_res(tp); i++)
683 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
684 METH_RES_EDGE_ATTR "}\n",
685 tp, get_method_res_type(tp, i), i);
689 for (i = 0; i < get_union_n_members(tp); i++)
690 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
691 "label: \"\"f" UNION_EDGE_ATTR "}\n",
692 tp, get_union_member(tp, i));
696 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
697 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
698 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
699 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
701 case tpo_enumeration:
706 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
707 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
708 get_pointer_points_to_type(tp), i);
716 break; /* case k_type */
719 printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
721 } /* switch kind_or_entity */
724 /************************************************************************/
725 /* open and close vcg file */
726 /************************************************************************/
728 void vcg_open (ir_graph *irg, char *suffix) {
729 char *fname; /* filename to put the vcg information in */
736 /** open file for vcg graph */
737 ent = get_irg_ent(irg);
738 id = get_entity_ld_ident (ent);
739 len = id_to_strlen (id);
741 fname = malloc (len + 5 + strlen(suffix));
742 strncpy (fname, cp, len); /* copy the filename */
744 strcat (fname, suffix); /* append file suffix */
746 fname = malloc (len + 5 + strlen(suffix));
747 strncpy (fname, cp, len); /* copy the filename */
748 fname[len] = '\0'; /* ensure string termination */
749 /*strcpy (fname, cp); * copy the filename *
750 this produces wrong, too long strings in conjuction with the
751 jocca frontend. The \0 seems to be missing. */
752 strcat (fname, suffix); /* append file suffix */
753 strcat (fname, ".vcg"); /* append the .vcg suffix */
754 F = fopen (fname, "w"); /* open file for writing */
756 panic ("cannot open %s for writing (%m)", fname); /* not reached */
760 strcpy(label, "yes");
762 strcpy (label, "no");
767 "graph: { title: \"ir graph of %s\"\n"
768 "display_edge_labels: %s\n"
769 "layoutalgorithm: mindepth\n"
770 "manhattan_edges: yes\n"
772 "orientation: bottom_to_top\n"
773 "classname 1: \"Data\"\n"
774 "classname 2: \"Block\"\n"
775 "classname 3: \"Entity type\""
776 "classname 4: \"Entity owner\""
777 "classname 5: \"Method Param\""
778 "classname 6: \"Method Res\""
779 "classname 7: \"Super\""
780 "classname 8: \"Union\""
781 "classname 9: \"Points-to\""
782 "classname 10: \"Array Element Type\""
783 "classname 11: \"Overwrites\""
784 "classname 12: \"Member\""
787 xfprintf (F, "\n"); /* a separator */
790 void vcg_open_name (const char *name) {
791 char *fname; /* filename to put the vcg information in */
795 /** open file for vcg graph */
797 fname = malloc (len + 5);
798 strcpy (fname, name); /* copy the filename */
799 strcat (fname, ".vcg"); /* append the .vcg suffix */
800 F = fopen (fname, "w"); /* open file for writing */
802 panic ("cannot open %s for writing (%m)", fname); /* not reached */
806 strcpy(label, "yes");
808 strcpy (label, "no");
813 "graph: { title: \"ir graph of %s\"\n"
814 "display_edge_labels: %s\n"
815 "layoutalgorithm: mindepth\n"
816 "manhattan_edges: yes\n"
818 "orientation: bottom_to_top\n"
819 "classname 1: \"Data\"\n"
820 "classname 2: \"Block\"\n"
821 "classname 3: \"Entity type\"\n"
822 "classname 4: \"Entity owner\"\n"
823 "classname 5: \"Method Param\"\n"
824 "classname 6: \"Method Res\"\n"
825 "classname 7: \"Super\"\n"
826 "classname 8: \"Union\"\n"
827 "classname 9: \"Points-to\"\n"
828 "classname 10: \"Array Element Type\"\n"
829 "classname 11: \"Overwrites\"\n"
830 "classname 12: \"Member\"\n"
833 xfprintf (F, "\n"); /* a separator */
838 xfprintf (F, "}\n"); /* print footer */
839 fclose (F); /* close vcg file */
842 /************************************************************************/
843 /* routines to dump a graph, blocks as conventional nodes. */
844 /************************************************************************/
847 dump_whole_node (ir_node *n, void* env) {
849 dump_ir_block_edge(n);
850 dump_ir_data_edges(n);
854 dump_ir_graph (ir_graph *irg)
857 rem = current_ir_graph;
858 current_ir_graph = irg;
862 /* walk over the graph */
863 irg_walk(irg->end, dump_whole_node, NULL, NULL);
867 current_ir_graph = rem;
870 /***********************************************************************/
871 /* the following routines dump the nodes as attached to the blocks. */
872 /***********************************************************************/
875 dump_ir_blocks_nodes (ir_node *n, void *env) {
876 ir_node *block = (ir_node *)env;
878 if (is_no_Block(n) && get_nodes_Block(n) == block) {
880 dump_ir_data_edges(n);
882 if (get_irn_op(n) == op_Bad)
887 dump_ir_block (ir_node *block, void *env) {
888 ir_graph *irg = (ir_graph *)env;
890 if (get_irn_opcode(block) == iro_Block) {
892 /* This is a block. So dump the vcg information to make a block. */
893 xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \"");
895 xfprintf (F, "%ld", get_irn_node_nr(block));
897 xfprintf (F, "%I", block->op->name);
899 xfprintf(F, "\" status:clustered color:lightyellow \n");
900 /* dump the blocks edges */
901 dump_ir_data_edges(block);
903 /* dump the nodes that go into the block */
904 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
906 /* Close the vcg information for the block */
907 xfprintf(F, "}\n\n");
913 dump_blockless_nodes (ir_node *n, void *env) {
914 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
916 dump_ir_data_edges(n);
917 dump_ir_block_edge(n);
919 if (get_irn_op(n) == op_Bad)
923 void dump_ir_block_graph_2 (ir_graph *irg)
926 /* walk over the blocks in the graph */
927 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
929 /* dump all nodes that are not in a Block */
930 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
932 /* dump the Bad node */
934 dump_node(get_irg_bad(irg));
938 dump_ir_block_graph (ir_graph *irg)
941 rem = current_ir_graph;
942 current_ir_graph = irg;
946 dump_ir_block_graph_2 (irg);
949 current_ir_graph = rem;
953 /***********************************************************************/
954 /* the following routines dump a control flow graph */
955 /***********************************************************************/
959 dump_block_to_cfg (ir_node *block, void *env) {
963 if (get_irn_opcode(block) == iro_Block) {
964 /* This is a block. Dump a node for the block. */
965 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
968 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
969 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
970 xfprintf (F, "edge: { sourcename: \"");
972 fprintf (F, "\" targetname: \"");
974 fprintf (F, "\" }\n");
980 dump_cfg (ir_graph *irg)
982 vcg_open (irg, "-cfg");
984 /* walk over the blocks in the graph */
985 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
991 /***********************************************************************/
992 /* the following routine dumps all type information reachable from an */
994 /***********************************************************************/
998 dump_type_graph (ir_graph *irg)
1001 rem = current_ir_graph;
1002 current_ir_graph = irg;
1004 vcg_open (irg, "-type");
1006 /* walk over the blocks in the graph */
1007 type_walk_irg(irg, dump_type_info, NULL, NULL);
1008 /* The walker for the const code can be called several times for the
1009 same (sub) experssion. So that no nodes are dumped several times
1010 we decrease the visited flag of the corresponding graph after each
1011 walk. So now increase it finally. */
1012 inc_irg_visited(get_const_code_irg());
1015 current_ir_graph = rem;
1018 /***********************************************************************/
1019 /* the following routine dumps all type information */
1020 /***********************************************************************/
1024 dump_all_types (void)
1026 vcg_open_name ("All_types");
1027 type_walk(dump_type_info, NULL, NULL);
1028 inc_irg_visited(get_const_code_irg());
1032 /***********************************************************************/
1033 /* dumps a graph with type information */
1034 /***********************************************************************/
1038 dump_ir_graph_w_types (ir_graph *irg)
1041 rem = current_ir_graph;
1042 current_ir_graph = irg;
1044 vcg_open (irg, "-all");
1046 /* dump common ir graph */
1047 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1048 /* dump type info */
1049 type_walk_irg(irg, dump_type_info, NULL, NULL);
1050 inc_irg_visited(get_const_code_irg());
1051 /* dump edges from graph to type info */
1052 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1055 current_ir_graph = rem;
1059 dump_ir_block_graph_w_types (ir_graph *irg)
1062 rem = current_ir_graph;
1063 current_ir_graph = irg;
1065 vcg_open (irg, "-all");
1067 /* dump common blocked ir graph */
1068 dump_ir_block_graph_2(irg);
1069 /* dump type info */
1070 type_walk_irg(irg, dump_type_info, NULL, NULL);
1071 inc_irg_visited(get_const_code_irg());
1072 /* dump edges from graph to type info */
1073 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1076 current_ir_graph = rem;
1079 /***********************************************************************/
1080 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1082 /* dump_ir_block_graph */
1084 /* dump_type_graph */
1085 /* dump_ir_graph_w_types */
1086 /***********************************************************************/
1087 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1089 for (i=0; i < get_irp_n_irgs(); i++) {
1090 dump_graph(get_irp_irg(i));
1095 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1096 abort with a segmentation fault. */
1097 void turn_of_edge_labels() {
1101 void dump_constant_entity_values() {