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 /* dumps a type or entity and it's edges. */
536 dump_type_info (type_or_ent *tore, void *env) {
537 int i = 0; /* to shutup gcc */
539 /* dump this type or entity */
540 xfprintf (F, "node: {title: \"%p\" ", tore);
541 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
542 xfprintf (F, "label: ");
544 switch (get_kind(tore)) {
547 entity *ent = (entity *)tore;
550 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
551 if(dynamic_allocated == get_entity_allocation(ent))
552 xfprintf (F, " info1:\"dynamic allocated\n");
554 xfprintf (F, " info1:\"static allocated\n");
555 switch (get_entity_visibility(ent)) {
556 case local: fprintf (F, "local\n"); break;
557 case external_visible: fprintf (F, "external_visible\n"); break;
558 case external_allocated: fprintf (F, "external_allocate\nd");break;
560 switch (get_entity_variability(ent)) {
561 case uninitialized: fprintf (F, "uninitialized");break;
562 case initialized: fprintf (F, "initialized"); break;
563 case part_constant: fprintf (F, "part_constant");break;
564 case constant: fprintf (F, "constant"); break;
566 xfprintf(F, "\"}\n");
568 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
569 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));
570 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
571 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
572 for(i = 0; i < get_entity_n_overwrites(ent); i++)
573 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
574 ENT_OVERWRITES_EDGE_ATTR "}\n", ent, get_entity_overwrites(ent, i));
575 /* attached subgraphs */
576 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
577 if (is_atomic_entity(ent)) {
578 value = get_atomic_ent_value(ent);
579 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
581 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
582 dump_const_expression(value);
584 if (is_compound_entity(ent)) {
585 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
586 value = get_compound_ent_value(ent, i);
587 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
589 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
590 dump_const_expression(value);
591 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
592 ENT_CORR_EDGE_ATTR "}\n", ent,
593 get_compound_ent_value_member(ent, i), i);
600 type *tp = (type *)tore;
601 xfprintf (F, "\"%I %I", get_type_tpop_nameid(tp), get_type_ident(tp));
603 switch (get_type_tpop_code(tp)) {
606 xfprintf (F, "\" " TYPE_CLASS_NODE_ATTR "}\n");
607 for (i=0; i < get_class_n_supertype(tp); i++)
608 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
609 TYPE_SUPER_EDGE_ATTR "}\n",
610 tp, get_class_supertype(tp, i));
611 for (i=0; i < get_class_n_member(tp); i++)
612 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
613 TYPE_MEMBER_EDGE_ATTR "}\n",
614 tp, get_class_member(tp, i));
618 xfprintf (F, "\"}\n");
619 for (i=0; i < get_struct_n_member(tp); i++)
620 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
621 TYPE_MEMBER_EDGE_ATTR "}\n",
622 tp, get_struct_member(tp, i));
626 xfprintf (F, "\" " TYPE_METH_NODE_ATTR "}\n");
627 for (i = 0; i < get_method_n_params(tp); i++)
628 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
629 METH_PAR_EDGE_ATTR "}\n",
630 tp, get_method_param_type(tp, i), i);
631 for (i = 0; i < get_method_n_res(tp); i++)
632 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
633 METH_RES_EDGE_ATTR "}\n",
634 tp, get_method_res_type(tp, i), i);
638 xfprintf (F, "\"}\n");
639 for (i = 0; i < get_union_n_members(tp); i++)
640 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
641 "label: \"\"f" UNION_EDGE_ATTR "}\n",
642 tp, get_union_member(tp, i));
646 xfprintf (F, "\"}\n");
647 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
648 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
649 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
650 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
652 case tpo_enumeration:
654 xfprintf (F, "\"}\n");
658 xfprintf (F, "\"}\n");
659 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
660 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
661 get_pointer_points_to_type(tp), i);
665 xfprintf (F, " (mode %I)\"}\n", get_mode_ident(get_type_mode(tp)));
670 break; /* case k_type */
673 xfprintf (F, "\" faulty type \"}\n");
674 printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
676 } /* switch kind_or_entity */
679 /************************************************************************/
680 /* open and close vcg file */
681 /************************************************************************/
683 void vcg_open (ir_graph *irg, char *suffix) {
684 char *fname; /* filename to put the vcg information in */
690 /** open file for vcg graph */
691 id = get_entity_ld_ident (get_irg_ent(irg));
692 len = id_to_strlen (id);
695 fname = malloc (len + 5 + strlen(suffix));
696 strncpy (fname, cp, len); /* copy the filename */
698 strcat (fname, suffix); /* append file suffix */
700 fname = malloc (len + 5 + strlen(suffix));
701 strncpy (fname, cp, len); /* copy the filename */
702 fname[len] = '\0'; /* ensure string termination */
703 /*strcpy (fname, cp); * copy the filename *
704 this produces wrong, too long strings in conjuction with the
705 jocca frontend. The \0 seems to be missing. */
706 strcat (fname, suffix); /* append file suffix */
707 strcat (fname, ".vcg"); /* append the .vcg suffix */
708 F = fopen (fname, "w"); /* open file for writing */
710 panic ("cannot open %s for writing (%m)", fname); /* not reached */
714 strcpy(label, "yes");
716 strcpy (label, "no");
721 "graph: { title: \"ir graph of %s\"\n"
722 "display_edge_labels: %s\n"
723 "layoutalgorithm: mindepth\n"
724 "manhattan_edges: yes\n"
726 "orientation: bottom_to_top\n"
727 "classname 1: \"Data\"\n"
728 "classname 2: \"Block\"\n"
729 "classname 3: \"Entity type\""
730 "classname 4: \"Entity owner\""
731 "classname 5: \"Method Param\""
732 "classname 6: \"Method Res\""
733 "classname 7: \"Super\""
734 "classname 8: \"Union\""
735 "classname 9: \"Points-to\""
736 "classname 10: \"Array Element Type\""
737 "classname 11: \"Overwrites\""
738 "classname 12: \"Member\""
741 xfprintf (F, "\n"); /* a separator */
744 void vcg_open_name (const char *name) {
745 char *fname; /* filename to put the vcg information in */
749 /** open file for vcg graph */
751 fname = malloc (len + 5);
752 strcpy (fname, name); /* copy the filename */
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\"\n"
776 "classname 4: \"Entity owner\"\n"
777 "classname 5: \"Method Param\"\n"
778 "classname 6: \"Method Res\"\n"
779 "classname 7: \"Super\"\n"
780 "classname 8: \"Union\"\n"
781 "classname 9: \"Points-to\"\n"
782 "classname 10: \"Array Element Type\"\n"
783 "classname 11: \"Overwrites\"\n"
784 "classname 12: \"Member\"\n"
787 xfprintf (F, "\n"); /* a separator */
792 xfprintf (F, "}\n"); /* print footer */
793 fclose (F); /* close vcg file */
796 /************************************************************************/
797 /* routines to dump a graph, blocks as conventional nodes. */
798 /************************************************************************/
801 dump_whole_node (ir_node *n, void* env) {
803 dump_ir_block_edge(n);
804 dump_ir_data_edges(n);
808 dump_ir_graph (ir_graph *irg)
811 rem = current_ir_graph;
812 current_ir_graph = irg;
816 /* walk over the graph */
817 irg_walk(irg->end, dump_whole_node, NULL, NULL);
821 current_ir_graph = rem;
824 /***********************************************************************/
825 /* the following routines dump the nodes as attached to the blocks. */
826 /***********************************************************************/
829 dump_ir_blocks_nodes (ir_node *n, void *env) {
830 ir_node *block = (ir_node *)env;
832 if (is_no_Block(n) && get_nodes_Block(n) == block) {
834 dump_ir_data_edges(n);
836 if (get_irn_op(n) == op_Bad)
841 dump_ir_block (ir_node *block, void *env) {
842 ir_graph *irg = (ir_graph *)env;
844 if (get_irn_opcode(block) == iro_Block) {
846 /* This is a block. So dump the vcg information to make a block. */
847 xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \"");
849 xfprintf (F, "%ld", get_irn_node_nr(block));
851 xfprintf (F, "%I", block->op->name);
853 xfprintf(F, "\" status:clustered color:lightyellow \n");
854 /* dump the blocks edges */
855 dump_ir_data_edges(block);
857 /* dump the nodes that go into the block */
858 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
860 /* Close the vcg information for the block */
861 xfprintf(F, "}\n\n");
867 dump_blockless_nodes (ir_node *n, void *env) {
868 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
870 dump_ir_data_edges(n);
871 dump_ir_block_edge(n);
873 if (get_irn_op(n) == op_Bad)
877 void dump_ir_block_graph_2 (ir_graph *irg)
880 /* walk over the blocks in the graph */
881 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
883 /* dump all nodes that are not in a Block */
884 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
886 /* dump the Bad node */
888 dump_node(get_irg_bad(irg));
892 dump_ir_block_graph (ir_graph *irg)
895 rem = current_ir_graph;
896 current_ir_graph = irg;
900 dump_ir_block_graph_2 (irg);
903 current_ir_graph = rem;
907 /***********************************************************************/
908 /* the following routines dump a control flow graph */
909 /***********************************************************************/
913 dump_block_to_cfg (ir_node *block, void *env) {
917 if (get_irn_opcode(block) == iro_Block) {
918 /* This is a block. Dump a node for the block. */
919 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
922 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
923 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
924 xfprintf (F, "edge: { sourcename: \"");
926 fprintf (F, "\" targetname: \"");
928 fprintf (F, "\" }\n");
934 dump_cfg (ir_graph *irg)
936 vcg_open (irg, "-cfg");
938 /* walk over the blocks in the graph */
939 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
945 /***********************************************************************/
946 /* the following routine dumps all type information reachable from an */
948 /***********************************************************************/
952 dump_type_graph (ir_graph *irg)
955 rem = current_ir_graph;
956 current_ir_graph = irg;
958 vcg_open (irg, "-type");
960 /* walk over the blocks in the graph */
961 type_walk_irg(irg, dump_type_info, NULL, NULL);
962 /* The walker for the const code can be called several times for the
963 same (sub) experssion. So that no nodes are dumped several times
964 we decrease the visited flag of the corresponding graph after each
965 walk. So now increase it finally. */
966 inc_irg_visited(get_const_code_irg());
969 current_ir_graph = rem;
972 /***********************************************************************/
973 /* the following routine dumps all type information */
974 /***********************************************************************/
978 dump_all_types (void)
980 vcg_open_name ("All_types");
981 type_walk(dump_type_info, NULL, NULL);
982 inc_irg_visited(get_const_code_irg());
986 /***********************************************************************/
987 /* dumps a graph with type information */
988 /***********************************************************************/
992 dump_ir_graph_w_types (ir_graph *irg)
995 rem = current_ir_graph;
996 current_ir_graph = irg;
998 vcg_open (irg, "-all");
1000 /* dump common ir graph */
1001 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1002 /* dump type info */
1003 type_walk_irg(irg, dump_type_info, NULL, NULL);
1004 inc_irg_visited(get_const_code_irg());
1005 /* dump edges from graph to type info */
1006 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1009 current_ir_graph = rem;
1013 dump_ir_block_graph_w_types (ir_graph *irg)
1016 rem = current_ir_graph;
1017 current_ir_graph = irg;
1019 vcg_open (irg, "-all");
1021 /* dump common blocked ir graph */
1022 dump_ir_block_graph_2(irg);
1023 /* dump type info */
1024 type_walk_irg(irg, dump_type_info, NULL, NULL);
1025 inc_irg_visited(get_const_code_irg());
1026 /* dump edges from graph to type info */
1027 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1030 current_ir_graph = rem;
1033 /***********************************************************************/
1034 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1036 /* dump_ir_block_graph */
1038 /* dump_type_graph */
1039 /* dump_ir_graph_w_types */
1040 /***********************************************************************/
1041 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1043 for (i=0; i < get_irp_n_irgs(); i++) {
1044 dump_graph(get_irp_irg(i));
1049 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1050 abort with a segmentation fault. */
1051 void turn_of_edge_labels() {
1055 void dump_constant_entity_values() {