3 * File name: ir/ir/irdump.c
4 * Purpose: Write vcg representation of firm to file.
5 * Author: Martin Trapp, Christian Schaefer
6 * Modified by: Goetz Lindenmaier, Hubert Schmidt
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
21 # include "irnode_t.h"
22 # include "irgraph_t.h"
23 # include "entity_t.h"
25 # include "firm_common_t.h"
30 # include "typewalk.h"
33 # include "type_or_entity.h"
45 /* Attributes of nodes */
46 #define PRINT_DEFAULT_NODE_ATTR
47 #define DEFAULT_NODE_ATTR " "
48 #define DEFAULT_TYPE_ATTRIBUTE " "
50 /* Attributes of edges between Firm nodes */
51 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
52 #define CF_EDGE_ATTR "color: red"
53 #define MEM_EDGE_ATTR "color: blue"
54 #define DOMINATOR_EDGE_ATTR "color: red"
56 #define BACK_EDGE_ATTR "linestyle: dashed "
58 /* Attributes of edges between Firm nodes and type/entity nodes */
59 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
61 /* Attributes of edges in type/entity graphs. */
62 #define TYPE_METH_NODE_ATTR "color: lightyellow"
63 #define TYPE_CLASS_NODE_ATTR "color: green"
64 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
65 #define ENTITY_NODE_ATTR "color: yellow"
66 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
67 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
68 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
69 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
70 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
71 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
72 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
73 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
74 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
75 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
76 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
77 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
78 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
81 #if DEBUG_libfirm && NODEID_AS_LABEL
82 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
83 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
84 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
85 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
86 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
89 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
90 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
91 #define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
92 #define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
93 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
96 #define PRINT_TYPE_TYPE_EDGE(S,T,...){fprintf (F, "edge: { sourcename: "); PRINT_TYPEID(S); fprintf (F, " targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
97 #define PRINT_TYPE_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: "); PRINT_TYPEID(S); fprintf (F, " targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
98 #define PRINT_ENT_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
99 #define PRINT_ENT_TYPE_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
100 #define PRINT_NODE_TYPE_EDGE(S,T,...){fprintf (F, "edge: { sourcename: \""); PRINT_NODEID(S); fprintf (F, "\" targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
101 #define PRINT_NODE_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_NODEID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
102 #define PRINT_ENT_NODE_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_NODEID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
105 /* A suffix to manipulate the file name. */
106 char *dump_file_suffix = NULL;
108 /* file to dump to */
111 /* A compiler option to turn off edge labels */
113 /* A compiler option to turn off dumping values of constant entities */
114 int const_entities = 1;
115 /* A compiler option to dump the keep alive edges */
116 int dump_keepalive = 0;
117 /* Compiler options to dump analysis information in dump_ir_graph */
118 int dump_out_edge_flag = 0;
119 int dump_dominator_information_flag = 0;
120 int dump_loop_information_flag = 0;
121 int dump_backedge_information_flag = 1;
122 int dump_const_local = 0;
123 bool opt_dump_analysed_type_info = 1;
125 INLINE bool get_opt_dump_const_local(void) {
126 if (!dump_out_edge_flag && !dump_loop_information_flag)
127 return dump_const_local;
132 /* A global variable to record output of the Bad node. */
133 static int Bad_dumped;
135 static void dump_ir_blocks_nodes (ir_node *n, void *env);
136 static void dump_whole_node(ir_node *n, void* env);
138 /*******************************************************************/
139 /* routines to dump information about a single node */
140 /*******************************************************************/
145 dump_node_opcode (ir_node *n)
150 switch(get_irn_opcode(n)) {
153 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
154 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
159 if (get_SymConst_kind(n) == linkage_ptr_info) {
160 /* don't use get_SymConst_ptr_info as it mangles the name. */
161 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
163 assert(get_kind(get_SymConst_type(n)) == k_type);
164 assert(get_type_ident(get_SymConst_type(n)));
165 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
166 if (get_SymConst_kind(n) == type_tag)
174 if (!interprocedural_view) fprintf(F, "Proj'");
178 fprintf (F, "%s", get_id_str(get_irn_opident(n)));
185 dump_node_mode (ir_node *n)
187 switch (get_irn_opcode(n)) {
206 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
213 static void dump_node_typeinfo(ir_node *n) {
214 if (!opt_dump_analysed_type_info) return;
215 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
216 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
217 type *tp = get_irn_type(n);
219 fprintf (F, " [%s]", get_type_name(tp));
226 dump_node_nodeattr (ir_node *n)
228 switch (get_irn_opcode(n)) {
230 if (false && interprocedural_view) {
231 fprintf (F, "%s", get_entity_name(get_irg_ent(current_ir_graph)));
235 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
236 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
238 fprintf (F, "%ld", get_Proj_proj(n));
242 fprintf (F, "%ld", get_Filter_proj(n));
245 fprintf (F, "%s", get_entity_name(get_Sel_entity(n)));
248 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
251 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
260 dump_node_vcgattr (ir_node *n)
262 switch (get_irn_opcode(n)) {
269 fprintf (F, "color: blue");
272 fprintf (F, "color: lightyellow");
275 fprintf (F, "color: green");
281 fprintf (F, "color: yellow");
284 PRINT_DEFAULT_NODE_ATTR;
289 dump_node_info (ir_node *n) {
291 fprintf (F, " info1: \"");
292 fprintf (F, "visited: %ld \n", get_irn_visited(n));
295 switch(get_irn_opcode(n)) {
297 type *tp = get_entity_type(get_irg_ent(get_Start_irg(n)));
298 fprintf(F, "start of method of type %s \n", get_type_name(tp));
299 for (i = 0; i < get_method_n_params(tp); ++i)
300 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
303 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
306 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
309 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
310 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
313 type *tp = get_Call_type(n);
314 fprintf(F, "calling method of type %s \n", get_type_name(tp));
315 for (i = 0; i < get_method_n_params(tp); ++i)
316 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
317 for (i = 0; i < get_method_n_ress(tp); ++i)
318 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
321 if (!interprocedural_view) {
322 type *tp = get_entity_type(get_irg_ent(current_ir_graph));
323 fprintf(F, "return in method of type %s \n", get_type_name(tp));
324 for (i = 0; i < get_method_n_ress(tp); ++i)
325 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
329 type *tp = get_Const_type(n);
330 assert(tp != none_type);
331 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
336 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
337 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent )
338 if (get_irn_type(n) != none_type)
339 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
345 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
346 ir_node *block = (is_Block(n)) ? n : get_nodes_block(n);
349 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
350 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
351 if (is_ip_cfop(pred)) {
352 ir_graph *irg = get_irn_irg(pred);
353 if (pmap_find(irgmap, irg) == NULL) return true;
362 bool is_constlike_node(ir_node *n) {
363 ir_op *op = get_irn_op(n);
364 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
368 /* outputs the predecessors of n, that are constants, local. I.e.,
369 generates a copy of the constant for each node called with. */
370 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
372 if (!get_opt_dump_const_local()) return;
373 /* Use visited flag to avoid outputting nodes twice.
374 initialize it first. */
375 for (i = 0; i < get_irn_arity(n); i++) {
376 ir_node *con = get_irn_n(n, i);
377 if (is_constlike_node(con)) {
378 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
379 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
382 for (i = 0; i < get_irn_arity(n); i++) {
383 ir_node *con = get_irn_n(n, i);
384 if (is_constlike_node(con) && irn_not_visited(con)) {
385 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
386 mark_irn_visited(con);
387 /* Generate a new name for the node by appending the names of
389 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
390 fprintf(F, " label: \"");
391 dump_node_opcode(con);
392 dump_node_mode (con);
393 dump_node_typeinfo(con);
395 dump_node_nodeattr(con);
397 fprintf (F, " %ld", get_irn_node_nr(con));
400 dump_node_vcgattr(con);
408 dump_node (ir_node *n, pmap * map) {
409 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
412 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
416 dump_node_typeinfo(n);
418 dump_node_nodeattr(n);
420 fprintf (F, " %ld", get_irn_node_nr(n));
423 dump_node_vcgattr(n);
426 dump_const_node_local(n, map);
429 /* dump the edge to the block this node belongs to */
431 dump_ir_block_edge(ir_node *n) {
432 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
433 if (is_no_Block(n)) {
434 fprintf (F, "edge: { sourcename: \"");
436 fprintf (F, "\" targetname: \"");
437 PRINT_NODEID(get_nodes_block(n));
438 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
442 static void print_edge_vcgattr(ir_node *from, int to) {
445 if (dump_backedge_information_flag && is_backedge(from, to))
446 fprintf (F, BACK_EDGE_ATTR);
448 switch (get_irn_opcode(from)) {
450 fprintf (F, CF_EDGE_ATTR);
452 case iro_Start: break;
455 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
456 fprintf (F, CF_EDGE_ATTR);
457 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
458 fprintf (F, MEM_EDGE_ATTR);
461 case iro_EndReg: break;
462 case iro_EndExcept: break;
464 case iro_Break: break;
465 case iro_Cond: break;
468 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
470 case iro_Const: break;
471 case iro_SymConst:break;
474 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
476 case iro_CallBegin: break;
479 case iro_Minus: break;
485 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
493 case iro_Shrs: break;
496 case iro_Conv: break;
498 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
504 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
507 fprintf (F, MEM_EDGE_ATTR);
509 case iro_Tuple: break;
512 switch (get_irn_modecode(from)) {
514 fprintf (F, CF_EDGE_ATTR);
517 fprintf (F, MEM_EDGE_ATTR);
523 case iro_Unknown: break;
530 /* dump edges to our inputs */
532 dump_ir_data_edges(ir_node *n, pmap *irgmap) {
533 int i, visited = get_irn_visited(n);
535 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
538 for (i = 0; i < get_irn_arity(n); i++) {
539 ir_node * pred = get_irn_n(n, i);
541 if ((interprocedural_view && get_irn_visited(pred) < visited))
542 continue; /* pred not dumped */
543 if (dump_backedge_information_flag && is_backedge(n, i))
544 fprintf (F, "backedge: {sourcename: \"");
546 fprintf (F, "edge: {sourcename: \"");
548 fprintf (F, "\" targetname: ");
549 if ((get_opt_dump_const_local()) && is_constlike_node(pred) &&
550 !pred_in_wrong_graph(n, i, irgmap)) {
551 PRINT_CONSTID(n, pred);
553 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
555 fprintf (F, " label: \"%d\" ", i);
556 print_edge_vcgattr(n, i);
563 dump_out_edge (ir_node *n, void* env) {
565 for (i = 0; i < get_irn_n_outs(n); i++) {
566 assert(get_irn_out(n, i));
567 fprintf (F, "edge: {sourcename: \"");
569 fprintf (F, "\" targetname: \"");
570 PRINT_NODEID(get_irn_out(n, i));
571 fprintf (F, "\" color: red linestyle: dashed");
577 dump_loop_node_edge (ir_loop *loop, int i) {
579 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
580 PRINT_NODEID(get_loop_node(loop, i));
581 fprintf (F, "\" color: green");
586 dump_loop_son_edge (ir_loop *loop, int i) {
588 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\" color: darkgreen}\n",
589 (void *)loop, (void *)get_loop_son(loop, i));
593 void dump_loops (ir_loop *loop) {
595 /* dump this loop node */
596 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
597 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
598 /* dump edges to nodes in loop -- only if it is a real loop */
599 if (get_loop_depth(loop) != 0) {
600 for (i = 0; i < get_loop_n_nodes(loop); i++) {
601 dump_loop_node_edge(loop, i);
604 for (i = 0; i < get_loop_n_sons(loop); i++) {
605 dump_loops(get_loop_son(loop, i));
606 dump_loop_son_edge(loop, i);
611 void dump_loop_info(ir_graph *irg) {
612 ir_graph *rem = current_ir_graph;
613 current_ir_graph = irg;
615 if (get_irg_loop(irg))
616 dump_loops(get_irg_loop(irg));
618 current_ir_graph = rem;
622 /* dumps the edges between nodes and their type or entity attributes. */
623 static void dump_node2type_edges (ir_node *n, void *env)
627 switch (get_irn_opcode(n)) {
629 /* @@@ some consts have an entity */
632 if ( (get_SymConst_kind(n) == type_tag)
633 || (get_SymConst_kind(n) == size))
635 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
639 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
642 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
645 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
648 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
651 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
659 static void dump_const_expression(ir_node *value) {
660 ir_graph *rem = current_ir_graph;
661 int rem_dump_const_local = dump_const_local;
662 dump_const_local = 0;
663 current_ir_graph = get_const_code_irg();
664 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_block(value));
665 /* Decrease visited flag so that we walk with the same flag for the next
666 expresssion. This guarantees that we don't dump the same node twice,
667 as for const expressions cse is performed to save memory. */
668 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
669 current_ir_graph = rem;
670 dump_const_local = rem_dump_const_local;
674 static void print_type_info(type *tp) {
675 if (get_type_state(tp) == layout_undefined) {
676 fprintf(F, "state: layout_undefined\n");
678 fprintf(F, "state: layout_fixed,\n");
680 if (get_type_mode(tp))
681 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
682 fprintf(F, "size: %dB,\n", get_type_size(tp));
686 static void print_typespecific_info(type *tp) {
687 switch (get_type_tpop_code(tp)) {
690 if (peculiarity_existent == get_class_peculiarity(tp))
691 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
693 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
697 fprintf (F, " " TYPE_METH_NODE_ATTR);
708 case tpo_enumeration:
721 static void print_type_node(type *tp)
723 fprintf (F, "node: {title: ");
725 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
726 fprintf (F, " info1: \"");
729 print_typespecific_info(tp);
733 #define X(a) case a: fprintf(F, #a); break
734 void dump_entity_node(entity *ent)
736 fprintf (F, "node: {title: \"");
737 PRINT_ENTID(ent); fprintf(F, "\"");
738 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
739 fprintf (F, "label: ");
740 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
741 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
743 fprintf (F, "\nallocation: ");
744 switch (get_entity_allocation(ent)) {
745 X(allocation_dynamic);
746 X(allocation_automatic);
747 X(allocation_static);
748 X(allocation_parameter);
751 fprintf (F, "\nvisibility: ");
752 switch (get_entity_visibility(ent)) {
754 X(visibility_external_visible);
755 X(visibility_external_allocated);
758 fprintf (F, "\nvariability: ");
759 switch (get_entity_variability(ent)) {
760 X(variability_uninitialized);
761 X(variability_initialized);
762 X(variability_part_constant);
763 X(variability_constant);
766 fprintf (F, "\nvolatility: ");
767 switch (get_entity_volatility(ent)) {
768 X(volatility_non_volatile);
769 X(volatility_is_volatile);
772 fprintf (F, "\npeculiarity: ");
773 switch (get_entity_peculiarity(ent)) {
774 X(peculiarity_description);
775 X(peculiarity_inherited);
776 X(peculiarity_existent);
778 fprintf(F, "\nname: %s\nld_name: %s",
779 get_entity_name(ent), get_entity_ld_name(ent));
780 fprintf(F, "\noffset: %d", get_entity_offset(ent));
781 if (is_method_type(get_entity_type(ent))) {
782 if (get_entity_irg(ent)) /* can be null */
783 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
785 { fprintf (F, "\nirg = NULL"); }
787 fprintf(F, "\"\n}\n");
791 /* dumps a type or entity and it's edges. */
793 dump_type_info (type_or_ent *tore, void *env) {
794 int i = 0; /* to shutup gcc */
796 /* dump this type or entity */
798 switch (get_kind(tore)) {
801 entity *ent = (entity *)tore;
804 dump_entity_node(ent);
806 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
807 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
808 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
809 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
810 if(is_class_type(get_entity_owner(ent))) {
811 for(i = 0; i < get_entity_n_overwrites(ent); i++){
812 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
815 /* attached subgraphs */
816 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
817 if (is_atomic_entity(ent)) {
818 value = get_atomic_ent_value(ent);
820 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
821 /* DDMN(value); $$$ */
822 dump_const_expression(value);
825 if (is_compound_entity(ent)) {
826 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
827 value = get_compound_ent_value(ent, i);
829 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
830 dump_const_expression(value);
831 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
833 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
834 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
835 get_compound_ent_value_member(ent, i), i);
844 type *tp = (type *)tore;
846 /* and now the edges */
847 switch (get_type_tpop_code(tp)) {
850 for (i=0; i < get_class_n_supertypes(tp); i++) {
851 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
854 for (i=0; i < get_class_n_members(tp); i++) {
855 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
860 for (i=0; i < get_struct_n_members(tp); i++) {
861 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
866 for (i = 0; i < get_method_n_params(tp); i++)
868 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
870 for (i = 0; i < get_method_n_ress(tp); i++)
872 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
877 for (i = 0; i < get_union_n_members(tp); i++)
879 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
884 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
885 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
886 for (i = 0; i < get_array_n_dimensions(tp); i++) {
887 ir_node *upper = get_array_upper_bound(tp, i);
888 ir_node *lower = get_array_lower_bound(tp, i);
889 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
890 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
891 dump_const_expression(upper);
892 dump_const_expression(lower);
896 case tpo_enumeration:
901 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
909 break; /* case k_type */
912 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
914 } /* switch kind_or_entity */
917 /* dumps a class type node and a superclass edge.
918 If env != null dumps entities of classes and overwrites edges. */
920 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
921 int i = 0; /* to shutup gcc */
923 /* dump this type or entity */
924 switch (get_kind(tore)) {
926 entity *ent = (entity *)tore;
927 if (get_entity_owner(ent) == get_glob_type()) break;
928 if ((env) && is_class_type(get_entity_owner(ent))) {
930 dump_entity_node(ent);
932 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
933 for(i = 0; i < get_entity_n_overwrites(ent); i++)
935 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
938 } break; /* case k_entity */
941 type *tp = (type *)tore;
942 if (tp == get_glob_type()) break;
943 switch (get_type_tpop_code(tp)) {
946 /* and now the edges */
947 for (i=0; i < get_class_n_supertypes(tp); i++)
949 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
955 break; /* case k_type */
958 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
960 } /* switch kind_or_entity */
963 /************************************************************************/
964 /* open and close vcg file */
965 /************************************************************************/
967 static void vcg_open (ir_graph *irg, char *suffix) {
968 char *fname; /* filename to put the vcg information in */
975 /** open file for vcg graph */
976 ent = get_irg_ent(irg);
977 id = ent->ld_name ? ent->ld_name : ent->name;
978 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
979 len = get_id_strlen (id);
980 cp = get_id_str (id);
981 if (dump_file_suffix)
982 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
984 fname = malloc (len + 5 + strlen(suffix));
985 strncpy (fname, cp, len); /* copy the filename */
987 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
988 strcat (fname, suffix); /* append file suffix */
989 strcat (fname, ".vcg"); /* append the .vcg suffix */
990 F = fopen (fname, "w"); /* open file for writing */
992 panic ("cannot open %s for writing (%m)", fname); /* not reached */
996 strcpy(label, "yes");
998 strcpy (label, "no");
1003 "graph: { title: \"ir graph of %s\"\n"
1004 "display_edge_labels: %s\n"
1005 "layoutalgorithm: mindepth\n"
1006 "manhattan_edges: yes\n"
1007 "port_sharing: no\n"
1008 "orientation: bottom_to_top\n"
1009 "classname 1: \"Data\"\n"
1010 "classname 2: \"Block\"\n"
1011 "classname 3: \"Entity type\"\n"
1012 "classname 4: \"Entity owner\"\n"
1013 "classname 5: \"Method Param\"\n"
1014 "classname 6: \"Method Res\"\n"
1015 "classname 7: \"Super\"\n"
1016 "classname 8: \"Union\"\n"
1017 "classname 9: \"Points-to\"\n"
1018 "classname 10: \"Array Element Type\"\n"
1019 "classname 11: \"Overwrites\"\n"
1020 "classname 12: \"Member\"\n"
1023 fprintf (F, "\n"); /* a separator */
1026 static void vcg_open_name (const char *name) {
1027 char *fname; /* filename to put the vcg information in */
1031 /** open file for vcg graph */
1033 fname = malloc (len + 5);
1034 if (dump_file_suffix)
1035 fname = malloc (len + 5 + strlen(dump_file_suffix));
1037 fname = malloc (len + 5);
1038 strcpy (fname, name); /* copy the filename */
1039 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1040 strcat (fname, ".vcg"); /* append the .vcg suffix */
1041 F = fopen (fname, "w"); /* open file for writing */
1043 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1047 strcpy(label, "yes");
1049 strcpy (label, "no");
1054 "graph: { title: \"ir graph of %s\"\n"
1055 "display_edge_labels: %s\n"
1056 "layoutalgorithm: mindepth\n"
1057 "manhattan_edges: yes\n"
1058 "port_sharing: no\n"
1059 "orientation: bottom_to_top\n"
1060 "classname 1: \"Data\"\n"
1061 "classname 2: \"Block\"\n"
1062 "classname 3: \"Entity type\"\n"
1063 "classname 4: \"Entity owner\"\n"
1064 "classname 5: \"Method Param\"\n"
1065 "classname 6: \"Method Res\"\n"
1066 "classname 7: \"Super\"\n"
1067 "classname 8: \"Union\"\n"
1068 "classname 9: \"Points-to\"\n"
1069 "classname 10: \"Array Element Type\"\n"
1070 "classname 11: \"Overwrites\"\n"
1071 "classname 12: \"Member\"\n"
1074 fprintf (F, "\n"); /* a separator */
1079 fprintf (F, "}\n"); /* print footer */
1080 fclose (F); /* close vcg file */
1083 /************************************************************************/
1084 /* routines to dump a graph, blocks as conventional nodes. */
1085 /************************************************************************/
1087 static int node_floats(ir_node *n) {
1088 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1089 (get_irg_pinned(current_ir_graph) == floats));
1093 dump_whole_node (ir_node *n, void* env) {
1095 if (!node_floats(n)) dump_ir_block_edge(n);
1096 dump_ir_data_edges(n, NULL);
1100 dump_ir_graph (ir_graph *irg)
1103 rem = current_ir_graph;
1104 current_ir_graph = irg;
1108 /* walk over the graph */
1109 /* dump_whole_node must be called in post visiting predecessors */
1110 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1112 /* dump the out edges in a separate walk */
1113 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1114 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1119 current_ir_graph = rem;
1122 /***********************************************************************/
1123 /* the following routines dump the nodes as attached to the blocks. */
1124 /***********************************************************************/
1127 dump_ir_blocks_nodes (ir_node *n, void *env) {
1128 ir_node *block = (ir_node *)env;
1130 if (is_no_Block(n) && get_nodes_block(n) == block && !node_floats(n)) {
1132 dump_ir_data_edges(n, NULL);
1134 if (get_irn_op(n) == op_Bad)
1139 dump_ir_block (ir_node *block, void *env) {
1140 ir_graph *irg = (ir_graph *)env;
1142 if (is_Block(block)) {
1144 /* This is a block. So dump the vcg information to make a block. */
1145 fprintf(F, "graph: { title: \"");
1146 PRINT_NODEID(block);
1147 fprintf(F, "\" label: \"");
1148 #ifdef DEBUG_libfirm
1149 fprintf (F, "%ld", get_irn_node_nr(block));
1151 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1153 // if (exc_normal != get_Block_exc (block))
1154 // fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1156 fprintf(F, "\" status:clustered color:%s \n",
1157 get_Block_matured (block) ? "yellow" : "red");
1158 /* dump the blocks edges */
1159 dump_ir_data_edges(block, NULL);
1161 /* dump the nodes that go into the block */
1162 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1164 /* Close the vcg information for the block */
1165 fprintf(F, "}\n\n");
1166 dump_const_node_local(block, NULL);
1172 dump_blockless_nodes (ir_node *n, void *env) {
1173 if (is_no_Block(n) && get_irn_op(get_nodes_block(n)) == op_Bad) {
1175 dump_ir_data_edges(n, NULL);
1176 dump_ir_block_edge(n);
1177 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1180 if (node_floats(n)) {
1182 dump_ir_data_edges(n, NULL);
1183 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1187 static void dump_ir_block_graph_2 (ir_graph *irg)
1190 /* walk over the blocks in the graph */
1191 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1193 /* dump all nodes that are not in a Block */
1194 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1196 /* dump the Bad node */
1198 dump_node(get_irg_bad(irg), NULL);
1202 dump_ir_block_graph (ir_graph *irg)
1205 rem = current_ir_graph;
1206 current_ir_graph = irg;
1210 dump_ir_block_graph_2 (irg);
1212 if (dump_loop_information_flag) dump_loop_info(irg);
1215 current_ir_graph = rem;
1219 /***********************************************************************/
1220 /* the following routines dump a control flow graph */
1221 /***********************************************************************/
1225 dump_block_to_cfg (ir_node *block, void *env) {
1229 if (is_Block(block)) {
1230 /* This is a block. Dump a node for the block. */
1231 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1232 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1233 PRINT_NODEID(block);
1235 if (dump_dominator_information_flag)
1236 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1238 /* Dump the edges */
1239 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1240 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1241 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1242 fprintf (F, "edge: { sourcename: \"");
1243 PRINT_NODEID(block);
1244 fprintf (F, "\" targetname: \"");
1246 fprintf (F, "\"}\n");
1249 /* Dump dominator edge */
1250 if (dump_dominator_information_flag && get_Block_idom(block)) {
1251 pred = get_Block_idom(block);
1252 fprintf (F, "edge: { sourcename: \"");
1253 PRINT_NODEID(block);
1254 fprintf (F, "\" targetname: \"");
1256 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1262 dump_cfg (ir_graph *irg)
1264 ir_graph *rem = current_ir_graph;
1265 int ddif = dump_dominator_information_flag;
1266 current_ir_graph = irg;
1267 vcg_open (irg, "-cfg");
1269 if (get_irg_dom_state(irg) != dom_consistent)
1270 dump_dominator_information_flag = 0;
1272 /* walk over the blocks in the graph */
1273 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1274 dump_node (get_irg_bad(irg), NULL);
1276 dump_dominator_information_flag = ddif;
1278 current_ir_graph = rem;
1282 /***********************************************************************/
1283 /* the following routine dumps all type information reachable from an */
1285 /***********************************************************************/
1289 dump_type_graph (ir_graph *irg)
1292 rem = current_ir_graph;
1293 current_ir_graph = irg;
1295 vcg_open (irg, "-type");
1297 /* walk over the blocks in the graph */
1298 type_walk_irg(irg, dump_type_info, NULL, NULL);
1299 /* The walker for the const code can be called several times for the
1300 same (sub) experssion. So that no nodes are dumped several times
1301 we decrease the visited flag of the corresponding graph after each
1302 walk. So now increase it finally. */
1303 inc_irg_visited(get_const_code_irg());
1306 current_ir_graph = rem;
1309 /***********************************************************************/
1310 /* the following routine dumps all type information */
1311 /***********************************************************************/
1315 dump_all_types (void)
1317 vcg_open_name ("All_types");
1318 type_walk(dump_type_info, NULL, NULL);
1319 inc_irg_visited(get_const_code_irg());
1324 dump_class_hierarchy (bool entities)
1326 vcg_open_name ("class_hierarchy");
1328 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1330 type_walk(dump_class_hierarchy_node, NULL, NULL);
1334 /***********************************************************************/
1335 /* dumps a graph with type information */
1336 /***********************************************************************/
1340 dump_ir_graph_w_types (ir_graph *irg)
1343 rem = current_ir_graph;
1344 current_ir_graph = irg;
1346 vcg_open (irg, "-all");
1348 /* dump common ir graph */
1349 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1350 /* dump type info */
1351 type_walk_irg(irg, dump_type_info, NULL, NULL);
1352 inc_irg_visited(get_const_code_irg());
1353 /* dump edges from graph to type info */
1354 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1357 current_ir_graph = rem;
1361 dump_ir_block_graph_w_types (ir_graph *irg)
1364 rem = current_ir_graph;
1365 current_ir_graph = irg;
1367 vcg_open (irg, "-all");
1369 /* dump common blocked ir graph */
1370 dump_ir_block_graph_2(irg);
1371 /* dump type info */
1372 type_walk_irg(irg, dump_type_info, NULL, NULL);
1373 inc_irg_visited(get_const_code_irg());
1374 /* dump edges from graph to type info */
1375 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1378 current_ir_graph = rem;
1381 /***********************************************************************/
1382 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1384 /* dump_ir_block_graph */
1386 /* dump_type_graph */
1387 /* dump_ir_graph_w_types */
1388 /***********************************************************************/
1389 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1391 for (i=0; i < get_irp_n_irgs(); i++) {
1392 dump_graph(get_irp_irg(i));
1397 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1398 abort with a segmentation fault. */
1399 void turn_off_edge_labels(void) {
1404 void dump_consts_local(bool b) {
1405 dump_const_local = b;
1408 void turn_off_constant_entity_values(void) {
1412 void dump_keepalive_edges(bool b) {
1416 bool get_opt_dump_keepalive_edges(void) {
1417 return dump_keepalive;
1420 void dump_out_edges(void) {
1421 dump_out_edge_flag = 1;
1424 void dump_dominator_information(void) {
1425 dump_dominator_information_flag = 1;
1428 void dump_loop_information(void) {
1429 dump_loop_information_flag = 1;
1432 void dont_dump_loop_information(void) {
1433 dump_loop_information_flag = 0;
1436 void dump_backedge_information(bool b) {
1437 dump_backedge_information_flag = b;
1440 static void clear_link(ir_node * node, void * env) {
1441 set_irn_link(node, NULL);
1445 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1446 assert(node); assert(map);
1448 || node_floats(node)
1449 || get_irn_op(node) == op_Bad
1450 || get_irn_op(node) == op_Unknown) {
1451 pmap_entry * entry = pmap_find(map, current_ir_graph);
1457 ARR_APP1(ir_node *, arr, node);
1458 entry->value = (void *)arr;
1460 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1463 pmap_insert(map, current_ir_graph, arr);
1466 ir_node * block = get_nodes_block(node);
1467 set_irn_link(node, get_irn_link(block));
1468 set_irn_link(block, node);
1473 static void dump_cg_ir_block(ir_node * block, void * env) {
1475 pmap *irgmap = (pmap *)env;
1476 assert(is_Block(block));
1478 fprintf(F, "graph: { title: \"");
1479 PRINT_NODEID(block);
1480 fprintf(F, "\" label: \"");
1481 dump_node_opcode(block);
1482 fprintf (F, " %ld", get_irn_node_nr(block));
1484 // if (exc_normal != get_Block_exc(block)) {
1485 // fprintf (F, " (%s)", exc_to_string (get_Block_exc(block))); }
1487 fprintf(F, "\" status:clustered color:%s \n",
1488 get_Block_matured(block) ? "yellow" : "red");
1490 /* dump the blocks edges */
1491 dump_ir_data_edges(block, irgmap);
1493 /* dump the nodes that go into the block */
1494 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1495 dump_node(node, irgmap);
1496 dump_ir_data_edges(node, irgmap);
1499 /* Close the vcg information for the block */
1501 dump_const_node_local(block, irgmap);
1505 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1508 fprintf(F, "graph: { title: \"%p\" label: \"%s\" status:clustered color:white \n",
1509 (void*) irg, get_entity_name(get_irg_ent(irg)));
1511 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1512 ir_node * node = arr[i];
1513 if (is_Block(node)) {
1514 /* Dumps the block and all the nodes in the block, which are to
1515 be found in Block->link. */
1516 dump_cg_ir_block(node, irgmap);
1518 /* Nodes that are not in a Block. */
1519 dump_node(node, NULL);
1520 dump_ir_data_edges(node, NULL);
1523 /* Close the vcg information for the irg */
1524 fprintf(F, "}\n\n");
1527 /* dump interprocedural graph with surrounding methods */
1528 void dump_cg_block_graph(ir_graph * irg) {
1529 pmap * map = pmap_create();
1530 pmap * map2 = pmap_create();
1535 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1536 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1537 pmap_insert(map2, entry->key, entry->value);
1538 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1539 d_cg_block_graph(entry->key, entry->value, map2);
1540 DEL_ARR_F(entry->value);
1546 if (dump_loop_information_flag) dump_loop_info(irg);
1550 static void collect_node(ir_node * node, void *env) {
1552 || node_floats(node)
1553 || get_irn_op(node) == op_Bad
1554 || get_irn_op(node) == op_Unknown) {
1555 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1556 ARR_APP1(ir_node *, arr, node);
1557 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1559 ir_node * block = get_nodes_block(node);
1560 set_irn_link(node, get_irn_link(block));
1561 set_irn_link(block, node);
1565 /* Links all nodes that have the block field set in the link field of
1566 the block. Adds all blocks and nodes not associated with a block
1567 in an array in irg->link. */
1568 static void collect_nodes(void) {
1570 for (i = 0; i < get_irp_n_irgs(); i++)
1571 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1572 cg_walk(clear_link, collect_node, NULL);
1575 static void dump_graphs(void) {
1577 for (i = 0; i < get_irp_n_irgs(); i++) {
1578 current_ir_graph = get_irp_irg(i);
1579 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1583 /* Dump all irgs in interprocedural view to a single file. */
1584 void dump_all_cg_block_graph(void) {
1586 int rem_view = interprocedural_view;
1587 interprocedural_view = 1;
1588 vcg_open_name ("All_graphs");
1593 if (dump_loop_information_flag)
1594 for (i = 0; i < get_irp_n_irgs(); i++)
1595 dump_loop_info(get_irp_irg(i));
1598 interprocedural_view = rem_view;
1601 /* dump interprocedural block graph with surrounding methods */
1602 void dump_cg_graph(ir_graph * irg) {
1603 pmap * map = pmap_create();
1604 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1608 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1609 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1610 pmap_insert(map2, entry->key, entry->value);
1611 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1612 ir_node ** arr = entry->value;
1614 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1616 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1617 get_id_str(irg_ident), get_id_str(irg_ident));
1619 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1620 ir_node * node = arr[i];
1621 dump_node(node, map2);
1622 dump_ir_data_edges(node, NULL);
1623 if (is_Block(node)) {
1624 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1625 dump_node(node, map2);
1626 dump_ir_block_edge(node);
1627 dump_ir_data_edges(node, NULL);
1634 /* Close the vcg information for the irg */
1635 fprintf(F, "}\n\n");
1644 /* Dump the information of type field specified in ana/irtypeinfo.h.
1645 * If the flag is set, the type name is output in [] in the node label,
1646 * else it is output as info.
1648 void dump_analysed_type_info(bool b) {
1649 opt_dump_analysed_type_info = b;