1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
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 "firm_common_t.h"
38 /* Attributes of nodes */
39 #define DEFAULT_NODE_ATTR ""
40 #define DEFAULT_TYPE_ATTRIBUTE ""
42 /* Attributes of edges between Firm nodes */
43 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
44 #define CF_EDGE_ATTR "color: red"
45 #define MEM_EDGE_ATTR "color: blue"
46 #define DOMINATOR_EDGE_ATTR "color: red"
48 #define BACK_EDGE_ATTR "linestyle: dashed "
50 /* Attributes of edges between Firm nodes and type/entity nodes */
51 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
53 /* Attributes of edges in type/entity graphs. */
54 #define TYPE_METH_NODE_ATTR "color: lightyellow"
55 #define TYPE_CLASS_NODE_ATTR "color: green"
56 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
57 #define ENTITY_NODE_ATTR "color: yellow"
58 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
59 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
60 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
61 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
62 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
63 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
64 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
65 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
66 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
67 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
68 #define ENT_VALUE_EDGE_ATTR "label: \"value "
69 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
70 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
73 #if DEBUG_libfirm && NODEID_AS_LABEL
74 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
75 #define PRINT_TYPEID(X) fprintf(F, "t%ld", get_type_nr(X))
76 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
77 #define PRINT_IRGID(X) fprintf(F,"g%ld", get_irg_graph_nr(X))
79 #define PRINT_NODEID(X) fprintf(F, "%p", X)
80 #define PRINT_TYPEID(X) fprintf(F, "%p", X)
81 #define PRINT_ENTID(X) fprintf(F, "%p", X)
82 #define PRINT_IRGID(X) fprintf(F,"%p",X)
85 #define PRINT_TYPE_TYPE_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_TYPEID(S); fprintf (F, "\" targetname: \""); PRINT_TYPEID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
86 #define PRINT_TYPE_ENT_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_TYPEID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
87 #define PRINT_ENT_ENT_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
88 #define PRINT_ENT_TYPE_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_TYPEID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
91 /* A suffix to manipulate the file name. */
92 char *dump_file_suffix = NULL;
97 /* A compiler option to turn off edge labels */
99 /* A compiler option to turn off dumping values of constant entities */
100 int const_entities = 1;
101 /* A compiler option to dump the keep alive edges */
102 int dump_keepalive = 0;
103 /* Compiler options to dump analysis information in dump_ir_graph */
104 int dump_out_edge_flag = 0;
105 int dump_dominator_information_flag = 0;
106 int dump_loop_information_flag = 0;
107 int dump_const_local = 0;
109 static INLINE bool dump_const_local_set(void) {
110 if (!dump_out_edge_flag && !dump_loop_information_flag)
111 return dump_const_local;
116 /* A global variable to record output of the Bad node. */
117 static int Bad_dumped;
119 static void dump_ir_blocks_nodes (ir_node *n, void *env);
120 static void dump_whole_node(ir_node *n, void* env);
122 /*******************************************************************/
123 /* routines to dump information about a single node */
124 /*******************************************************************/
129 dump_node_opcode (ir_node *n)
134 if (n->op->code == iro_Const) {
135 xfprintf (F, "%v", n->attr.con);
138 } else if (n->op->code == iro_SymConst) {
139 if (get_SymConst_kind(n) == linkage_ptr_info) {
140 /* don't use get_SymConst_ptr_info as it mangles the name. */
141 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
143 assert(get_kind(get_SymConst_type(n)) == k_type);
144 assert(get_type_ident(get_SymConst_type(n)));
145 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
146 if (get_SymConst_kind(n) == type_tag)
153 } else if (n->op->code == iro_Filter && !interprocedural_view) {
158 xfprintf (F, "%I", get_irn_opident(n));
163 dump_node_mode (ir_node *n)
165 switch (n->op->code) {
183 xfprintf (F, "%I", get_mode_ident(n->mode));
191 dump_node_nodeattr (ir_node *n)
193 switch (n->op->code) {
195 if (false && interprocedural_view) {
196 xfprintf (F, "%I", get_entity_ident(get_irg_ent(current_ir_graph)));
200 if (n->in[1]->op->code == iro_Cmp) {
201 fprintf (F, "%s", get_pnc_string(n->attr.proj));
203 xfprintf (F, "%ld", n->attr.proj);
207 xfprintf (F, "%ld", n->attr.filter.proj);
210 assert(get_kind(get_Sel_entity(n)) == k_entity);
211 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
219 dump_node_vcgattr (ir_node *n)
221 switch (n->op->code) {
228 fprintf (F, "color: blue");
231 fprintf (F, "color: lightyellow");
234 fprintf (F, "color: green");
240 fprintf (F, "color: yellow");
243 xfprintf (F, DEFAULT_NODE_ATTR);
247 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
248 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
251 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
252 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
253 if (is_ip_cfop(pred)) {
254 ir_graph *irg = get_ip_cfop_irg(pred);
255 if (pmap_find(irgmap, irg) == NULL) return true;
264 bool is_constlike_node(ir_node *n) {
265 ir_op *op = get_irn_op(n);
266 return (op == op_Const || op == op_Bad || op == op_SymConst);
270 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
272 if (!dump_const_local_set()) return;
273 /* Use visited flag to avoid outputting nodes twice.
274 initialize it first. */
275 for (i = 0; i < get_irn_arity(n); i++) {
276 ir_node *con = get_irn_n(n, i);
277 if (is_constlike_node(con)) {
278 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
279 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
282 for (i = 0; i < get_irn_arity(n); i++) {
283 ir_node *con = get_irn_n(n, i);
284 if (is_constlike_node(con) && irn_not_visited(con)) {
285 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
286 mark_irn_visited(con);
287 /* Generate a new name for the node by appending the names of
289 fprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
290 fprintf(F, "\" label: \"");
291 dump_node_opcode(con);
292 dump_node_mode (con);
294 dump_node_nodeattr(con);
296 xfprintf (F, " %ld", get_irn_node_nr(con));
299 dump_node_vcgattr(con);
306 dump_node (ir_node *n, pmap * map) {
307 if (dump_const_local_set() && is_constlike_node(n)) return;
310 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
315 dump_node_nodeattr(n);
317 xfprintf (F, " %ld", get_irn_node_nr(n));
320 dump_node_vcgattr(n);
322 dump_const_node_local(n, map);
326 dump_ir_node (ir_node *n)
329 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
331 switch (n->op->code) { /* node label */
333 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
334 xfprintf (F, DEFAULT_NODE_ATTR);
341 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
342 xfprintf (F, DEFAULT_NODE_ATTR);
345 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
346 xfprintf (F, DEFAULT_NODE_ATTR);
349 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
350 if (get_irn_modecode(n) == irm_M)
351 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
353 xfprintf (F, DEFAULT_NODE_ATTR);
356 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
357 xfprintf (F, DEFAULT_NODE_ATTR);
360 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
361 xfprintf (F, DEFAULT_NODE_ATTR);
364 if (n->in[1]->op->code == iro_Cmp) {
365 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
366 get_pnc_string(n->attr.proj));
368 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
370 xfprintf (F, DEFAULT_NODE_ATTR);
373 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
374 xfprintf (F, DEFAULT_NODE_ATTR);
377 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
378 xfprintf (F, DEFAULT_NODE_ATTR);
381 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
382 xfprintf (F, DEFAULT_NODE_ATTR);
385 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
386 xfprintf (F, DEFAULT_NODE_ATTR);
389 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
390 xfprintf (F, DEFAULT_NODE_ATTR);
393 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
394 xfprintf (F, DEFAULT_NODE_ATTR);
397 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
398 xfprintf (F, DEFAULT_NODE_ATTR);
401 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
402 xfprintf (F, DEFAULT_NODE_ATTR);
405 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
406 xfprintf (F, DEFAULT_NODE_ATTR);
409 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
410 xfprintf (F, DEFAULT_NODE_ATTR);
413 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
414 xfprintf (F, DEFAULT_NODE_ATTR);
417 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
418 xfprintf (F, DEFAULT_NODE_ATTR);
421 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
422 xfprintf (F, DEFAULT_NODE_ATTR);
425 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
426 xfprintf (F, DEFAULT_NODE_ATTR);
429 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
430 xfprintf (F, DEFAULT_NODE_ATTR);
433 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
434 xfprintf (F, DEFAULT_NODE_ATTR);
437 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
438 xfprintf (F, DEFAULT_NODE_ATTR);
441 xfprintf (F, "\"%I\"", get_irn_opident(n));
442 xfprintf (F, DEFAULT_NODE_ATTR);
445 xfprintf (F, "\"%I\"", get_irn_opident(n));
446 xfprintf (F, DEFAULT_NODE_ATTR);
449 xfprintf (F, "\"%I\"", get_irn_opident(n));
450 xfprintf (F, DEFAULT_NODE_ATTR);
453 xfprintf (F, "\"%I\"", get_irn_opident(n));
454 xfprintf (F, DEFAULT_NODE_ATTR);
457 xfprintf (F, "\"%I\"", get_irn_opident(n));
458 xfprintf (F, DEFAULT_NODE_ATTR);
461 xfprintf (F, "\"%I\"", get_irn_opident(n));
462 xfprintf (F, DEFAULT_NODE_ATTR);
465 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
466 xfprintf (F, DEFAULT_NODE_ATTR);
470 xfprintf (F, "\"%R\"", n);
471 xfprintf (F, DEFAULT_NODE_ATTR);
474 xfprintf (F, "\"%I\" ", get_irn_opident(n));
475 xfprintf (F, DEFAULT_NODE_ATTR);
478 assert(get_kind(get_Sel_entity(n)) == k_entity);
479 xfprintf (F, "\"%I ", get_irn_opident(n));
480 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
481 xfprintf (F, DEFAULT_NODE_ATTR);
484 assert(get_kind(get_SymConst_type(n)) == k_type);
485 assert(get_type_ident(get_SymConst_type(n)));
486 fprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
487 switch (n->attr.i.num){
489 fprintf (F, "tag\" ");
492 fprintf (F, "size\" ");
498 xfprintf (F, DEFAULT_NODE_ATTR);
501 xfprintf (F, "\"%I\" ", get_irn_opident(n));
502 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
505 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
506 xfprintf (F, DEFAULT_NODE_ATTR);
509 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
510 xfprintf (F, DEFAULT_NODE_ATTR);
513 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
515 fprintf (F, "}\n"); /* footer */
519 /* dump the edge to the block this node belongs to */
521 dump_ir_block_edge(ir_node *n) {
522 if (dump_const_local_set() && is_constlike_node(n)) return;
523 if (is_no_Block(n)) {
524 fprintf (F, "edge: { sourcename: \"");
526 fprintf (F, "\" targetname: \"");
527 PRINT_NODEID(get_nodes_Block(n));
528 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
532 static void print_edge_vcgattr(ir_node *from, int to) {
535 if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
537 switch (get_irn_opcode(from)) {
539 xfprintf (F, CF_EDGE_ATTR);
541 case iro_Start: break;
544 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
545 xfprintf (F, CF_EDGE_ATTR);
546 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
547 xfprintf (F, MEM_EDGE_ATTR);
550 case iro_EndReg: break;
551 case iro_EndExcept: break;
553 case iro_Break: break;
554 case iro_Cond: break;
557 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
559 case iro_Const: break;
560 case iro_SymConst:break;
563 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
565 case iro_CallBegin: break;
568 case iro_Minus: break;
574 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
582 case iro_Shrs: break;
585 case iro_Conv: break;
587 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
593 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
596 xfprintf (F, MEM_EDGE_ATTR);
598 case iro_Tuple: break;
601 switch (get_irn_modecode(from)) {
603 xfprintf (F, CF_EDGE_ATTR);
606 xfprintf (F, MEM_EDGE_ATTR);
612 case iro_Unknown: break;
619 /* dump edges to our inputs */
621 dump_ir_data_edges(ir_node *n) {
622 int i, visited = get_irn_visited(n);
624 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
627 for (i = 0; i < get_irn_arity(n); i++) {
628 ir_node * pred = get_irn_n(n, i);
630 if ((interprocedural_view && get_irn_visited(pred) < visited))
631 continue; /* pred not dumped */
632 if (is_backedge(n, i))
633 fprintf (F, "backedge: {sourcename: \"");
635 fprintf (F, "edge: {sourcename: \"");
637 fprintf (F, "\" targetname: \"");
638 if ((dump_const_local_set()) && is_constlike_node(pred))
642 fprintf (F, " label: \"%d\" ", i);
643 print_edge_vcgattr(n, i);
650 dump_out_edge (ir_node *n, void* env) {
652 for (i = 0; i < get_irn_n_outs(n); i++) {
653 assert(get_irn_out(n, i));
654 fprintf (F, "edge: {sourcename: \"");
656 fprintf (F, "\" targetname: \"");
657 PRINT_NODEID(get_irn_out(n, i));
658 fprintf (F, "\" color: red linestyle: dashed");
664 dump_loop_node_edge (ir_loop *loop, int i) {
666 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", loop);
667 PRINT_NODEID(get_loop_node(loop, i));
668 fprintf (F, "\" color: green");
673 void dump_loops (ir_loop *loop) {
675 /* dump this loop node */
676 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
677 loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
678 /* dump edges to nodes in loop -- only if it is a real loop */
679 if (get_loop_depth(loop) != 0) {
680 for (i = 0; i < get_loop_n_nodes(loop); i++) {
681 dump_loop_node_edge(loop, i);
684 for (i = 0; i < get_loop_n_sons(loop); i++) {
685 dump_loops(get_loop_son(loop, i));
690 void dump_loop_info(ir_graph *irg) {
691 ir_graph *rem = current_ir_graph;
692 current_ir_graph = irg;
694 if (get_irg_loop(irg))
695 dump_loops(get_irg_loop(irg));
697 current_ir_graph = rem;
701 /* dumps the edges between nodes and their type or entity attributes. */
702 static void dump_node2type_edges (ir_node *n, void *env)
706 switch (get_irn_opcode(n)) {
708 /* @@@ some consts have an entity */
711 if ( (get_SymConst_kind(n) == type_tag)
712 || (get_SymConst_kind(n) == size)) {
713 fprintf (F, "edge: { sourcename: \"");
715 fprintf (F, "\" targetname: \"%p\" "
716 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
720 fprintf (F, "edge: { sourcename: \"");
722 fprintf (F, "\" targetname: \"%p\" "
723 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
726 fprintf (F, "edge: { sourcename: \"");
728 fprintf (F, "\" targetname: \"%p\" "
729 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
732 fprintf (F, "edge: { sourcename: \"");
734 fprintf (F, "\" targetname: \"%p\" "
735 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
738 fprintf (F, "edge: { sourcename: \"");
740 fprintf (F, "\" targetname: \"%p\" "
741 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
749 static void dump_const_expression(ir_node *value) {
750 ir_graph *rem = current_ir_graph;
751 int rem_dump_const_local = dump_const_local;
752 dump_const_local = 0;
753 current_ir_graph = get_const_code_irg();
754 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
755 /* Decrease visited flag so that we walk with the same flag for the next
756 expresssion. This guarantees that we don't dump the same node twice,
757 as for const expressions cse is performed to save memory. */
758 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
759 current_ir_graph = rem;
760 dump_const_local = rem_dump_const_local;
764 static void print_type_info(type *tp) {
765 if (get_type_state(tp) == layout_undefined) {
766 fprintf(F, "state: layout_undefined\n");
768 fprintf(F, "state: layout_fixed,\n");
770 if (get_type_mode(tp))
771 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
772 fprintf(F, "size: %dB,\n", get_type_size(tp));
776 static void print_typespecific_info(type *tp) {
777 switch (get_type_tpop_code(tp)) {
780 if(existent == get_class_peculiarity(tp))
781 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
783 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
787 xfprintf (F, " " TYPE_METH_NODE_ATTR);
798 case tpo_enumeration:
811 static void print_type_node(type *tp) {
812 xfprintf (F, "node: {title: \"");
814 xfprintf (F, "\" label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
815 xfprintf (F, "info1: \"");
818 print_typespecific_info(tp);
822 void dump_entity_node(entity *ent) {
823 xfprintf (F, "node: {title: \"");
825 xfprintf (F, "\"" DEFAULT_TYPE_ATTRIBUTE);
826 xfprintf (F, "label: ");
827 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
828 fprintf (F, "\n info1:\"\nallocation: ");
829 switch (get_entity_allocation(ent)) {
830 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
831 case automatic_allocated: fprintf (F, "automatic allocated"); break;
832 case static_allocated: fprintf (F, "static allocated"); break;
833 case parameter_allocated: fprintf (F, "parameter allocated"); break;
835 fprintf (F, "\nvisibility: ");
836 switch (get_entity_visibility(ent)) {
837 case local: fprintf (F, "local"); break;
838 case external_visible: fprintf (F, "external_visible"); break;
839 case external_allocated: fprintf (F, "external_allocate"); break;
841 fprintf (F, "\nvariability: ");
842 switch (get_entity_variability(ent)) {
843 case uninitialized: fprintf (F, "uninitialized");break;
844 case initialized: fprintf (F, "initialized"); break;
845 case part_constant: fprintf (F, "part_constant");break;
846 case constant: fprintf (F, "constant"); break;
848 fprintf (F, "\nvolatility: ");
849 switch (get_entity_volatility(ent)) {
850 case non_volatile: fprintf (F, "non_volatile"); break;
851 case is_volatile: fprintf (F, "is_volatile"); break;
853 fprintf (F, "\npeculiarity: ");
854 switch (get_entity_peculiarity(ent)) {
855 case description: fprintf (F, "description"); break;
856 case inherited: fprintf (F, "inherited"); break;
857 case existent: fprintf (F, "existent"); break;
859 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
860 fprintf(F, "\noffset: %d", get_entity_offset(ent));
861 if (is_method_type(get_entity_type(ent)))
862 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
863 fprintf(F, "\"\n}\n");
866 /* dumps a type or entity and it's edges. */
868 dump_type_info (type_or_ent *tore, void *env) {
869 int i = 0; /* to shutup gcc */
871 /* dump this type or entity */
873 switch (get_kind(tore)) {
876 entity *ent = (entity *)tore;
879 dump_entity_node(ent);
881 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
882 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
883 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
884 PRINT_ENT_TYPE_EDGE(ent,get_entity_type(ent),ENT_TYPE_EDGE_ATTR);
885 if(is_class_type(get_entity_owner(ent))) {
886 for(i = 0; i < get_entity_n_overwrites(ent); i++){
887 PRINT_ENT_ENT_EDGE(ent,get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
890 /* attached subgraphs */
891 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
892 if (is_atomic_entity(ent)) {
893 value = get_atomic_ent_value(ent);
895 fprintf (F, "edge: { sourcename: \"");
897 fprintf (F, "\" targetname: \"");
899 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
901 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"", GET_ENTID(ent));
903 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
905 dump_const_expression(value);
908 if (is_compound_entity(ent)) {
909 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
910 value = get_compound_ent_value(ent, i);
912 fprintf (F, "edge: { sourcename: \"");
914 fprintf (F, "\" targetname: \"");
916 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
917 dump_const_expression(value);
918 PRINT_ENT_ENT_EDGE(ent,get_compound_ent_value_member(ent, i),ENT_CORR_EDGE_ATTR,i);
920 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
921 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
922 get_compound_ent_value_member(ent, i), i);
932 type *tp = (type *)tore;
937 /* and now the edges */
938 switch (get_type_tpop_code(tp)) {
941 for (i=0; i < get_class_n_supertypes(tp); i++)
943 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
946 for (i=0; i < get_class_n_members(tp); i++)
948 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
953 for (i=0; i < get_struct_n_members(tp); i++)
955 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
960 for (i = 0; i < get_method_n_params(tp); i++)
962 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
964 for (i = 0; i < get_method_n_ress(tp); i++)
966 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
971 for (i = 0; i < get_union_n_members(tp); i++)
973 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
978 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
979 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
981 case tpo_enumeration:
986 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
994 break; /* case k_type */
997 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
999 } /* switch kind_or_entity */
1002 /* dumps a class type node and a superclass edge.
1003 If env != null dumps entities of classes and overwrites edges. */
1005 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1006 int i = 0; /* to shutup gcc */
1008 /* dump this type or entity */
1009 switch (get_kind(tore)) {
1011 entity *ent = (entity *)tore;
1012 if (get_entity_owner(ent) == get_glob_type()) break;
1013 if ((env) && is_class_type(get_entity_owner(ent))) {
1015 dump_entity_node(ent);
1017 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1018 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1020 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1023 } break; /* case k_entity */
1026 type *tp = (type *)tore;
1027 if (tp == get_glob_type()) break;
1028 switch (get_type_tpop_code(tp)) {
1030 print_type_node(tp);
1031 /* and now the edges */
1032 for (i=0; i < get_class_n_supertypes(tp); i++)
1034 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1040 break; /* case k_type */
1043 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1045 } /* switch kind_or_entity */
1048 /************************************************************************/
1049 /* open and close vcg file */
1050 /************************************************************************/
1052 static void vcg_open (ir_graph *irg, char *suffix) {
1053 char *fname; /* filename to put the vcg information in */
1060 /** open file for vcg graph */
1061 ent = get_irg_ent(irg);
1062 id = ent->ld_name ? ent->ld_name : ent->name;
1063 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1064 len = id_to_strlen (id);
1065 cp = id_to_str (id);
1066 if (dump_file_suffix)
1067 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1069 fname = malloc (len + 5 + strlen(suffix));
1070 strncpy (fname, cp, len); /* copy the filename */
1072 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1073 strcat (fname, suffix); /* append file suffix */
1074 strcat (fname, ".vcg"); /* append the .vcg suffix */
1075 F = fopen (fname, "w"); /* open file for writing */
1077 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1081 strcpy(label, "yes");
1083 strcpy (label, "no");
1088 "graph: { title: \"ir graph of %s\"\n"
1089 "display_edge_labels: %s\n"
1090 "layoutalgorithm: mindepth\n"
1091 "manhattan_edges: yes\n"
1092 "port_sharing: no\n"
1093 "orientation: bottom_to_top\n"
1094 "classname 1: \"Data\"\n"
1095 "classname 2: \"Block\"\n"
1096 "classname 3: \"Entity type\""
1097 "classname 4: \"Entity owner\""
1098 "classname 5: \"Method Param\""
1099 "classname 6: \"Method Res\""
1100 "classname 7: \"Super\""
1101 "classname 8: \"Union\""
1102 "classname 9: \"Points-to\""
1103 "classname 10: \"Array Element Type\""
1104 "classname 11: \"Overwrites\""
1105 "classname 12: \"Member\""
1108 fprintf (F, "\n"); /* a separator */
1111 static void vcg_open_name (const char *name) {
1112 char *fname; /* filename to put the vcg information in */
1116 /** open file for vcg graph */
1118 fname = malloc (len + 5);
1119 if (dump_file_suffix)
1120 fname = malloc (len + 5 + strlen(dump_file_suffix));
1122 fname = malloc (len + 5);
1123 strcpy (fname, name); /* copy the filename */
1124 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1125 strcat (fname, ".vcg"); /* append the .vcg suffix */
1126 F = fopen (fname, "w"); /* open file for writing */
1128 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1132 strcpy(label, "yes");
1134 strcpy (label, "no");
1139 "graph: { title: \"ir graph of %s\"\n"
1140 "display_edge_labels: %s\n"
1141 "layoutalgorithm: mindepth\n"
1142 "manhattan_edges: yes\n"
1143 "port_sharing: no\n"
1144 "orientation: bottom_to_top\n"
1145 "classname 1: \"Data\"\n"
1146 "classname 2: \"Block\"\n"
1147 "classname 3: \"Entity type\"\n"
1148 "classname 4: \"Entity owner\"\n"
1149 "classname 5: \"Method Param\"\n"
1150 "classname 6: \"Method Res\"\n"
1151 "classname 7: \"Super\"\n"
1152 "classname 8: \"Union\"\n"
1153 "classname 9: \"Points-to\"\n"
1154 "classname 10: \"Array Element Type\"\n"
1155 "classname 11: \"Overwrites\"\n"
1156 "classname 12: \"Member\"\n"
1159 fprintf (F, "\n"); /* a separator */
1164 fprintf (F, "}\n"); /* print footer */
1165 fclose (F); /* close vcg file */
1168 /************************************************************************/
1169 /* routines to dump a graph, blocks as conventional nodes. */
1170 /************************************************************************/
1172 static int node_floats(ir_node *n) {
1173 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1174 (get_irg_pinned(current_ir_graph) == floats));
1178 dump_whole_node (ir_node *n, void* env) {
1180 if (!node_floats(n)) dump_ir_block_edge(n);
1181 dump_ir_data_edges(n);
1185 dump_ir_graph (ir_graph *irg)
1188 rem = current_ir_graph;
1189 current_ir_graph = irg;
1193 /* walk over the graph */
1194 /* dump_whole_node must be called in post visiting predecessors */
1195 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1197 /* dump the out edges in a separate walk */
1198 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1199 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1204 current_ir_graph = rem;
1207 /***********************************************************************/
1208 /* the following routines dump the nodes as attached to the blocks. */
1209 /***********************************************************************/
1212 dump_ir_blocks_nodes (ir_node *n, void *env) {
1213 ir_node *block = (ir_node *)env;
1215 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1217 dump_ir_data_edges(n);
1219 if (get_irn_op(n) == op_Bad)
1224 dump_ir_block (ir_node *block, void *env) {
1225 ir_graph *irg = (ir_graph *)env;
1227 if (get_irn_opcode(block) == iro_Block) {
1229 /* This is a block. So dump the vcg information to make a block. */
1230 fprintf(F, "graph: { title: \"");
1231 PRINT_NODEID(block);
1232 fprintf(F, "\" label: \"");
1233 #ifdef DEBUG_libfirm
1234 fprintf (F, "%ld", get_irn_node_nr(block));
1236 xfprintf (F, "%I", block->op->name);
1238 if (exc_normal != get_Block_exc (block))
1239 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1241 fprintf(F, "\" status:clustered color:%s \n",
1242 get_Block_matured (block) ? "yellow" : "red");
1243 /* dump the blocks edges */
1244 dump_ir_data_edges(block);
1246 /* dump the nodes that go into the block */
1247 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1249 /* Close the vcg information for the block */
1250 fprintf(F, "}\n\n");
1251 dump_const_node_local(block, NULL);
1257 dump_blockless_nodes (ir_node *n, void *env) {
1258 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1260 dump_ir_data_edges(n);
1261 dump_ir_block_edge(n);
1262 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1265 if (node_floats(n)) {
1267 dump_ir_data_edges(n);
1268 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1272 static void dump_ir_block_graph_2 (ir_graph *irg)
1275 /* walk over the blocks in the graph */
1276 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1278 /* dump all nodes that are not in a Block */
1279 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1281 /* dump the Bad node */
1283 dump_node(get_irg_bad(irg), NULL);
1287 dump_ir_block_graph (ir_graph *irg)
1290 rem = current_ir_graph;
1291 current_ir_graph = irg;
1295 dump_ir_block_graph_2 (irg);
1297 if (dump_loop_information_flag) dump_loop_info(irg);
1300 current_ir_graph = rem;
1304 /***********************************************************************/
1305 /* the following routines dump a control flow graph */
1306 /***********************************************************************/
1310 dump_block_to_cfg (ir_node *block, void *env) {
1314 if (get_irn_opcode(block) == iro_Block) {
1315 /* This is a block. Dump a node for the block. */
1316 fprintf (F, "node: {title:\""); PRINT_NODEID(block);
1317 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1319 if (exc_normal != get_Block_exc (block))
1320 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1323 if (dump_dominator_information_flag)
1324 fprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1326 /* Dump the edges */
1327 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1328 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1329 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1330 fprintf (F, "edge: { sourcename: \"");
1331 PRINT_NODEID(block);
1332 fprintf (F, "\" targetname: \"");
1334 fprintf (F, "\" }\n");
1337 /* Dump dominator edge */
1338 if (dump_dominator_information_flag && get_Block_idom(block)) {
1339 pred = get_Block_idom(block);
1340 fprintf (F, "edge: { sourcename: \"");
1341 PRINT_NODEID(block);
1342 fprintf (F, "\" targetname: \"");
1344 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1350 dump_cfg (ir_graph *irg)
1352 ir_graph *rem = current_ir_graph;
1353 int ddif = dump_dominator_information_flag;
1354 current_ir_graph = irg;
1355 vcg_open (irg, "-cfg");
1357 if (get_irg_dom_state(irg) != dom_consistent)
1358 dump_dominator_information_flag = 0;
1360 /* walk over the blocks in the graph */
1361 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1362 dump_ir_node (irg->bad);
1364 dump_dominator_information_flag = ddif;
1366 current_ir_graph = rem;
1370 /***********************************************************************/
1371 /* the following routine dumps all type information reachable from an */
1373 /***********************************************************************/
1377 dump_type_graph (ir_graph *irg)
1380 rem = current_ir_graph;
1381 current_ir_graph = irg;
1383 vcg_open (irg, "-type");
1385 /* walk over the blocks in the graph */
1386 type_walk_irg(irg, dump_type_info, NULL, NULL);
1387 /* The walker for the const code can be called several times for the
1388 same (sub) experssion. So that no nodes are dumped several times
1389 we decrease the visited flag of the corresponding graph after each
1390 walk. So now increase it finally. */
1391 inc_irg_visited(get_const_code_irg());
1394 current_ir_graph = rem;
1397 /***********************************************************************/
1398 /* the following routine dumps all type information */
1399 /***********************************************************************/
1403 dump_all_types (void)
1405 vcg_open_name ("All_types");
1406 type_walk(dump_type_info, NULL, NULL);
1407 inc_irg_visited(get_const_code_irg());
1412 dump_class_hierarchy (bool entities)
1414 vcg_open_name ("class_hierarchy");
1416 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1418 type_walk(dump_class_hierarchy_node, NULL, NULL);
1422 /***********************************************************************/
1423 /* dumps a graph with type information */
1424 /***********************************************************************/
1428 dump_ir_graph_w_types (ir_graph *irg)
1431 rem = current_ir_graph;
1432 current_ir_graph = irg;
1434 vcg_open (irg, "-all");
1436 /* dump common ir graph */
1437 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1438 /* dump type info */
1439 type_walk_irg(irg, dump_type_info, NULL, NULL);
1440 inc_irg_visited(get_const_code_irg());
1441 /* dump edges from graph to type info */
1442 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1445 current_ir_graph = rem;
1449 dump_ir_block_graph_w_types (ir_graph *irg)
1452 rem = current_ir_graph;
1453 current_ir_graph = irg;
1455 vcg_open (irg, "-all");
1457 /* dump common blocked ir graph */
1458 dump_ir_block_graph_2(irg);
1459 /* dump type info */
1460 type_walk_irg(irg, dump_type_info, NULL, NULL);
1461 inc_irg_visited(get_const_code_irg());
1462 /* dump edges from graph to type info */
1463 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1466 current_ir_graph = rem;
1469 /***********************************************************************/
1470 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1472 /* dump_ir_block_graph */
1474 /* dump_type_graph */
1475 /* dump_ir_graph_w_types */
1476 /***********************************************************************/
1477 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1479 for (i=0; i < get_irp_n_irgs(); i++) {
1480 dump_graph(get_irp_irg(i));
1485 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1486 abort with a segmentation fault. */
1487 void turn_off_edge_labels(void) {
1492 void dump_consts_local(bool b) {
1493 dump_const_local = b;
1496 void turn_off_constant_entity_values(void) {
1500 void dump_keepalive_edges(bool b) {
1504 void dump_out_edges(void) {
1505 dump_out_edge_flag = 1;
1508 void dump_dominator_information(void) {
1509 dump_dominator_information_flag = 1;
1512 void dump_loop_information(void) {
1513 dump_loop_information_flag = 1;
1516 void dont_dump_loop_information(void) {
1517 dump_loop_information_flag = 0;
1520 static void clear_link(ir_node * node, void * env) {
1521 set_irn_link(node, NULL);
1524 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1526 || node_floats(node)
1527 || get_irn_op(node) == op_Bad
1528 || get_irn_op(node) == op_Unknown) {
1529 pmap_entry * entry = pmap_find(map, current_ir_graph);
1531 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1533 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1535 pmap_insert(map, current_ir_graph, arr);
1538 ir_node * block = get_nodes_Block(node);
1539 set_irn_link(node, get_irn_link(block));
1540 set_irn_link(block, node);
1545 static void dump_cg_ir_block(ir_node * block, void * env) {
1547 pmap *irgmap = (pmap *)env;
1548 assert(is_Block(block));
1549 fprintf(F, "graph: { title: \"");
1550 PRINT_NODEID(block);
1551 fprintf(F, "\" label: \"");
1552 #ifdef DEBUG_libfirm
1553 fprintf (F, "%ld", get_irn_node_nr(block));
1555 xfprintf (F, "%I", block->op->name);
1557 if (exc_normal != get_Block_exc(block)) {
1558 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1561 fprintf(F, "\" status:clustered color:%s \n",
1562 get_Block_matured(block) ? "yellow" : "red");
1564 /* dump the blocks edges */
1565 dump_ir_data_edges(block);
1567 /* dump the nodes that go into the block */
1568 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1569 dump_node(node, irgmap);
1570 dump_ir_data_edges(node);
1573 /* Close the vcg information for the block */
1574 fprintf(F, "}\n\n");
1577 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1580 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1581 irg, get_entity_ident(get_irg_ent(irg)));
1583 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1584 ir_node * node = arr[i];
1585 if (is_Block(node)) {
1586 /* Dumps the block and all the nodes in the block , which are to
1587 be found in Block->link. */
1588 dump_cg_ir_block(node, irgmap);
1590 /* Nodes that are not in a Block. */
1591 dump_node(node, NULL);
1592 dump_ir_data_edges(node);
1595 /* Close the vcg information for the irg */
1596 fprintf(F, "}\n\n");
1599 /* dump interprocedural graph with surrounding methods */
1600 void dump_cg_block_graph(ir_graph * irg) {
1601 pmap * map = pmap_create();
1602 pmap * map2 = pmap_create();
1607 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1608 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1609 pmap_insert(map2, entry->key, entry->value);
1610 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1611 d_cg_block_graph(entry->key, entry->value, map2);
1612 DEL_ARR_F(entry->value);
1618 if (dump_loop_information_flag) dump_loop_info(irg);
1622 static void collect_node(ir_node * node, void *env) {
1624 || node_floats(node)
1625 || get_irn_op(node) == op_Bad
1626 || get_irn_op(node) == op_Unknown) {
1627 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1628 ARR_APP1(ir_node *, arr, node);
1629 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1631 ir_node * block = get_nodes_Block(node);
1632 set_irn_link(node, get_irn_link(block));
1633 set_irn_link(block, node);
1637 /* Links all nodes that have the block field set in the link field of
1638 the block. Adds all blocks and nodes not associated with a block
1639 in a array in irg->link. */
1640 static void collect_nodes(void) {
1642 for (i = 0; i < get_irp_n_irgs(); i++)
1643 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1644 cg_walk(clear_link, collect_node, NULL);
1647 static void dump_graphs(void) {
1649 for (i = 0; i < get_irp_n_irgs(); i++) {
1650 current_ir_graph = get_irp_irg(i);
1651 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1655 /* Dump all irgs in interprocedural view to a single file. */
1656 void dump_all_cg_block_graph(void) {
1658 int rem_view = interprocedural_view;
1659 interprocedural_view = 1;
1660 vcg_open_name ("All_graphs");
1665 if (dump_loop_information_flag)
1666 for (i = 0; i < get_irp_n_irgs(); i++)
1667 dump_loop_info(get_irp_irg(i));
1670 interprocedural_view = rem_view;
1673 /* dump interprocedural block graph with surrounding methods */
1674 void dump_cg_graph(ir_graph * irg) {
1675 pmap * map = pmap_create();
1676 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1680 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1681 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1682 pmap_insert(map2, entry->key, entry->value);
1683 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1684 ir_node ** arr = entry->value;
1686 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1688 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1689 irg_ident, irg_ident);
1691 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1692 ir_node * node = arr[i];
1693 dump_node(node, map2);
1694 dump_ir_data_edges(node);
1695 if (is_Block(node)) {
1696 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1697 dump_node(node, map2);
1698 dump_ir_block_edge(node);
1699 dump_ir_data_edges(node);
1706 /* Close the vcg information for the irg */
1707 fprintf(F, "}\n\n");