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 %d\""
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__);}
89 #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__);}
90 #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__);}
91 #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__);}
94 /* A suffix to manipulate the file name. */
95 char *dump_file_suffix = NULL;
100 /* A compiler option to turn off edge labels */
102 /* A compiler option to turn off dumping values of constant entities */
103 int const_entities = 1;
104 /* A compiler option to dump the keep alive edges */
105 int dump_keepalive = 0;
106 /* Compiler options to dump analysis information in dump_ir_graph */
107 int dump_out_edge_flag = 0;
108 int dump_dominator_information_flag = 0;
109 int dump_loop_information_flag = 0;
110 int dump_const_local = 0;
112 static INLINE bool dump_const_local_set(void) {
113 if (!dump_out_edge_flag && !dump_loop_information_flag)
114 return dump_const_local;
119 /* A global variable to record output of the Bad node. */
120 static int Bad_dumped;
122 static void dump_ir_blocks_nodes (ir_node *n, void *env);
123 static void dump_whole_node(ir_node *n, void* env);
125 /*******************************************************************/
126 /* routines to dump information about a single node */
127 /*******************************************************************/
132 dump_node_opcode (ir_node *n)
137 if (n->op->code == iro_Const) {
138 xfprintf (F, "%v", n->attr.con);
141 } else if (n->op->code == iro_SymConst) {
142 if (get_SymConst_kind(n) == linkage_ptr_info) {
143 /* don't use get_SymConst_ptr_info as it mangles the name. */
144 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
146 assert(get_kind(get_SymConst_type(n)) == k_type);
147 assert(get_type_ident(get_SymConst_type(n)));
148 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
149 if (get_SymConst_kind(n) == type_tag)
156 } else if (n->op->code == iro_Filter && !interprocedural_view) {
161 xfprintf (F, "%I", get_irn_opident(n));
166 dump_node_mode (ir_node *n)
168 switch (n->op->code) {
186 xfprintf (F, "%I", get_mode_ident(n->mode));
194 dump_node_nodeattr (ir_node *n)
196 switch (n->op->code) {
198 if (false && interprocedural_view) {
199 xfprintf (F, "%I", get_entity_ident(get_irg_ent(current_ir_graph)));
203 if (n->in[1]->op->code == iro_Cmp) {
204 fprintf (F, "%s", get_pnc_string(n->attr.proj));
206 xfprintf (F, "%ld", n->attr.proj);
210 xfprintf (F, "%ld", n->attr.filter.proj);
213 assert(get_kind(get_Sel_entity(n)) == k_entity);
214 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
222 dump_node_vcgattr (ir_node *n)
224 switch (n->op->code) {
231 fprintf (F, "color: blue");
234 fprintf (F, "color: lightyellow");
237 fprintf (F, "color: green");
243 fprintf (F, "color: yellow");
246 xfprintf (F, DEFAULT_NODE_ATTR);
250 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
251 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
254 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
255 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
256 if (is_ip_cfop(pred)) {
257 ir_graph *irg = get_ip_cfop_irg(pred);
258 if (pmap_find(irgmap, irg) == NULL) return true;
267 bool is_constlike_node(ir_node *n) {
268 ir_op *op = get_irn_op(n);
269 return (op == op_Const || op == op_Bad || op == op_SymConst);
273 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
275 if (!dump_const_local_set()) return;
276 /* Use visited flag to avoid outputting nodes twice.
277 initialize it first. */
278 for (i = 0; i < get_irn_arity(n); i++) {
279 ir_node *con = get_irn_n(n, i);
280 if (is_constlike_node(con)) {
281 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
282 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
285 for (i = 0; i < get_irn_arity(n); i++) {
286 ir_node *con = get_irn_n(n, i);
287 if (is_constlike_node(con) && irn_not_visited(con)) {
288 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
289 mark_irn_visited(con);
290 /* Generate a new name for the node by appending the names of
292 fprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
293 fprintf(F, "\" label: \"");
294 dump_node_opcode(con);
295 dump_node_mode (con);
297 dump_node_nodeattr(con);
299 xfprintf (F, " %ld", get_irn_node_nr(con));
302 dump_node_vcgattr(con);
309 dump_node (ir_node *n, pmap * map) {
310 if (dump_const_local_set() && is_constlike_node(n)) return;
313 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
318 dump_node_nodeattr(n);
320 xfprintf (F, " %ld", get_irn_node_nr(n));
323 dump_node_vcgattr(n);
325 dump_const_node_local(n, map);
329 dump_ir_node (ir_node *n)
332 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
334 switch (n->op->code) { /* node label */
336 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
337 xfprintf (F, DEFAULT_NODE_ATTR);
344 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
345 xfprintf (F, DEFAULT_NODE_ATTR);
348 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
349 xfprintf (F, DEFAULT_NODE_ATTR);
352 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
353 if (get_irn_modecode(n) == irm_M)
354 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
356 xfprintf (F, DEFAULT_NODE_ATTR);
359 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
360 xfprintf (F, DEFAULT_NODE_ATTR);
363 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
364 xfprintf (F, DEFAULT_NODE_ATTR);
367 if (n->in[1]->op->code == iro_Cmp) {
368 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
369 get_pnc_string(n->attr.proj));
371 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
373 xfprintf (F, DEFAULT_NODE_ATTR);
376 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
377 xfprintf (F, DEFAULT_NODE_ATTR);
380 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
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\"", get_irn_opident(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%I\"", get_irn_opident(n), get_irn_modeident(n));
469 xfprintf (F, DEFAULT_NODE_ATTR);
473 xfprintf (F, "\"%R\"", n);
474 xfprintf (F, DEFAULT_NODE_ATTR);
477 xfprintf (F, "\"%I\" ", get_irn_opident(n));
478 xfprintf (F, DEFAULT_NODE_ATTR);
481 assert(get_kind(get_Sel_entity(n)) == k_entity);
482 xfprintf (F, "\"%I ", get_irn_opident(n));
483 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
484 xfprintf (F, DEFAULT_NODE_ATTR);
487 assert(get_kind(get_SymConst_type(n)) == k_type);
488 assert(get_type_ident(get_SymConst_type(n)));
489 fprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
490 switch (n->attr.i.num){
492 fprintf (F, "tag\" ");
495 fprintf (F, "size\" ");
501 xfprintf (F, DEFAULT_NODE_ATTR);
504 xfprintf (F, "\"%I\" ", get_irn_opident(n));
505 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
508 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
509 xfprintf (F, DEFAULT_NODE_ATTR);
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));
518 fprintf (F, "}\n"); /* footer */
522 /* dump the edge to the block this node belongs to */
524 dump_ir_block_edge(ir_node *n) {
525 if (dump_const_local_set() && is_constlike_node(n)) return;
526 if (is_no_Block(n)) {
527 fprintf (F, "edge: { sourcename: \"");
529 fprintf (F, "\" targetname: \"");
530 PRINT_NODEID(get_nodes_Block(n));
531 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
535 static void print_edge_vcgattr(ir_node *from, int to) {
538 if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
540 switch (get_irn_opcode(from)) {
542 xfprintf (F, CF_EDGE_ATTR);
544 case iro_Start: break;
547 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
548 xfprintf (F, CF_EDGE_ATTR);
549 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
550 xfprintf (F, MEM_EDGE_ATTR);
553 case iro_EndReg: break;
554 case iro_EndExcept: break;
556 case iro_Break: break;
557 case iro_Cond: break;
560 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
562 case iro_Const: break;
563 case iro_SymConst:break;
566 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
568 case iro_CallBegin: break;
571 case iro_Minus: break;
577 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
585 case iro_Shrs: break;
588 case iro_Conv: break;
590 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
596 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
599 xfprintf (F, MEM_EDGE_ATTR);
601 case iro_Tuple: break;
604 switch (get_irn_modecode(from)) {
606 xfprintf (F, CF_EDGE_ATTR);
609 xfprintf (F, MEM_EDGE_ATTR);
615 case iro_Unknown: break;
622 /* dump edges to our inputs */
624 dump_ir_data_edges(ir_node *n) {
625 int i, visited = get_irn_visited(n);
627 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
630 for (i = 0; i < get_irn_arity(n); i++) {
631 ir_node * pred = get_irn_n(n, i);
633 if ((interprocedural_view && get_irn_visited(pred) < visited))
634 continue; /* pred not dumped */
635 if (is_backedge(n, i))
636 fprintf (F, "backedge: {sourcename: \"");
638 fprintf (F, "edge: {sourcename: \"");
640 fprintf (F, "\" targetname: \"");
641 if ((dump_const_local_set()) && is_constlike_node(pred))
645 fprintf (F, " label: \"%d\" ", i);
646 print_edge_vcgattr(n, i);
653 dump_out_edge (ir_node *n, void* env) {
655 for (i = 0; i < get_irn_n_outs(n); i++) {
656 assert(get_irn_out(n, i));
657 fprintf (F, "edge: {sourcename: \"");
659 fprintf (F, "\" targetname: \"");
660 PRINT_NODEID(get_irn_out(n, i));
661 fprintf (F, "\" color: red linestyle: dashed");
667 dump_loop_node_edge (ir_loop *loop, int i) {
669 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", loop);
670 PRINT_NODEID(get_loop_node(loop, i));
671 fprintf (F, "\" color: green");
676 void dump_loops (ir_loop *loop) {
678 /* dump this loop node */
679 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
680 loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
681 /* dump edges to nodes in loop -- only if it is a real loop */
682 if (get_loop_depth(loop) != 0) {
683 for (i = 0; i < get_loop_n_nodes(loop); i++) {
684 dump_loop_node_edge(loop, i);
687 for (i = 0; i < get_loop_n_sons(loop); i++) {
688 dump_loops(get_loop_son(loop, i));
693 void dump_loop_info(ir_graph *irg) {
694 ir_graph *rem = current_ir_graph;
695 current_ir_graph = irg;
697 if (get_irg_loop(irg))
698 dump_loops(get_irg_loop(irg));
700 current_ir_graph = rem;
704 /* dumps the edges between nodes and their type or entity attributes. */
705 static void dump_node2type_edges (ir_node *n, void *env)
709 switch (get_irn_opcode(n)) {
711 /* @@@ some consts have an entity */
714 if ( (get_SymConst_kind(n) == type_tag)
715 || (get_SymConst_kind(n) == size))
717 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
721 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
724 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
727 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
730 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
738 static void dump_const_expression(ir_node *value) {
739 ir_graph *rem = current_ir_graph;
740 int rem_dump_const_local = dump_const_local;
741 dump_const_local = 0;
742 current_ir_graph = get_const_code_irg();
743 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
744 /* Decrease visited flag so that we walk with the same flag for the next
745 expresssion. This guarantees that we don't dump the same node twice,
746 as for const expressions cse is performed to save memory. */
747 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
748 current_ir_graph = rem;
749 dump_const_local = rem_dump_const_local;
753 static void print_type_info(type *tp) {
754 if (get_type_state(tp) == layout_undefined) {
755 fprintf(F, "state: layout_undefined\n");
757 fprintf(F, "state: layout_fixed,\n");
759 if (get_type_mode(tp))
760 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
761 fprintf(F, "size: %dB,\n", get_type_size(tp));
765 static void print_typespecific_info(type *tp) {
766 switch (get_type_tpop_code(tp)) {
769 if(existent == get_class_peculiarity(tp))
770 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
772 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
776 xfprintf (F, " " TYPE_METH_NODE_ATTR);
787 case tpo_enumeration:
800 static void print_type_node(type *tp) {
801 xfprintf (F, "node: {title: \"");
803 xfprintf (F, "\" label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
804 xfprintf (F, "info1: \"");
807 print_typespecific_info(tp);
811 void dump_entity_node(entity *ent) {
812 xfprintf (F, "node: {title: \"");
814 xfprintf (F, "\"" DEFAULT_TYPE_ATTRIBUTE);
815 xfprintf (F, "label: ");
816 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
817 fprintf (F, "\n info1:\"\nallocation: ");
818 switch (get_entity_allocation(ent)) {
819 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
820 case automatic_allocated: fprintf (F, "automatic allocated"); break;
821 case static_allocated: fprintf (F, "static allocated"); break;
822 case parameter_allocated: fprintf (F, "parameter allocated"); break;
824 fprintf (F, "\nvisibility: ");
825 switch (get_entity_visibility(ent)) {
826 case local: fprintf (F, "local"); break;
827 case external_visible: fprintf (F, "external_visible"); break;
828 case external_allocated: fprintf (F, "external_allocate"); break;
830 fprintf (F, "\nvariability: ");
831 switch (get_entity_variability(ent)) {
832 case uninitialized: fprintf (F, "uninitialized");break;
833 case initialized: fprintf (F, "initialized"); break;
834 case part_constant: fprintf (F, "part_constant");break;
835 case constant: fprintf (F, "constant"); break;
837 fprintf (F, "\nvolatility: ");
838 switch (get_entity_volatility(ent)) {
839 case non_volatile: fprintf (F, "non_volatile"); break;
840 case is_volatile: fprintf (F, "is_volatile"); break;
842 fprintf (F, "\npeculiarity: ");
843 switch (get_entity_peculiarity(ent)) {
844 case description: fprintf (F, "description"); break;
845 case inherited: fprintf (F, "inherited"); break;
846 case existent: fprintf (F, "existent"); break;
848 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
849 fprintf(F, "\noffset: %d", get_entity_offset(ent));
850 if (is_method_type(get_entity_type(ent)))
851 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
852 fprintf(F, "\"\n}\n");
855 /* dumps a type or entity and it's edges. */
857 dump_type_info (type_or_ent *tore, void *env) {
858 int i = 0; /* to shutup gcc */
860 /* dump this type or entity */
862 switch (get_kind(tore)) {
865 entity *ent = (entity *)tore;
868 dump_entity_node(ent);
870 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
871 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
872 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
873 PRINT_ENT_TYPE_EDGE(ent,get_entity_type(ent),ENT_TYPE_EDGE_ATTR);
874 if(is_class_type(get_entity_owner(ent))) {
875 for(i = 0; i < get_entity_n_overwrites(ent); i++){
876 PRINT_ENT_ENT_EDGE(ent,get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
879 /* attached subgraphs */
880 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
881 if (is_atomic_entity(ent)) {
882 value = get_atomic_ent_value(ent);
884 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
886 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"", GET_ENTID(ent));
888 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
890 dump_const_expression(value);
893 if (is_compound_entity(ent)) {
894 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
895 value = get_compound_ent_value(ent, i);
897 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
898 dump_const_expression(value);
899 PRINT_ENT_ENT_EDGE(ent,get_compound_ent_value_member(ent, i),ENT_CORR_EDGE_ATTR,i);
901 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
902 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
903 get_compound_ent_value_member(ent, i), i);
913 type *tp = (type *)tore;
918 /* and now the edges */
919 switch (get_type_tpop_code(tp)) {
922 for (i=0; i < get_class_n_supertypes(tp); i++)
924 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
927 for (i=0; i < get_class_n_members(tp); i++)
929 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
934 for (i=0; i < get_struct_n_members(tp); i++)
936 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
941 for (i = 0; i < get_method_n_params(tp); i++)
943 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
945 for (i = 0; i < get_method_n_ress(tp); i++)
947 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
952 for (i = 0; i < get_union_n_members(tp); i++)
954 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
959 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
960 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
962 case tpo_enumeration:
967 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
975 break; /* case k_type */
978 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
980 } /* switch kind_or_entity */
983 /* dumps a class type node and a superclass edge.
984 If env != null dumps entities of classes and overwrites edges. */
986 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
987 int i = 0; /* to shutup gcc */
989 /* dump this type or entity */
990 switch (get_kind(tore)) {
992 entity *ent = (entity *)tore;
993 if (get_entity_owner(ent) == get_glob_type()) break;
994 if ((env) && is_class_type(get_entity_owner(ent))) {
996 dump_entity_node(ent);
998 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
999 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1001 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1004 } break; /* case k_entity */
1007 type *tp = (type *)tore;
1008 if (tp == get_glob_type()) break;
1009 switch (get_type_tpop_code(tp)) {
1011 print_type_node(tp);
1012 /* and now the edges */
1013 for (i=0; i < get_class_n_supertypes(tp); i++)
1015 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1021 break; /* case k_type */
1024 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1026 } /* switch kind_or_entity */
1029 /************************************************************************/
1030 /* open and close vcg file */
1031 /************************************************************************/
1033 static void vcg_open (ir_graph *irg, char *suffix) {
1034 char *fname; /* filename to put the vcg information in */
1041 /** open file for vcg graph */
1042 ent = get_irg_ent(irg);
1043 id = ent->ld_name ? ent->ld_name : ent->name;
1044 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1045 len = id_to_strlen (id);
1046 cp = id_to_str (id);
1047 if (dump_file_suffix)
1048 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1050 fname = malloc (len + 5 + strlen(suffix));
1051 strncpy (fname, cp, len); /* copy the filename */
1053 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1054 strcat (fname, suffix); /* append file suffix */
1055 strcat (fname, ".vcg"); /* append the .vcg suffix */
1056 F = fopen (fname, "w"); /* open file for writing */
1058 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1062 strcpy(label, "yes");
1064 strcpy (label, "no");
1069 "graph: { title: \"ir graph of %s\"\n"
1070 "display_edge_labels: %s\n"
1071 "layoutalgorithm: mindepth\n"
1072 "manhattan_edges: yes\n"
1073 "port_sharing: no\n"
1074 "orientation: bottom_to_top\n"
1075 "classname 1: \"Data\"\n"
1076 "classname 2: \"Block\"\n"
1077 "classname 3: \"Entity type\""
1078 "classname 4: \"Entity owner\""
1079 "classname 5: \"Method Param\""
1080 "classname 6: \"Method Res\""
1081 "classname 7: \"Super\""
1082 "classname 8: \"Union\""
1083 "classname 9: \"Points-to\""
1084 "classname 10: \"Array Element Type\""
1085 "classname 11: \"Overwrites\""
1086 "classname 12: \"Member\""
1089 fprintf (F, "\n"); /* a separator */
1092 static void vcg_open_name (const char *name) {
1093 char *fname; /* filename to put the vcg information in */
1097 /** open file for vcg graph */
1099 fname = malloc (len + 5);
1100 if (dump_file_suffix)
1101 fname = malloc (len + 5 + strlen(dump_file_suffix));
1103 fname = malloc (len + 5);
1104 strcpy (fname, name); /* copy the filename */
1105 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1106 strcat (fname, ".vcg"); /* append the .vcg suffix */
1107 F = fopen (fname, "w"); /* open file for writing */
1109 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1113 strcpy(label, "yes");
1115 strcpy (label, "no");
1120 "graph: { title: \"ir graph of %s\"\n"
1121 "display_edge_labels: %s\n"
1122 "layoutalgorithm: mindepth\n"
1123 "manhattan_edges: yes\n"
1124 "port_sharing: no\n"
1125 "orientation: bottom_to_top\n"
1126 "classname 1: \"Data\"\n"
1127 "classname 2: \"Block\"\n"
1128 "classname 3: \"Entity type\"\n"
1129 "classname 4: \"Entity owner\"\n"
1130 "classname 5: \"Method Param\"\n"
1131 "classname 6: \"Method Res\"\n"
1132 "classname 7: \"Super\"\n"
1133 "classname 8: \"Union\"\n"
1134 "classname 9: \"Points-to\"\n"
1135 "classname 10: \"Array Element Type\"\n"
1136 "classname 11: \"Overwrites\"\n"
1137 "classname 12: \"Member\"\n"
1140 fprintf (F, "\n"); /* a separator */
1145 fprintf (F, "}\n"); /* print footer */
1146 fclose (F); /* close vcg file */
1149 /************************************************************************/
1150 /* routines to dump a graph, blocks as conventional nodes. */
1151 /************************************************************************/
1153 static int node_floats(ir_node *n) {
1154 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1155 (get_irg_pinned(current_ir_graph) == floats));
1159 dump_whole_node (ir_node *n, void* env) {
1161 if (!node_floats(n)) dump_ir_block_edge(n);
1162 dump_ir_data_edges(n);
1166 dump_ir_graph (ir_graph *irg)
1169 rem = current_ir_graph;
1170 current_ir_graph = irg;
1174 /* walk over the graph */
1175 /* dump_whole_node must be called in post visiting predecessors */
1176 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1178 /* dump the out edges in a separate walk */
1179 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1180 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1185 current_ir_graph = rem;
1188 /***********************************************************************/
1189 /* the following routines dump the nodes as attached to the blocks. */
1190 /***********************************************************************/
1193 dump_ir_blocks_nodes (ir_node *n, void *env) {
1194 ir_node *block = (ir_node *)env;
1196 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1198 dump_ir_data_edges(n);
1200 if (get_irn_op(n) == op_Bad)
1205 dump_ir_block (ir_node *block, void *env) {
1206 ir_graph *irg = (ir_graph *)env;
1208 if (get_irn_opcode(block) == iro_Block) {
1210 /* This is a block. So dump the vcg information to make a block. */
1211 fprintf(F, "graph: { title: \"");
1212 PRINT_NODEID(block);
1213 fprintf(F, "\" label: \"");
1214 #ifdef DEBUG_libfirm
1215 fprintf (F, "%ld", get_irn_node_nr(block));
1217 xfprintf (F, "%I", block->op->name);
1219 if (exc_normal != get_Block_exc (block))
1220 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1222 fprintf(F, "\" status:clustered color:%s \n",
1223 get_Block_matured (block) ? "yellow" : "red");
1224 /* dump the blocks edges */
1225 dump_ir_data_edges(block);
1227 /* dump the nodes that go into the block */
1228 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1230 /* Close the vcg information for the block */
1231 fprintf(F, "}\n\n");
1232 dump_const_node_local(block, NULL);
1238 dump_blockless_nodes (ir_node *n, void *env) {
1239 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1241 dump_ir_data_edges(n);
1242 dump_ir_block_edge(n);
1243 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1246 if (node_floats(n)) {
1248 dump_ir_data_edges(n);
1249 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1253 static void dump_ir_block_graph_2 (ir_graph *irg)
1256 /* walk over the blocks in the graph */
1257 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1259 /* dump all nodes that are not in a Block */
1260 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1262 /* dump the Bad node */
1264 dump_node(get_irg_bad(irg), NULL);
1268 dump_ir_block_graph (ir_graph *irg)
1271 rem = current_ir_graph;
1272 current_ir_graph = irg;
1276 dump_ir_block_graph_2 (irg);
1278 if (dump_loop_information_flag) dump_loop_info(irg);
1281 current_ir_graph = rem;
1285 /***********************************************************************/
1286 /* the following routines dump a control flow graph */
1287 /***********************************************************************/
1291 dump_block_to_cfg (ir_node *block, void *env) {
1295 if (get_irn_opcode(block) == iro_Block) {
1296 /* This is a block. Dump a node for the block. */
1297 fprintf (F, "node: {title:\""); PRINT_NODEID(block);
1298 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1300 if (exc_normal != get_Block_exc (block))
1301 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1304 if (dump_dominator_information_flag)
1305 fprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1307 /* Dump the edges */
1308 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1309 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1310 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1311 fprintf (F, "edge: { sourcename: \"");
1312 PRINT_NODEID(block);
1313 fprintf (F, "\" targetname: \"");
1315 fprintf (F, "\" }\n");
1318 /* Dump dominator edge */
1319 if (dump_dominator_information_flag && get_Block_idom(block)) {
1320 pred = get_Block_idom(block);
1321 fprintf (F, "edge: { sourcename: \"");
1322 PRINT_NODEID(block);
1323 fprintf (F, "\" targetname: \"");
1325 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1331 dump_cfg (ir_graph *irg)
1333 ir_graph *rem = current_ir_graph;
1334 int ddif = dump_dominator_information_flag;
1335 current_ir_graph = irg;
1336 vcg_open (irg, "-cfg");
1338 if (get_irg_dom_state(irg) != dom_consistent)
1339 dump_dominator_information_flag = 0;
1341 /* walk over the blocks in the graph */
1342 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1343 dump_ir_node (irg->bad);
1345 dump_dominator_information_flag = ddif;
1347 current_ir_graph = rem;
1351 /***********************************************************************/
1352 /* the following routine dumps all type information reachable from an */
1354 /***********************************************************************/
1358 dump_type_graph (ir_graph *irg)
1361 rem = current_ir_graph;
1362 current_ir_graph = irg;
1364 vcg_open (irg, "-type");
1366 /* walk over the blocks in the graph */
1367 type_walk_irg(irg, dump_type_info, NULL, NULL);
1368 /* The walker for the const code can be called several times for the
1369 same (sub) experssion. So that no nodes are dumped several times
1370 we decrease the visited flag of the corresponding graph after each
1371 walk. So now increase it finally. */
1372 inc_irg_visited(get_const_code_irg());
1375 current_ir_graph = rem;
1378 /***********************************************************************/
1379 /* the following routine dumps all type information */
1380 /***********************************************************************/
1384 dump_all_types (void)
1386 vcg_open_name ("All_types");
1387 type_walk(dump_type_info, NULL, NULL);
1388 inc_irg_visited(get_const_code_irg());
1393 dump_class_hierarchy (bool entities)
1395 vcg_open_name ("class_hierarchy");
1397 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1399 type_walk(dump_class_hierarchy_node, NULL, NULL);
1403 /***********************************************************************/
1404 /* dumps a graph with type information */
1405 /***********************************************************************/
1409 dump_ir_graph_w_types (ir_graph *irg)
1412 rem = current_ir_graph;
1413 current_ir_graph = irg;
1415 vcg_open (irg, "-all");
1417 /* dump common ir graph */
1418 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1419 /* dump type info */
1420 type_walk_irg(irg, dump_type_info, NULL, NULL);
1421 inc_irg_visited(get_const_code_irg());
1422 /* dump edges from graph to type info */
1423 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1426 current_ir_graph = rem;
1430 dump_ir_block_graph_w_types (ir_graph *irg)
1433 rem = current_ir_graph;
1434 current_ir_graph = irg;
1436 vcg_open (irg, "-all");
1438 /* dump common blocked ir graph */
1439 dump_ir_block_graph_2(irg);
1440 /* dump type info */
1441 type_walk_irg(irg, dump_type_info, NULL, NULL);
1442 inc_irg_visited(get_const_code_irg());
1443 /* dump edges from graph to type info */
1444 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1447 current_ir_graph = rem;
1450 /***********************************************************************/
1451 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1453 /* dump_ir_block_graph */
1455 /* dump_type_graph */
1456 /* dump_ir_graph_w_types */
1457 /***********************************************************************/
1458 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1460 for (i=0; i < get_irp_n_irgs(); i++) {
1461 dump_graph(get_irp_irg(i));
1466 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1467 abort with a segmentation fault. */
1468 void turn_off_edge_labels(void) {
1473 void dump_consts_local(bool b) {
1474 dump_const_local = b;
1477 void turn_off_constant_entity_values(void) {
1481 void dump_keepalive_edges(bool b) {
1485 void dump_out_edges(void) {
1486 dump_out_edge_flag = 1;
1489 void dump_dominator_information(void) {
1490 dump_dominator_information_flag = 1;
1493 void dump_loop_information(void) {
1494 dump_loop_information_flag = 1;
1497 void dont_dump_loop_information(void) {
1498 dump_loop_information_flag = 0;
1501 static void clear_link(ir_node * node, void * env) {
1502 set_irn_link(node, NULL);
1505 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1507 || node_floats(node)
1508 || get_irn_op(node) == op_Bad
1509 || get_irn_op(node) == op_Unknown) {
1510 pmap_entry * entry = pmap_find(map, current_ir_graph);
1512 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1514 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1516 pmap_insert(map, current_ir_graph, arr);
1519 ir_node * block = get_nodes_Block(node);
1520 set_irn_link(node, get_irn_link(block));
1521 set_irn_link(block, node);
1526 static void dump_cg_ir_block(ir_node * block, void * env) {
1528 pmap *irgmap = (pmap *)env;
1529 assert(is_Block(block));
1530 fprintf(F, "graph: { title: \"");
1531 PRINT_NODEID(block);
1532 fprintf(F, "\" label: \"");
1533 #ifdef DEBUG_libfirm
1534 fprintf (F, "%ld", get_irn_node_nr(block));
1536 xfprintf (F, "%I", block->op->name);
1538 if (exc_normal != get_Block_exc(block)) {
1539 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1542 fprintf(F, "\" status:clustered color:%s \n",
1543 get_Block_matured(block) ? "yellow" : "red");
1545 /* dump the blocks edges */
1546 dump_ir_data_edges(block);
1548 /* dump the nodes that go into the block */
1549 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1550 dump_node(node, irgmap);
1551 dump_ir_data_edges(node);
1554 /* Close the vcg information for the block */
1555 fprintf(F, "}\n\n");
1558 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1561 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1562 irg, get_entity_ident(get_irg_ent(irg)));
1564 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1565 ir_node * node = arr[i];
1566 if (is_Block(node)) {
1567 /* Dumps the block and all the nodes in the block , which are to
1568 be found in Block->link. */
1569 dump_cg_ir_block(node, irgmap);
1571 /* Nodes that are not in a Block. */
1572 dump_node(node, NULL);
1573 dump_ir_data_edges(node);
1576 /* Close the vcg information for the irg */
1577 fprintf(F, "}\n\n");
1580 /* dump interprocedural graph with surrounding methods */
1581 void dump_cg_block_graph(ir_graph * irg) {
1582 pmap * map = pmap_create();
1583 pmap * map2 = pmap_create();
1588 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1589 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1590 pmap_insert(map2, entry->key, entry->value);
1591 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1592 d_cg_block_graph(entry->key, entry->value, map2);
1593 DEL_ARR_F(entry->value);
1599 if (dump_loop_information_flag) dump_loop_info(irg);
1603 static void collect_node(ir_node * node, void *env) {
1605 || node_floats(node)
1606 || get_irn_op(node) == op_Bad
1607 || get_irn_op(node) == op_Unknown) {
1608 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1609 ARR_APP1(ir_node *, arr, node);
1610 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1612 ir_node * block = get_nodes_Block(node);
1613 set_irn_link(node, get_irn_link(block));
1614 set_irn_link(block, node);
1618 /* Links all nodes that have the block field set in the link field of
1619 the block. Adds all blocks and nodes not associated with a block
1620 in a array in irg->link. */
1621 static void collect_nodes(void) {
1623 for (i = 0; i < get_irp_n_irgs(); i++)
1624 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1625 cg_walk(clear_link, collect_node, NULL);
1628 static void dump_graphs(void) {
1630 for (i = 0; i < get_irp_n_irgs(); i++) {
1631 current_ir_graph = get_irp_irg(i);
1632 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1636 /* Dump all irgs in interprocedural view to a single file. */
1637 void dump_all_cg_block_graph(void) {
1639 int rem_view = interprocedural_view;
1640 interprocedural_view = 1;
1641 vcg_open_name ("All_graphs");
1646 if (dump_loop_information_flag)
1647 for (i = 0; i < get_irp_n_irgs(); i++)
1648 dump_loop_info(get_irp_irg(i));
1651 interprocedural_view = rem_view;
1654 /* dump interprocedural block graph with surrounding methods */
1655 void dump_cg_graph(ir_graph * irg) {
1656 pmap * map = pmap_create();
1657 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1661 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1662 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1663 pmap_insert(map2, entry->key, entry->value);
1664 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1665 ir_node ** arr = entry->value;
1667 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1669 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1670 irg_ident, irg_ident);
1672 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1673 ir_node * node = arr[i];
1674 dump_node(node, map2);
1675 dump_ir_data_edges(node);
1676 if (is_Block(node)) {
1677 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1678 dump_node(node, map2);
1679 dump_ir_block_edge(node);
1680 dump_ir_data_edges(node);
1687 /* Close the vcg information for the irg */
1688 fprintf(F, "}\n\n");