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, "\"%p%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_const_local = 0;
122 bool opt_dump_analysed_type_info = 1;
124 INLINE bool get_opt_dump_const_local(void) {
125 if (!dump_out_edge_flag && !dump_loop_information_flag)
126 return dump_const_local;
131 /* A global variable to record output of the Bad node. */
132 static int Bad_dumped;
134 static void dump_ir_blocks_nodes (ir_node *n, void *env);
135 static void dump_whole_node(ir_node *n, void* env);
137 /*******************************************************************/
138 /* routines to dump information about a single node */
139 /*******************************************************************/
144 dump_node_opcode (ir_node *n)
149 switch(get_irn_opcode(n)) {
152 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
153 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
158 if (get_SymConst_kind(n) == linkage_ptr_info) {
159 /* don't use get_SymConst_ptr_info as it mangles the name. */
160 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
162 assert(get_kind(get_SymConst_type(n)) == k_type);
163 assert(get_type_ident(get_SymConst_type(n)));
164 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
165 if (get_SymConst_kind(n) == type_tag)
173 if (!interprocedural_view) fprintf(F, "Proj'");
177 fprintf (F, "%s", get_id_str(get_irn_opident(n)));
184 dump_node_mode (ir_node *n)
186 switch (get_irn_opcode(n)) {
205 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
212 static void dump_node_typeinfo(ir_node *n) {
213 if (!opt_dump_analysed_type_info) return;
214 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
215 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
216 type *tp = get_irn_type(n);
218 fprintf (F, " [%s]", get_type_name(tp));
225 dump_node_nodeattr (ir_node *n)
227 switch (get_irn_opcode(n)) {
229 if (false && interprocedural_view) {
230 fprintf (F, "%s", get_entity_name(get_irg_ent(current_ir_graph)));
234 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
235 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
237 fprintf (F, "%ld", get_Proj_proj(n));
241 fprintf (F, "%ld", get_Filter_proj(n));
244 assert(get_kind(get_Sel_entity(n)) == k_entity);
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_ip_cfop_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 (is_backedge(from, to)) fprintf (F, BACK_EDGE_ATTR);
447 switch (get_irn_opcode(from)) {
449 fprintf (F, CF_EDGE_ATTR);
451 case iro_Start: break;
454 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
455 fprintf (F, CF_EDGE_ATTR);
456 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
457 fprintf (F, MEM_EDGE_ATTR);
460 case iro_EndReg: break;
461 case iro_EndExcept: break;
463 case iro_Break: break;
464 case iro_Cond: break;
467 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
469 case iro_Const: break;
470 case iro_SymConst:break;
473 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
475 case iro_CallBegin: break;
478 case iro_Minus: break;
484 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
492 case iro_Shrs: break;
495 case iro_Conv: break;
497 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
503 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
506 fprintf (F, MEM_EDGE_ATTR);
508 case iro_Tuple: break;
511 switch (get_irn_modecode(from)) {
513 fprintf (F, CF_EDGE_ATTR);
516 fprintf (F, MEM_EDGE_ATTR);
522 case iro_Unknown: break;
529 /* dump edges to our inputs */
531 dump_ir_data_edges(ir_node *n, pmap *irgmap) {
532 int i, visited = get_irn_visited(n);
534 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
537 for (i = 0; i < get_irn_arity(n); i++) {
538 ir_node * pred = get_irn_n(n, i);
540 if ((interprocedural_view && get_irn_visited(pred) < visited))
541 continue; /* pred not dumped */
542 if (is_backedge(n, i))
543 fprintf (F, "backedge: {sourcename: \"");
545 fprintf (F, "edge: {sourcename: \"");
547 fprintf (F, "\" targetname: ");
548 if ((get_opt_dump_const_local()) && is_constlike_node(pred) &&
549 !pred_in_wrong_graph(n, i, irgmap))
551 PRINT_CONSTID(n, pred);
554 {fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
556 fprintf (F, " label: \"%d\" ", i);
557 print_edge_vcgattr(n, i);
564 dump_out_edge (ir_node *n, void* env) {
566 for (i = 0; i < get_irn_n_outs(n); i++) {
567 assert(get_irn_out(n, i));
568 fprintf (F, "edge: {sourcename: \"");
570 fprintf (F, "\" targetname: \"");
571 PRINT_NODEID(get_irn_out(n, i));
572 fprintf (F, "\" color: red linestyle: dashed");
578 dump_loop_node_edge (ir_loop *loop, int i) {
580 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
581 PRINT_NODEID(get_loop_node(loop, i));
582 fprintf (F, "\" color: green");
587 void dump_loops (ir_loop *loop) {
589 /* dump this loop node */
590 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
591 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
592 /* dump edges to nodes in loop -- only if it is a real loop */
593 if (get_loop_depth(loop) != 0) {
594 for (i = 0; i < get_loop_n_nodes(loop); i++) {
595 dump_loop_node_edge(loop, i);
598 for (i = 0; i < get_loop_n_sons(loop); i++) {
599 dump_loops(get_loop_son(loop, i));
604 void dump_loop_info(ir_graph *irg) {
605 ir_graph *rem = current_ir_graph;
606 current_ir_graph = irg;
608 if (get_irg_loop(irg))
609 dump_loops(get_irg_loop(irg));
611 current_ir_graph = rem;
615 /* dumps the edges between nodes and their type or entity attributes. */
616 static void dump_node2type_edges (ir_node *n, void *env)
620 switch (get_irn_opcode(n)) {
622 /* @@@ some consts have an entity */
625 if ( (get_SymConst_kind(n) == type_tag)
626 || (get_SymConst_kind(n) == size))
628 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
632 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
635 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
638 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
641 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
644 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
652 static void dump_const_expression(ir_node *value) {
653 ir_graph *rem = current_ir_graph;
654 int rem_dump_const_local = dump_const_local;
655 dump_const_local = 0;
656 current_ir_graph = get_const_code_irg();
657 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
658 /* Decrease visited flag so that we walk with the same flag for the next
659 expresssion. This guarantees that we don't dump the same node twice,
660 as for const expressions cse is performed to save memory. */
661 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
662 current_ir_graph = rem;
663 dump_const_local = rem_dump_const_local;
667 static void print_type_info(type *tp) {
668 if (get_type_state(tp) == layout_undefined) {
669 fprintf(F, "state: layout_undefined\n");
671 fprintf(F, "state: layout_fixed,\n");
673 if (get_type_mode(tp))
674 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
675 fprintf(F, "size: %dB,\n", get_type_size(tp));
679 static void print_typespecific_info(type *tp) {
680 switch (get_type_tpop_code(tp)) {
683 if (peculiarity_existent == get_class_peculiarity(tp))
684 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
686 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
690 fprintf (F, " " TYPE_METH_NODE_ATTR);
701 case tpo_enumeration:
714 static void print_type_node(type *tp)
716 fprintf (F, "node: {title: ");
718 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
719 fprintf (F, " info1: \"");
722 print_typespecific_info(tp);
726 #define X(a) case a: fprintf(F, #a); break
727 void dump_entity_node(entity *ent)
729 fprintf (F, "node: {title: \"");
730 PRINT_ENTID(ent); fprintf(F, "\"");
731 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
732 fprintf (F, "label: ");
733 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
734 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
736 fprintf (F, "\nallocation: ");
737 switch (get_entity_allocation(ent)) {
738 X(allocation_dynamic);
739 X(allocation_automatic);
740 X(allocation_static);
741 X(allocation_parameter);
744 fprintf (F, "\nvisibility: ");
745 switch (get_entity_visibility(ent)) {
747 X(visibility_external_visible);
748 X(visibility_external_allocated);
751 fprintf (F, "\nvariability: ");
752 switch (get_entity_variability(ent)) {
753 X(variability_uninitialized);
754 X(variability_initialized);
755 X(variability_part_constant);
756 X(variability_constant);
759 fprintf (F, "\nvolatility: ");
760 switch (get_entity_volatility(ent)) {
761 X(volatility_non_volatile);
762 X(volatility_is_volatile);
765 fprintf (F, "\npeculiarity: ");
766 switch (get_entity_peculiarity(ent)) {
767 X(peculiarity_description);
768 X(peculiarity_inherited);
769 X(peculiarity_existent);
771 fprintf(F, "\nname: %s\nld_name: %s",
772 get_entity_name(ent), get_entity_ld_name(ent));
773 fprintf(F, "\noffset: %d", get_entity_offset(ent));
774 if (is_method_type(get_entity_type(ent))) {
775 if (get_entity_irg(ent)) /* can be null */
776 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
778 { fprintf (F, "\nirg = NULL"); }
780 fprintf(F, "\"\n}\n");
784 /* dumps a type or entity and it's edges. */
786 dump_type_info (type_or_ent *tore, void *env) {
787 int i = 0; /* to shutup gcc */
789 /* dump this type or entity */
791 switch (get_kind(tore)) {
794 entity *ent = (entity *)tore;
797 dump_entity_node(ent);
799 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
800 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
801 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
802 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
803 if(is_class_type(get_entity_owner(ent))) {
804 for(i = 0; i < get_entity_n_overwrites(ent); i++){
805 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
808 /* attached subgraphs */
809 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
810 if (is_atomic_entity(ent)) {
811 value = get_atomic_ent_value(ent);
813 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
814 /* DDMN(value); $$$ */
815 dump_const_expression(value);
818 if (is_compound_entity(ent)) {
819 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
820 value = get_compound_ent_value(ent, i);
822 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
823 dump_const_expression(value);
824 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
826 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
827 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
828 get_compound_ent_value_member(ent, i), i);
837 type *tp = (type *)tore;
839 /* and now the edges */
840 switch (get_type_tpop_code(tp)) {
843 for (i=0; i < get_class_n_supertypes(tp); i++) {
844 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
847 for (i=0; i < get_class_n_members(tp); i++) {
848 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
853 for (i=0; i < get_struct_n_members(tp); i++) {
854 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
859 for (i = 0; i < get_method_n_params(tp); i++)
861 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
863 for (i = 0; i < get_method_n_ress(tp); i++)
865 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
870 for (i = 0; i < get_union_n_members(tp); i++)
872 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
877 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
878 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
879 for (i = 0; i < get_array_n_dimensions(tp); i++) {
880 ir_node *upper = get_array_upper_bound(tp, i);
881 ir_node *lower = get_array_lower_bound(tp, i);
882 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
883 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
884 dump_const_expression(upper);
885 dump_const_expression(lower);
889 case tpo_enumeration:
894 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
902 break; /* case k_type */
905 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
907 } /* switch kind_or_entity */
910 /* dumps a class type node and a superclass edge.
911 If env != null dumps entities of classes and overwrites edges. */
913 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
914 int i = 0; /* to shutup gcc */
916 /* dump this type or entity */
917 switch (get_kind(tore)) {
919 entity *ent = (entity *)tore;
920 if (get_entity_owner(ent) == get_glob_type()) break;
921 if ((env) && is_class_type(get_entity_owner(ent))) {
923 dump_entity_node(ent);
925 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
926 for(i = 0; i < get_entity_n_overwrites(ent); i++)
928 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
931 } break; /* case k_entity */
934 type *tp = (type *)tore;
935 if (tp == get_glob_type()) break;
936 switch (get_type_tpop_code(tp)) {
939 /* and now the edges */
940 for (i=0; i < get_class_n_supertypes(tp); i++)
942 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
948 break; /* case k_type */
951 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
953 } /* switch kind_or_entity */
956 /************************************************************************/
957 /* open and close vcg file */
958 /************************************************************************/
960 static void vcg_open (ir_graph *irg, char *suffix) {
961 char *fname; /* filename to put the vcg information in */
968 /** open file for vcg graph */
969 ent = get_irg_ent(irg);
970 id = ent->ld_name ? ent->ld_name : ent->name;
971 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
972 len = get_id_strlen (id);
973 cp = get_id_str (id);
974 if (dump_file_suffix)
975 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
977 fname = malloc (len + 5 + strlen(suffix));
978 strncpy (fname, cp, len); /* copy the filename */
980 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
981 strcat (fname, suffix); /* append file suffix */
982 strcat (fname, ".vcg"); /* append the .vcg suffix */
983 F = fopen (fname, "w"); /* open file for writing */
985 panic ("cannot open %s for writing (%m)", fname); /* not reached */
989 strcpy(label, "yes");
991 strcpy (label, "no");
996 "graph: { title: \"ir graph of %s\"\n"
997 "display_edge_labels: %s\n"
998 "layoutalgorithm: mindepth\n"
999 "manhattan_edges: yes\n"
1000 "port_sharing: no\n"
1001 "orientation: bottom_to_top\n"
1002 "classname 1: \"Data\"\n"
1003 "classname 2: \"Block\"\n"
1004 "classname 3: \"Entity type\"\n"
1005 "classname 4: \"Entity owner\"\n"
1006 "classname 5: \"Method Param\"\n"
1007 "classname 6: \"Method Res\"\n"
1008 "classname 7: \"Super\"\n"
1009 "classname 8: \"Union\"\n"
1010 "classname 9: \"Points-to\"\n"
1011 "classname 10: \"Array Element Type\"\n"
1012 "classname 11: \"Overwrites\"\n"
1013 "classname 12: \"Member\"\n"
1016 fprintf (F, "\n"); /* a separator */
1019 static void vcg_open_name (const char *name) {
1020 char *fname; /* filename to put the vcg information in */
1024 /** open file for vcg graph */
1026 fname = malloc (len + 5);
1027 if (dump_file_suffix)
1028 fname = malloc (len + 5 + strlen(dump_file_suffix));
1030 fname = malloc (len + 5);
1031 strcpy (fname, name); /* copy the filename */
1032 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1033 strcat (fname, ".vcg"); /* append the .vcg suffix */
1034 F = fopen (fname, "w"); /* open file for writing */
1036 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1040 strcpy(label, "yes");
1042 strcpy (label, "no");
1047 "graph: { title: \"ir graph of %s\"\n"
1048 "display_edge_labels: %s\n"
1049 "layoutalgorithm: mindepth\n"
1050 "manhattan_edges: yes\n"
1051 "port_sharing: no\n"
1052 "orientation: bottom_to_top\n"
1053 "classname 1: \"Data\"\n"
1054 "classname 2: \"Block\"\n"
1055 "classname 3: \"Entity type\"\n"
1056 "classname 4: \"Entity owner\"\n"
1057 "classname 5: \"Method Param\"\n"
1058 "classname 6: \"Method Res\"\n"
1059 "classname 7: \"Super\"\n"
1060 "classname 8: \"Union\"\n"
1061 "classname 9: \"Points-to\"\n"
1062 "classname 10: \"Array Element Type\"\n"
1063 "classname 11: \"Overwrites\"\n"
1064 "classname 12: \"Member\"\n"
1067 fprintf (F, "\n"); /* a separator */
1072 fprintf (F, "}\n"); /* print footer */
1073 fclose (F); /* close vcg file */
1076 /************************************************************************/
1077 /* routines to dump a graph, blocks as conventional nodes. */
1078 /************************************************************************/
1080 static int node_floats(ir_node *n) {
1081 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1082 (get_irg_pinned(current_ir_graph) == floats));
1086 dump_whole_node (ir_node *n, void* env) {
1088 if (!node_floats(n)) dump_ir_block_edge(n);
1089 dump_ir_data_edges(n, NULL);
1093 dump_ir_graph (ir_graph *irg)
1096 rem = current_ir_graph;
1097 current_ir_graph = irg;
1101 /* walk over the graph */
1102 /* dump_whole_node must be called in post visiting predecessors */
1103 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1105 /* dump the out edges in a separate walk */
1106 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1107 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1112 current_ir_graph = rem;
1115 /***********************************************************************/
1116 /* the following routines dump the nodes as attached to the blocks. */
1117 /***********************************************************************/
1120 dump_ir_blocks_nodes (ir_node *n, void *env) {
1121 ir_node *block = (ir_node *)env;
1123 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1125 dump_ir_data_edges(n, NULL);
1127 if (get_irn_op(n) == op_Bad)
1132 dump_ir_block (ir_node *block, void *env) {
1133 ir_graph *irg = (ir_graph *)env;
1135 if (get_irn_opcode(block) == iro_Block) {
1137 /* This is a block. So dump the vcg information to make a block. */
1138 fprintf(F, "graph: { title: \"");
1139 PRINT_NODEID(block);
1140 fprintf(F, "\" label: \"");
1141 #ifdef DEBUG_libfirm
1142 fprintf (F, "%ld", get_irn_node_nr(block));
1144 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1146 if (exc_normal != get_Block_exc (block))
1147 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1149 fprintf(F, "\" status:clustered color:%s \n",
1150 get_Block_matured (block) ? "yellow" : "red");
1151 /* dump the blocks edges */
1152 dump_ir_data_edges(block, NULL);
1154 /* dump the nodes that go into the block */
1155 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1157 /* Close the vcg information for the block */
1158 fprintf(F, "}\n\n");
1159 dump_const_node_local(block, NULL);
1165 dump_blockless_nodes (ir_node *n, void *env) {
1166 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1168 dump_ir_data_edges(n, NULL);
1169 dump_ir_block_edge(n);
1170 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1173 if (node_floats(n)) {
1175 dump_ir_data_edges(n, NULL);
1176 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1180 static void dump_ir_block_graph_2 (ir_graph *irg)
1183 /* walk over the blocks in the graph */
1184 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1186 /* dump all nodes that are not in a Block */
1187 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1189 /* dump the Bad node */
1191 dump_node(get_irg_bad(irg), NULL);
1195 dump_ir_block_graph (ir_graph *irg)
1198 rem = current_ir_graph;
1199 current_ir_graph = irg;
1203 dump_ir_block_graph_2 (irg);
1205 if (dump_loop_information_flag) dump_loop_info(irg);
1208 current_ir_graph = rem;
1212 /***********************************************************************/
1213 /* the following routines dump a control flow graph */
1214 /***********************************************************************/
1218 dump_block_to_cfg (ir_node *block, void *env) {
1222 if (get_irn_opcode(block) == iro_Block) {
1223 /* This is a block. Dump a node for the block. */
1224 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1225 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1226 #ifdef DEBUG_libfirm
1227 fprintf (F, "%ld", get_irn_node_nr(block));
1229 fprintf (F, "%p", (void*) block);
1232 if (exc_normal != get_Block_exc (block))
1233 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1236 if (dump_dominator_information_flag)
1237 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1239 /* Dump the edges */
1240 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1241 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1242 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1243 fprintf (F, "edge: { sourcename: \"");
1244 PRINT_NODEID(block);
1245 fprintf (F, "\" targetname: \"");
1247 fprintf (F, "\"}\n");
1250 /* Dump dominator edge */
1251 if (dump_dominator_information_flag && get_Block_idom(block)) {
1252 pred = get_Block_idom(block);
1253 fprintf (F, "edge: { sourcename: \"");
1254 PRINT_NODEID(block);
1255 fprintf (F, "\" targetname: \"");
1257 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1263 dump_cfg (ir_graph *irg)
1265 ir_graph *rem = current_ir_graph;
1266 int ddif = dump_dominator_information_flag;
1267 current_ir_graph = irg;
1268 vcg_open (irg, "-cfg");
1270 if (get_irg_dom_state(irg) != dom_consistent)
1271 dump_dominator_information_flag = 0;
1273 /* walk over the blocks in the graph */
1274 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1275 dump_node (get_irg_bad(irg), NULL);
1277 dump_dominator_information_flag = ddif;
1279 current_ir_graph = rem;
1283 /***********************************************************************/
1284 /* the following routine dumps all type information reachable from an */
1286 /***********************************************************************/
1290 dump_type_graph (ir_graph *irg)
1293 rem = current_ir_graph;
1294 current_ir_graph = irg;
1296 vcg_open (irg, "-type");
1298 /* walk over the blocks in the graph */
1299 type_walk_irg(irg, dump_type_info, NULL, NULL);
1300 /* The walker for the const code can be called several times for the
1301 same (sub) experssion. So that no nodes are dumped several times
1302 we decrease the visited flag of the corresponding graph after each
1303 walk. So now increase it finally. */
1304 inc_irg_visited(get_const_code_irg());
1307 current_ir_graph = rem;
1310 /***********************************************************************/
1311 /* the following routine dumps all type information */
1312 /***********************************************************************/
1316 dump_all_types (void)
1318 vcg_open_name ("All_types");
1319 type_walk(dump_type_info, NULL, NULL);
1320 inc_irg_visited(get_const_code_irg());
1325 dump_class_hierarchy (bool entities)
1327 vcg_open_name ("class_hierarchy");
1329 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1331 type_walk(dump_class_hierarchy_node, NULL, NULL);
1335 /***********************************************************************/
1336 /* dumps a graph with type information */
1337 /***********************************************************************/
1341 dump_ir_graph_w_types (ir_graph *irg)
1344 rem = current_ir_graph;
1345 current_ir_graph = irg;
1347 vcg_open (irg, "-all");
1349 /* dump common ir graph */
1350 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1351 /* dump type info */
1352 type_walk_irg(irg, dump_type_info, NULL, NULL);
1353 inc_irg_visited(get_const_code_irg());
1354 /* dump edges from graph to type info */
1355 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1358 current_ir_graph = rem;
1362 dump_ir_block_graph_w_types (ir_graph *irg)
1365 rem = current_ir_graph;
1366 current_ir_graph = irg;
1368 vcg_open (irg, "-all");
1370 /* dump common blocked ir graph */
1371 dump_ir_block_graph_2(irg);
1372 /* dump type info */
1373 type_walk_irg(irg, dump_type_info, NULL, NULL);
1374 inc_irg_visited(get_const_code_irg());
1375 /* dump edges from graph to type info */
1376 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1379 current_ir_graph = rem;
1382 /***********************************************************************/
1383 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1385 /* dump_ir_block_graph */
1387 /* dump_type_graph */
1388 /* dump_ir_graph_w_types */
1389 /***********************************************************************/
1390 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1392 for (i=0; i < get_irp_n_irgs(); i++) {
1393 dump_graph(get_irp_irg(i));
1398 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1399 abort with a segmentation fault. */
1400 void turn_off_edge_labels(void) {
1405 void dump_consts_local(bool b) {
1406 dump_const_local = b;
1409 void turn_off_constant_entity_values(void) {
1413 void dump_keepalive_edges(bool b) {
1417 bool get_opt_dump_keepalive_edges(void) {
1418 return dump_keepalive;
1421 void dump_out_edges(void) {
1422 dump_out_edge_flag = 1;
1425 void dump_dominator_information(void) {
1426 dump_dominator_information_flag = 1;
1429 void dump_loop_information(void) {
1430 dump_loop_information_flag = 1;
1433 void dont_dump_loop_information(void) {
1434 dump_loop_information_flag = 0;
1437 static void clear_link(ir_node * node, void * env) {
1438 set_irn_link(node, NULL);
1442 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1443 assert(node); assert(map);
1445 || node_floats(node)
1446 || get_irn_op(node) == op_Bad
1447 || get_irn_op(node) == op_Unknown) {
1448 pmap_entry * entry = pmap_find(map, current_ir_graph);
1454 ARR_APP1(ir_node *, arr, node);
1455 entry->value = (void *)arr;
1457 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1460 pmap_insert(map, current_ir_graph, arr);
1463 ir_node * block = get_nodes_Block(node);
1464 set_irn_link(node, get_irn_link(block));
1465 set_irn_link(block, node);
1470 static void dump_cg_ir_block(ir_node * block, void * env) {
1472 pmap *irgmap = (pmap *)env;
1473 assert(is_Block(block));
1475 fprintf(F, "graph: { title: \"");
1476 PRINT_NODEID(block);
1477 fprintf(F, "\" label: \"");
1478 dump_node_opcode(block);
1479 fprintf (F, " %ld", get_irn_node_nr(block));
1481 if (exc_normal != get_Block_exc(block)) {
1482 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1485 fprintf(F, "\" status:clustered color:%s \n",
1486 get_Block_matured(block) ? "yellow" : "red");
1488 /* dump the blocks edges */
1489 dump_ir_data_edges(block, irgmap);
1491 /* dump the nodes that go into the block */
1492 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1493 dump_node(node, irgmap);
1494 dump_ir_data_edges(node, irgmap);
1497 /* Close the vcg information for the block */
1499 dump_const_node_local(block, irgmap);
1503 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1506 fprintf(F, "graph: { title: \"%p\" label: \"%s\" status:clustered color:white \n",
1507 (void*) irg, get_entity_name(get_irg_ent(irg)));
1509 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1510 ir_node * node = arr[i];
1511 if (is_Block(node)) {
1512 /* Dumps the block and all the nodes in the block, which are to
1513 be found in Block->link. */
1514 dump_cg_ir_block(node, irgmap);
1516 /* Nodes that are not in a Block. */
1517 dump_node(node, NULL);
1518 dump_ir_data_edges(node, NULL);
1521 /* Close the vcg information for the irg */
1522 fprintf(F, "}\n\n");
1525 /* dump interprocedural graph with surrounding methods */
1526 void dump_cg_block_graph(ir_graph * irg) {
1527 pmap * map = pmap_create();
1528 pmap * map2 = pmap_create();
1533 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1534 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1535 pmap_insert(map2, entry->key, entry->value);
1536 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1537 d_cg_block_graph(entry->key, entry->value, map2);
1538 DEL_ARR_F(entry->value);
1544 if (dump_loop_information_flag) dump_loop_info(irg);
1548 static void collect_node(ir_node * node, void *env) {
1550 || node_floats(node)
1551 || get_irn_op(node) == op_Bad
1552 || get_irn_op(node) == op_Unknown) {
1553 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1554 ARR_APP1(ir_node *, arr, node);
1555 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1557 ir_node * block = get_nodes_Block(node);
1558 set_irn_link(node, get_irn_link(block));
1559 set_irn_link(block, node);
1563 /* Links all nodes that have the block field set in the link field of
1564 the block. Adds all blocks and nodes not associated with a block
1565 in a array in irg->link. */
1566 static void collect_nodes(void) {
1568 for (i = 0; i < get_irp_n_irgs(); i++)
1569 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1570 cg_walk(clear_link, collect_node, NULL);
1573 static void dump_graphs(void) {
1575 for (i = 0; i < get_irp_n_irgs(); i++) {
1576 current_ir_graph = get_irp_irg(i);
1577 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1581 /* Dump all irgs in interprocedural view to a single file. */
1582 void dump_all_cg_block_graph(void) {
1584 int rem_view = interprocedural_view;
1585 interprocedural_view = 1;
1586 vcg_open_name ("All_graphs");
1591 if (dump_loop_information_flag)
1592 for (i = 0; i < get_irp_n_irgs(); i++)
1593 dump_loop_info(get_irp_irg(i));
1596 interprocedural_view = rem_view;
1599 /* dump interprocedural block graph with surrounding methods */
1600 void dump_cg_graph(ir_graph * irg) {
1601 pmap * map = pmap_create();
1602 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1606 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1607 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1608 pmap_insert(map2, entry->key, entry->value);
1609 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1610 ir_node ** arr = entry->value;
1612 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1614 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1615 get_id_str(irg_ident), get_id_str(irg_ident));
1617 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1618 ir_node * node = arr[i];
1619 dump_node(node, map2);
1620 dump_ir_data_edges(node, NULL);
1621 if (is_Block(node)) {
1622 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1623 dump_node(node, map2);
1624 dump_ir_block_edge(node);
1625 dump_ir_data_edges(node, NULL);
1632 /* Close the vcg information for the irg */
1633 fprintf(F, "}\n\n");
1642 /* Dump the information of type field specified in ana/irtypeinfo.h.
1643 * If the flag is set, the type name is output in [] in the node label,
1644 * else it is output as info.
1646 void dump_analysed_type_info(bool b) {
1647 opt_dump_analysed_type_info = b;