1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
4 * Authors: Martin Trapp, Christian Schaefer
6 * irdump.h: dumping of an intermediate representation graph
18 # include "irnode_t.h"
19 # include "irgraph_t.h"
20 # include "entity_t.h"
22 # include "firm_common_t.h"
27 # include "typewalk.h"
30 # include "type_or_entity.h"
42 /* Attributes of nodes */
43 #define DEFAULT_NODE_ATTR ""
44 #define DEFAULT_TYPE_ATTRIBUTE ""
46 /* Attributes of edges between Firm nodes */
47 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
48 #define CF_EDGE_ATTR "color: red"
49 #define MEM_EDGE_ATTR "color: blue"
50 #define DOMINATOR_EDGE_ATTR "color: red"
52 #define BACK_EDGE_ATTR "linestyle: dashed "
54 /* Attributes of edges between Firm nodes and type/entity nodes */
55 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
57 /* Attributes of edges in type/entity graphs. */
58 #define TYPE_METH_NODE_ATTR "color: lightyellow"
59 #define TYPE_CLASS_NODE_ATTR "color: green"
60 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
61 #define ENTITY_NODE_ATTR "color: yellow"
62 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
63 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
64 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
65 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
66 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
67 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
68 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
69 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
70 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
71 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
72 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
73 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
74 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
77 #if DEBUG_libfirm && NODEID_AS_LABEL
78 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
79 #define PRINT_TYPEID(X) fprintf(F, "t%ld", get_type_nr(X))
80 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
81 #define PRINT_IRGID(X) fprintf(F,"g%ld", get_irg_graph_nr(X))
83 #define PRINT_NODEID(X) fprintf(F, "%p", X)
84 #define PRINT_TYPEID(X) fprintf(F, "%p", X)
85 #define PRINT_ENTID(X) fprintf(F, "%p", X)
86 #define PRINT_IRGID(X) fprintf(F,"%p",X)
89 #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__);}
90 #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__);}
91 #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__);}
92 #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__);}
93 #define PRINT_NODE_TYPE_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_NODEID(S); fprintf (F, "\" targetname: \""); PRINT_TYPEID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
94 #define PRINT_NODE_ENT_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_NODEID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
95 #define PRINT_ENT_NODE_EDGE(S,T,ATR,...) {fprintf (F, "edge: { sourcename:\""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_NODEID(T); fprintf (F,"\" " ATR "}\n",##__VA_ARGS__);}
98 /* A suffix to manipulate the file name. */
99 char *dump_file_suffix = NULL;
101 /* file to dump to */
104 /* A compiler option to turn off edge labels */
106 /* A compiler option to turn off dumping values of constant entities */
107 int const_entities = 1;
108 /* A compiler option to dump the keep alive edges */
109 int dump_keepalive = 0;
110 /* Compiler options to dump analysis information in dump_ir_graph */
111 int dump_out_edge_flag = 0;
112 int dump_dominator_information_flag = 0;
113 int dump_loop_information_flag = 0;
114 int dump_const_local = 0;
116 static INLINE bool dump_const_local_set(void) {
117 if (!dump_out_edge_flag && !dump_loop_information_flag)
118 return dump_const_local;
123 /* A global variable to record output of the Bad node. */
124 static int Bad_dumped;
126 static void dump_ir_blocks_nodes (ir_node *n, void *env);
127 static void dump_whole_node(ir_node *n, void* env);
129 /*******************************************************************/
130 /* routines to dump information about a single node */
131 /*******************************************************************/
136 dump_node_opcode (ir_node *n)
141 if (n->op->code == iro_Const) {
142 xfprintf (F, "%v", n->attr.con);
145 } else if (n->op->code == iro_SymConst) {
146 if (get_SymConst_kind(n) == linkage_ptr_info) {
147 /* don't use get_SymConst_ptr_info as it mangles the name. */
148 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
150 assert(get_kind(get_SymConst_type(n)) == k_type);
151 assert(get_type_ident(get_SymConst_type(n)));
152 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
153 if (get_SymConst_kind(n) == type_tag)
160 } else if (n->op->code == iro_Filter && !interprocedural_view) {
165 xfprintf (F, "%I", get_irn_opident(n));
170 dump_node_mode (ir_node *n)
172 switch (n->op->code) {
190 xfprintf (F, "%I", get_mode_ident(n->mode));
198 dump_node_nodeattr (ir_node *n)
200 switch (n->op->code) {
202 if (false && interprocedural_view) {
203 xfprintf (F, "%I", get_entity_ident(get_irg_ent(current_ir_graph)));
207 if (n->in[1]->op->code == iro_Cmp) {
208 fprintf (F, "%s", get_pnc_string(n->attr.proj));
210 xfprintf (F, "%ld", n->attr.proj);
214 xfprintf (F, "%ld", n->attr.filter.proj);
217 assert(get_kind(get_Sel_entity(n)) == k_entity);
218 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
226 dump_node_vcgattr (ir_node *n)
228 switch (n->op->code) {
235 fprintf (F, "color: blue");
238 fprintf (F, "color: lightyellow");
241 fprintf (F, "color: green");
247 fprintf (F, "color: yellow");
250 xfprintf (F, DEFAULT_NODE_ATTR);
254 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
255 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
258 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
259 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
260 if (is_ip_cfop(pred)) {
261 ir_graph *irg = get_ip_cfop_irg(pred);
262 if (pmap_find(irgmap, irg) == NULL) return true;
271 bool is_constlike_node(ir_node *n) {
272 ir_op *op = get_irn_op(n);
273 return (op == op_Const || op == op_Bad || op == op_SymConst);
277 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
279 if (!dump_const_local_set()) return;
280 /* Use visited flag to avoid outputting nodes twice.
281 initialize it first. */
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)) {
285 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
286 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
289 for (i = 0; i < get_irn_arity(n); i++) {
290 ir_node *con = get_irn_n(n, i);
291 if (is_constlike_node(con) && irn_not_visited(con)) {
292 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
293 mark_irn_visited(con);
294 /* Generate a new name for the node by appending the names of
296 fprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
297 fprintf(F, "\" label: \"");
298 dump_node_opcode(con);
299 dump_node_mode (con);
301 dump_node_nodeattr(con);
303 xfprintf (F, " %ld", get_irn_node_nr(con));
306 dump_node_vcgattr(con);
313 dump_node (ir_node *n, pmap * map) {
314 if (dump_const_local_set() && is_constlike_node(n)) return;
317 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
322 dump_node_nodeattr(n);
324 xfprintf (F, " %ld", get_irn_node_nr(n));
327 dump_node_vcgattr(n);
329 dump_const_node_local(n, map);
333 dump_ir_node (ir_node *n)
336 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
338 switch (n->op->code) { /* node label */
340 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
341 xfprintf (F, DEFAULT_NODE_ATTR);
348 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
349 xfprintf (F, DEFAULT_NODE_ATTR);
352 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
353 xfprintf (F, DEFAULT_NODE_ATTR);
356 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
357 if (get_irn_modecode(n) == irm_M)
358 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
360 xfprintf (F, DEFAULT_NODE_ATTR);
363 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
364 xfprintf (F, DEFAULT_NODE_ATTR);
367 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
368 xfprintf (F, DEFAULT_NODE_ATTR);
371 if (n->in[1]->op->code == iro_Cmp) {
372 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
373 get_pnc_string(n->attr.proj));
375 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
377 xfprintf (F, DEFAULT_NODE_ATTR);
380 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
381 xfprintf (F, DEFAULT_NODE_ATTR);
384 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
385 xfprintf (F, DEFAULT_NODE_ATTR);
388 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
389 xfprintf (F, DEFAULT_NODE_ATTR);
392 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
393 xfprintf (F, DEFAULT_NODE_ATTR);
396 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
397 xfprintf (F, DEFAULT_NODE_ATTR);
400 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
401 xfprintf (F, DEFAULT_NODE_ATTR);
404 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
405 xfprintf (F, DEFAULT_NODE_ATTR);
408 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
409 xfprintf (F, DEFAULT_NODE_ATTR);
412 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
413 xfprintf (F, DEFAULT_NODE_ATTR);
416 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
417 xfprintf (F, DEFAULT_NODE_ATTR);
420 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
421 xfprintf (F, DEFAULT_NODE_ATTR);
424 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
425 xfprintf (F, DEFAULT_NODE_ATTR);
428 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
429 xfprintf (F, DEFAULT_NODE_ATTR);
432 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
433 xfprintf (F, DEFAULT_NODE_ATTR);
436 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
437 xfprintf (F, DEFAULT_NODE_ATTR);
440 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
441 xfprintf (F, DEFAULT_NODE_ATTR);
444 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
445 xfprintf (F, DEFAULT_NODE_ATTR);
448 xfprintf (F, "\"%I\"", get_irn_opident(n));
449 xfprintf (F, DEFAULT_NODE_ATTR);
452 xfprintf (F, "\"%I\"", get_irn_opident(n));
453 xfprintf (F, DEFAULT_NODE_ATTR);
456 xfprintf (F, "\"%I\"", get_irn_opident(n));
457 xfprintf (F, DEFAULT_NODE_ATTR);
460 xfprintf (F, "\"%I\"", get_irn_opident(n));
461 xfprintf (F, DEFAULT_NODE_ATTR);
464 xfprintf (F, "\"%I\"", get_irn_opident(n));
465 xfprintf (F, DEFAULT_NODE_ATTR);
468 xfprintf (F, "\"%I\"", get_irn_opident(n));
469 xfprintf (F, DEFAULT_NODE_ATTR);
472 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
473 xfprintf (F, DEFAULT_NODE_ATTR);
477 xfprintf (F, "\"%R\"", n);
478 xfprintf (F, DEFAULT_NODE_ATTR);
481 xfprintf (F, "\"%I\" ", get_irn_opident(n));
482 xfprintf (F, DEFAULT_NODE_ATTR);
485 assert(get_kind(get_Sel_entity(n)) == k_entity);
486 xfprintf (F, "\"%I ", get_irn_opident(n));
487 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
488 xfprintf (F, DEFAULT_NODE_ATTR);
491 assert(get_kind(get_SymConst_type(n)) == k_type);
492 assert(get_type_ident(get_SymConst_type(n)));
493 fprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
494 switch (n->attr.i.num){
496 fprintf (F, "tag\" ");
499 fprintf (F, "size\" ");
505 xfprintf (F, DEFAULT_NODE_ATTR);
508 xfprintf (F, "\"%I\" ", get_irn_opident(n));
509 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
512 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
513 xfprintf (F, DEFAULT_NODE_ATTR);
516 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
517 xfprintf (F, DEFAULT_NODE_ATTR);
520 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
522 fprintf (F, "}\n"); /* footer */
526 /* dump the edge to the block this node belongs to */
528 dump_ir_block_edge(ir_node *n) {
529 if (dump_const_local_set() && is_constlike_node(n)) return;
530 if (is_no_Block(n)) {
531 fprintf (F, "edge: { sourcename: \"");
533 fprintf (F, "\" targetname: \"");
534 PRINT_NODEID(get_nodes_Block(n));
535 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
539 static void print_edge_vcgattr(ir_node *from, int to) {
542 if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
544 switch (get_irn_opcode(from)) {
546 xfprintf (F, CF_EDGE_ATTR);
548 case iro_Start: break;
551 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
552 xfprintf (F, CF_EDGE_ATTR);
553 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
554 xfprintf (F, MEM_EDGE_ATTR);
557 case iro_EndReg: break;
558 case iro_EndExcept: break;
560 case iro_Break: break;
561 case iro_Cond: break;
564 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
566 case iro_Const: break;
567 case iro_SymConst:break;
570 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
572 case iro_CallBegin: break;
575 case iro_Minus: break;
581 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
589 case iro_Shrs: break;
592 case iro_Conv: break;
594 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
600 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
603 xfprintf (F, MEM_EDGE_ATTR);
605 case iro_Tuple: break;
608 switch (get_irn_modecode(from)) {
610 xfprintf (F, CF_EDGE_ATTR);
613 xfprintf (F, MEM_EDGE_ATTR);
619 case iro_Unknown: break;
626 /* dump edges to our inputs */
628 dump_ir_data_edges(ir_node *n) {
629 int i, visited = get_irn_visited(n);
631 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
634 for (i = 0; i < get_irn_arity(n); i++) {
635 ir_node * pred = get_irn_n(n, i);
637 if ((interprocedural_view && get_irn_visited(pred) < visited))
638 continue; /* pred not dumped */
639 if (is_backedge(n, i))
640 fprintf (F, "backedge: {sourcename: \"");
642 fprintf (F, "edge: {sourcename: \"");
644 fprintf (F, "\" targetname: \"");
645 if ((dump_const_local_set()) && is_constlike_node(pred))
649 fprintf (F, " label: \"%d\" ", i);
650 print_edge_vcgattr(n, i);
657 dump_out_edge (ir_node *n, void* env) {
659 for (i = 0; i < get_irn_n_outs(n); i++) {
660 assert(get_irn_out(n, i));
661 fprintf (F, "edge: {sourcename: \"");
663 fprintf (F, "\" targetname: \"");
664 PRINT_NODEID(get_irn_out(n, i));
665 fprintf (F, "\" color: red linestyle: dashed");
671 dump_loop_node_edge (ir_loop *loop, int i) {
673 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", loop);
674 PRINT_NODEID(get_loop_node(loop, i));
675 fprintf (F, "\" color: green");
680 void dump_loops (ir_loop *loop) {
682 /* dump this loop node */
683 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
684 loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
685 /* dump edges to nodes in loop -- only if it is a real loop */
686 if (get_loop_depth(loop) != 0) {
687 for (i = 0; i < get_loop_n_nodes(loop); i++) {
688 dump_loop_node_edge(loop, i);
691 for (i = 0; i < get_loop_n_sons(loop); i++) {
692 dump_loops(get_loop_son(loop, i));
697 void dump_loop_info(ir_graph *irg) {
698 ir_graph *rem = current_ir_graph;
699 current_ir_graph = irg;
701 if (get_irg_loop(irg))
702 dump_loops(get_irg_loop(irg));
704 current_ir_graph = rem;
708 /* dumps the edges between nodes and their type or entity attributes. */
709 static void dump_node2type_edges (ir_node *n, void *env)
713 switch (get_irn_opcode(n)) {
715 /* @@@ some consts have an entity */
718 if ( (get_SymConst_kind(n) == type_tag)
719 || (get_SymConst_kind(n) == size))
721 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
725 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
728 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
731 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
734 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
742 static void dump_const_expression(ir_node *value) {
743 ir_graph *rem = current_ir_graph;
744 int rem_dump_const_local = dump_const_local;
745 dump_const_local = 0;
746 current_ir_graph = get_const_code_irg();
747 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
748 /* Decrease visited flag so that we walk with the same flag for the next
749 expresssion. This guarantees that we don't dump the same node twice,
750 as for const expressions cse is performed to save memory. */
751 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
752 current_ir_graph = rem;
753 dump_const_local = rem_dump_const_local;
757 static void print_type_info(type *tp) {
758 if (get_type_state(tp) == layout_undefined) {
759 fprintf(F, "state: layout_undefined\n");
761 fprintf(F, "state: layout_fixed,\n");
763 if (get_type_mode(tp))
764 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
765 fprintf(F, "size: %dB,\n", get_type_size(tp));
769 static void print_typespecific_info(type *tp) {
770 switch (get_type_tpop_code(tp)) {
773 if(existent == get_class_peculiarity(tp))
774 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
776 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
780 xfprintf (F, " " TYPE_METH_NODE_ATTR);
791 case tpo_enumeration:
804 static void print_type_node(type *tp) {
805 xfprintf (F, "node: {title: \"");
807 xfprintf (F, "\" label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
808 xfprintf (F, "info1: \"");
811 print_typespecific_info(tp);
815 void dump_entity_node(entity *ent) {
816 xfprintf (F, "node: {title: \"");
818 xfprintf (F, "\"" DEFAULT_TYPE_ATTRIBUTE);
819 xfprintf (F, "label: ");
820 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
821 fprintf (F, "\n info1:\"\nallocation: ");
822 switch (get_entity_allocation(ent)) {
823 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
824 case automatic_allocated: fprintf (F, "automatic allocated"); break;
825 case static_allocated: fprintf (F, "static allocated"); break;
826 case parameter_allocated: fprintf (F, "parameter allocated"); break;
828 fprintf (F, "\nvisibility: ");
829 switch (get_entity_visibility(ent)) {
830 case local: fprintf (F, "local"); break;
831 case external_visible: fprintf (F, "external_visible"); break;
832 case external_allocated: fprintf (F, "external_allocate"); break;
834 fprintf (F, "\nvariability: ");
835 switch (get_entity_variability(ent)) {
836 case uninitialized: fprintf (F, "uninitialized");break;
837 case initialized: fprintf (F, "initialized"); break;
838 case part_constant: fprintf (F, "part_constant");break;
839 case constant: fprintf (F, "constant"); break;
841 fprintf (F, "\nvolatility: ");
842 switch (get_entity_volatility(ent)) {
843 case non_volatile: fprintf (F, "non_volatile"); break;
844 case is_volatile: fprintf (F, "is_volatile"); break;
846 fprintf (F, "\npeculiarity: ");
847 switch (get_entity_peculiarity(ent)) {
848 case description: fprintf (F, "description"); break;
849 case inherited: fprintf (F, "inherited"); break;
850 case existent: fprintf (F, "existent"); break;
852 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
853 fprintf(F, "\noffset: %d", get_entity_offset(ent));
854 if (is_method_type(get_entity_type(ent))) {
855 if (get_entity_irg(ent)) /* can be null */
856 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
858 { fprintf (F, "\nirg = NULL"); }
860 fprintf(F, "\"\n}\n");
863 /* dumps a type or entity and it's edges. */
865 dump_type_info (type_or_ent *tore, void *env) {
866 int i = 0; /* to shutup gcc */
868 /* dump this type or entity */
870 switch (get_kind(tore)) {
873 entity *ent = (entity *)tore;
876 dump_entity_node(ent);
878 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
879 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
880 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
881 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
882 if(is_class_type(get_entity_owner(ent))) {
883 for(i = 0; i < get_entity_n_overwrites(ent); i++){
884 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
887 /* attached subgraphs */
888 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
889 if (is_atomic_entity(ent)) {
890 value = get_atomic_ent_value(ent);
892 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
894 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"", GET_ENTID(ent));
896 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
898 dump_const_expression(value);
901 if (is_compound_entity(ent)) {
902 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
903 value = get_compound_ent_value(ent, i);
905 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
906 dump_const_expression(value);
907 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
909 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
910 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
911 get_compound_ent_value_member(ent, i), i);
920 type *tp = (type *)tore;
922 /* and now the edges */
923 switch (get_type_tpop_code(tp)) {
926 for (i=0; i < get_class_n_supertypes(tp); i++) {
927 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
930 for (i=0; i < get_class_n_members(tp); i++) {
931 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
936 for (i=0; i < get_struct_n_members(tp); i++) {
937 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
942 for (i = 0; i < get_method_n_params(tp); i++)
944 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
946 for (i = 0; i < get_method_n_ress(tp); i++)
948 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
953 for (i = 0; i < get_union_n_members(tp); i++)
955 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
960 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
961 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
963 case tpo_enumeration:
968 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
976 break; /* case k_type */
979 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
981 } /* switch kind_or_entity */
984 /* dumps a class type node and a superclass edge.
985 If env != null dumps entities of classes and overwrites edges. */
987 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
988 int i = 0; /* to shutup gcc */
990 /* dump this type or entity */
991 switch (get_kind(tore)) {
993 entity *ent = (entity *)tore;
994 if (get_entity_owner(ent) == get_glob_type()) break;
995 if ((env) && is_class_type(get_entity_owner(ent))) {
997 dump_entity_node(ent);
999 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1000 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1002 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1005 } break; /* case k_entity */
1008 type *tp = (type *)tore;
1009 if (tp == get_glob_type()) break;
1010 switch (get_type_tpop_code(tp)) {
1012 print_type_node(tp);
1013 /* and now the edges */
1014 for (i=0; i < get_class_n_supertypes(tp); i++)
1016 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1022 break; /* case k_type */
1025 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1027 } /* switch kind_or_entity */
1030 /************************************************************************/
1031 /* open and close vcg file */
1032 /************************************************************************/
1034 static void vcg_open (ir_graph *irg, char *suffix) {
1035 char *fname; /* filename to put the vcg information in */
1042 /** open file for vcg graph */
1043 ent = get_irg_ent(irg);
1044 id = ent->ld_name ? ent->ld_name : ent->name;
1045 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1046 len = id_to_strlen (id);
1047 cp = id_to_str (id);
1048 if (dump_file_suffix)
1049 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1051 fname = malloc (len + 5 + strlen(suffix));
1052 strncpy (fname, cp, len); /* copy the filename */
1054 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1055 strcat (fname, suffix); /* append file suffix */
1056 strcat (fname, ".vcg"); /* append the .vcg suffix */
1057 F = fopen (fname, "w"); /* open file for writing */
1059 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1063 strcpy(label, "yes");
1065 strcpy (label, "no");
1070 "graph: { title: \"ir graph of %s\"\n"
1071 "display_edge_labels: %s\n"
1072 "layoutalgorithm: mindepth\n"
1073 "manhattan_edges: yes\n"
1074 "port_sharing: no\n"
1075 "orientation: bottom_to_top\n"
1076 "classname 1: \"Data\"\n"
1077 "classname 2: \"Block\"\n"
1078 "classname 3: \"Entity type\""
1079 "classname 4: \"Entity owner\""
1080 "classname 5: \"Method Param\""
1081 "classname 6: \"Method Res\""
1082 "classname 7: \"Super\""
1083 "classname 8: \"Union\""
1084 "classname 9: \"Points-to\""
1085 "classname 10: \"Array Element Type\""
1086 "classname 11: \"Overwrites\""
1087 "classname 12: \"Member\""
1090 fprintf (F, "\n"); /* a separator */
1093 static void vcg_open_name (const char *name) {
1094 char *fname; /* filename to put the vcg information in */
1098 /** open file for vcg graph */
1100 fname = malloc (len + 5);
1101 if (dump_file_suffix)
1102 fname = malloc (len + 5 + strlen(dump_file_suffix));
1104 fname = malloc (len + 5);
1105 strcpy (fname, name); /* copy the filename */
1106 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1107 strcat (fname, ".vcg"); /* append the .vcg suffix */
1108 F = fopen (fname, "w"); /* open file for writing */
1110 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1114 strcpy(label, "yes");
1116 strcpy (label, "no");
1121 "graph: { title: \"ir graph of %s\"\n"
1122 "display_edge_labels: %s\n"
1123 "layoutalgorithm: mindepth\n"
1124 "manhattan_edges: yes\n"
1125 "port_sharing: no\n"
1126 "orientation: bottom_to_top\n"
1127 "classname 1: \"Data\"\n"
1128 "classname 2: \"Block\"\n"
1129 "classname 3: \"Entity type\"\n"
1130 "classname 4: \"Entity owner\"\n"
1131 "classname 5: \"Method Param\"\n"
1132 "classname 6: \"Method Res\"\n"
1133 "classname 7: \"Super\"\n"
1134 "classname 8: \"Union\"\n"
1135 "classname 9: \"Points-to\"\n"
1136 "classname 10: \"Array Element Type\"\n"
1137 "classname 11: \"Overwrites\"\n"
1138 "classname 12: \"Member\"\n"
1141 fprintf (F, "\n"); /* a separator */
1146 fprintf (F, "}\n"); /* print footer */
1147 fclose (F); /* close vcg file */
1150 /************************************************************************/
1151 /* routines to dump a graph, blocks as conventional nodes. */
1152 /************************************************************************/
1154 static int node_floats(ir_node *n) {
1155 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1156 (get_irg_pinned(current_ir_graph) == floats));
1160 dump_whole_node (ir_node *n, void* env) {
1162 if (!node_floats(n)) dump_ir_block_edge(n);
1163 dump_ir_data_edges(n);
1167 dump_ir_graph (ir_graph *irg)
1170 rem = current_ir_graph;
1171 current_ir_graph = irg;
1175 /* walk over the graph */
1176 /* dump_whole_node must be called in post visiting predecessors */
1177 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1179 /* dump the out edges in a separate walk */
1180 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1181 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1186 current_ir_graph = rem;
1189 /***********************************************************************/
1190 /* the following routines dump the nodes as attached to the blocks. */
1191 /***********************************************************************/
1194 dump_ir_blocks_nodes (ir_node *n, void *env) {
1195 ir_node *block = (ir_node *)env;
1197 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1199 dump_ir_data_edges(n);
1201 if (get_irn_op(n) == op_Bad)
1206 dump_ir_block (ir_node *block, void *env) {
1207 ir_graph *irg = (ir_graph *)env;
1209 if (get_irn_opcode(block) == iro_Block) {
1211 /* This is a block. So dump the vcg information to make a block. */
1212 fprintf(F, "graph: { title: \"");
1213 PRINT_NODEID(block);
1214 fprintf(F, "\" label: \"");
1215 #ifdef DEBUG_libfirm
1216 fprintf (F, "%ld", get_irn_node_nr(block));
1218 xfprintf (F, "%I", block->op->name);
1220 if (exc_normal != get_Block_exc (block))
1221 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1223 fprintf(F, "\" status:clustered color:%s \n",
1224 get_Block_matured (block) ? "yellow" : "red");
1225 /* dump the blocks edges */
1226 dump_ir_data_edges(block);
1228 /* dump the nodes that go into the block */
1229 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1231 /* Close the vcg information for the block */
1232 fprintf(F, "}\n\n");
1233 dump_const_node_local(block, NULL);
1239 dump_blockless_nodes (ir_node *n, void *env) {
1240 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1242 dump_ir_data_edges(n);
1243 dump_ir_block_edge(n);
1244 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1247 if (node_floats(n)) {
1249 dump_ir_data_edges(n);
1250 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1254 static void dump_ir_block_graph_2 (ir_graph *irg)
1257 /* walk over the blocks in the graph */
1258 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1260 /* dump all nodes that are not in a Block */
1261 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1263 /* dump the Bad node */
1265 dump_node(get_irg_bad(irg), NULL);
1269 dump_ir_block_graph (ir_graph *irg)
1272 rem = current_ir_graph;
1273 current_ir_graph = irg;
1277 dump_ir_block_graph_2 (irg);
1279 if (dump_loop_information_flag) dump_loop_info(irg);
1282 current_ir_graph = rem;
1286 /***********************************************************************/
1287 /* the following routines dump a control flow graph */
1288 /***********************************************************************/
1292 dump_block_to_cfg (ir_node *block, void *env) {
1296 if (get_irn_opcode(block) == iro_Block) {
1297 /* This is a block. Dump a node for the block. */
1298 fprintf (F, "node: {title:\""); PRINT_NODEID(block);
1299 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1301 if (exc_normal != get_Block_exc (block))
1302 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1305 if (dump_dominator_information_flag)
1306 fprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1308 /* Dump the edges */
1309 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1310 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1311 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1312 fprintf (F, "edge: { sourcename: \"");
1313 PRINT_NODEID(block);
1314 fprintf (F, "\" targetname: \"");
1316 fprintf (F, "\" }\n");
1319 /* Dump dominator edge */
1320 if (dump_dominator_information_flag && get_Block_idom(block)) {
1321 pred = get_Block_idom(block);
1322 fprintf (F, "edge: { sourcename: \"");
1323 PRINT_NODEID(block);
1324 fprintf (F, "\" targetname: \"");
1326 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1332 dump_cfg (ir_graph *irg)
1334 ir_graph *rem = current_ir_graph;
1335 int ddif = dump_dominator_information_flag;
1336 current_ir_graph = irg;
1337 vcg_open (irg, "-cfg");
1339 if (get_irg_dom_state(irg) != dom_consistent)
1340 dump_dominator_information_flag = 0;
1342 /* walk over the blocks in the graph */
1343 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1344 dump_ir_node (irg->bad);
1346 dump_dominator_information_flag = ddif;
1348 current_ir_graph = rem;
1352 /***********************************************************************/
1353 /* the following routine dumps all type information reachable from an */
1355 /***********************************************************************/
1359 dump_type_graph (ir_graph *irg)
1362 rem = current_ir_graph;
1363 current_ir_graph = irg;
1365 vcg_open (irg, "-type");
1367 /* walk over the blocks in the graph */
1368 type_walk_irg(irg, dump_type_info, NULL, NULL);
1369 /* The walker for the const code can be called several times for the
1370 same (sub) experssion. So that no nodes are dumped several times
1371 we decrease the visited flag of the corresponding graph after each
1372 walk. So now increase it finally. */
1373 inc_irg_visited(get_const_code_irg());
1376 current_ir_graph = rem;
1379 /***********************************************************************/
1380 /* the following routine dumps all type information */
1381 /***********************************************************************/
1385 dump_all_types (void)
1387 vcg_open_name ("All_types");
1388 type_walk(dump_type_info, NULL, NULL);
1389 inc_irg_visited(get_const_code_irg());
1394 dump_class_hierarchy (bool entities)
1396 vcg_open_name ("class_hierarchy");
1398 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1400 type_walk(dump_class_hierarchy_node, NULL, NULL);
1404 /***********************************************************************/
1405 /* dumps a graph with type information */
1406 /***********************************************************************/
1410 dump_ir_graph_w_types (ir_graph *irg)
1413 rem = current_ir_graph;
1414 current_ir_graph = irg;
1416 vcg_open (irg, "-all");
1418 /* dump common ir graph */
1419 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1420 /* dump type info */
1421 type_walk_irg(irg, dump_type_info, NULL, NULL);
1422 inc_irg_visited(get_const_code_irg());
1423 /* dump edges from graph to type info */
1424 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1427 current_ir_graph = rem;
1431 dump_ir_block_graph_w_types (ir_graph *irg)
1434 rem = current_ir_graph;
1435 current_ir_graph = irg;
1437 vcg_open (irg, "-all");
1439 /* dump common blocked ir graph */
1440 dump_ir_block_graph_2(irg);
1441 /* dump type info */
1442 type_walk_irg(irg, dump_type_info, NULL, NULL);
1443 inc_irg_visited(get_const_code_irg());
1444 /* dump edges from graph to type info */
1445 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1448 current_ir_graph = rem;
1451 /***********************************************************************/
1452 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1454 /* dump_ir_block_graph */
1456 /* dump_type_graph */
1457 /* dump_ir_graph_w_types */
1458 /***********************************************************************/
1459 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1461 for (i=0; i < get_irp_n_irgs(); i++) {
1462 dump_graph(get_irp_irg(i));
1467 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1468 abort with a segmentation fault. */
1469 void turn_off_edge_labels(void) {
1474 void dump_consts_local(bool b) {
1475 dump_const_local = b;
1478 void turn_off_constant_entity_values(void) {
1482 void dump_keepalive_edges(bool b) {
1486 void dump_out_edges(void) {
1487 dump_out_edge_flag = 1;
1490 void dump_dominator_information(void) {
1491 dump_dominator_information_flag = 1;
1494 void dump_loop_information(void) {
1495 dump_loop_information_flag = 1;
1498 void dont_dump_loop_information(void) {
1499 dump_loop_information_flag = 0;
1502 static void clear_link(ir_node * node, void * env) {
1503 set_irn_link(node, NULL);
1506 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1508 || node_floats(node)
1509 || get_irn_op(node) == op_Bad
1510 || get_irn_op(node) == op_Unknown) {
1511 pmap_entry * entry = pmap_find(map, current_ir_graph);
1513 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1515 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1517 pmap_insert(map, current_ir_graph, arr);
1520 ir_node * block = get_nodes_Block(node);
1521 set_irn_link(node, get_irn_link(block));
1522 set_irn_link(block, node);
1527 static void dump_cg_ir_block(ir_node * block, void * env) {
1529 pmap *irgmap = (pmap *)env;
1530 assert(is_Block(block));
1531 fprintf(F, "graph: { title: \"");
1532 PRINT_NODEID(block);
1533 fprintf(F, "\" label: \"");
1534 #ifdef DEBUG_libfirm
1535 fprintf (F, "%ld", get_irn_node_nr(block));
1537 xfprintf (F, "%I", block->op->name);
1539 if (exc_normal != get_Block_exc(block)) {
1540 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1543 fprintf(F, "\" status:clustered color:%s \n",
1544 get_Block_matured(block) ? "yellow" : "red");
1546 /* dump the blocks edges */
1547 dump_ir_data_edges(block);
1549 /* dump the nodes that go into the block */
1550 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1551 dump_node(node, irgmap);
1552 dump_ir_data_edges(node);
1555 /* Close the vcg information for the block */
1556 fprintf(F, "}\n\n");
1559 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1562 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1563 irg, get_entity_ident(get_irg_ent(irg)));
1565 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1566 ir_node * node = arr[i];
1567 if (is_Block(node)) {
1568 /* Dumps the block and all the nodes in the block , which are to
1569 be found in Block->link. */
1570 dump_cg_ir_block(node, irgmap);
1572 /* Nodes that are not in a Block. */
1573 dump_node(node, NULL);
1574 dump_ir_data_edges(node);
1577 /* Close the vcg information for the irg */
1578 fprintf(F, "}\n\n");
1581 /* dump interprocedural graph with surrounding methods */
1582 void dump_cg_block_graph(ir_graph * irg) {
1583 pmap * map = pmap_create();
1584 pmap * map2 = pmap_create();
1589 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1590 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1591 pmap_insert(map2, entry->key, entry->value);
1592 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1593 d_cg_block_graph(entry->key, entry->value, map2);
1594 DEL_ARR_F(entry->value);
1600 if (dump_loop_information_flag) dump_loop_info(irg);
1604 static void collect_node(ir_node * node, void *env) {
1606 || node_floats(node)
1607 || get_irn_op(node) == op_Bad
1608 || get_irn_op(node) == op_Unknown) {
1609 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1610 ARR_APP1(ir_node *, arr, node);
1611 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1613 ir_node * block = get_nodes_Block(node);
1614 set_irn_link(node, get_irn_link(block));
1615 set_irn_link(block, node);
1619 /* Links all nodes that have the block field set in the link field of
1620 the block. Adds all blocks and nodes not associated with a block
1621 in a array in irg->link. */
1622 static void collect_nodes(void) {
1624 for (i = 0; i < get_irp_n_irgs(); i++)
1625 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1626 cg_walk(clear_link, collect_node, NULL);
1629 static void dump_graphs(void) {
1631 for (i = 0; i < get_irp_n_irgs(); i++) {
1632 current_ir_graph = get_irp_irg(i);
1633 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1637 /* Dump all irgs in interprocedural view to a single file. */
1638 void dump_all_cg_block_graph(void) {
1640 int rem_view = interprocedural_view;
1641 interprocedural_view = 1;
1642 vcg_open_name ("All_graphs");
1647 if (dump_loop_information_flag)
1648 for (i = 0; i < get_irp_n_irgs(); i++)
1649 dump_loop_info(get_irp_irg(i));
1652 interprocedural_view = rem_view;
1655 /* dump interprocedural block graph with surrounding methods */
1656 void dump_cg_graph(ir_graph * irg) {
1657 pmap * map = pmap_create();
1658 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1662 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1663 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1664 pmap_insert(map2, entry->key, entry->value);
1665 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1666 ir_node ** arr = entry->value;
1668 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1670 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1671 irg_ident, irg_ident);
1673 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1674 ir_node * node = arr[i];
1675 dump_node(node, map2);
1676 dump_ir_data_edges(node);
1677 if (is_Block(node)) {
1678 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1679 dump_node(node, map2);
1680 dump_ir_block_edge(node);
1681 dump_ir_data_edges(node);
1688 /* Close the vcg information for the irg */
1689 fprintf(F, "}\n\n");