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)
150 if (get_irn_opcode(n) == iro_Const) { res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
151 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
155 } else if (get_irn_opcode(n) == iro_SymConst) {
156 if (get_SymConst_kind(n) == linkage_ptr_info) {
157 /* don't use get_SymConst_ptr_info as it mangles the name. */
158 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
160 assert(get_kind(get_SymConst_type(n)) == k_type);
161 assert(get_type_ident(get_SymConst_type(n)));
162 fprintf (F, "SymC %s ", get_id_str(get_type_ident(get_SymConst_type(n))));
163 if (get_SymConst_kind(n) == type_tag)
170 } else if (get_irn_opcode(n) == iro_Filter && !interprocedural_view) {
175 fprintf (F, "%s", get_id_str(get_irn_opident(n)));
180 dump_node_mode (ir_node *n)
182 switch (get_irn_opcode(n)) {
200 fprintf (F, "%s", get_id_str(get_mode_ident(get_irn_mode(n))));
207 static void dump_node_typeinfo(ir_node *n) {
208 if (!opt_dump_analysed_type_info) return;
209 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
210 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
211 type *tp = get_irn_type(n);
213 fprintf (F, " [%s]", get_type_name(tp));
220 dump_node_nodeattr (ir_node *n)
222 switch (get_irn_opcode(n)) {
224 if (false && interprocedural_view) {
225 fprintf (F, "%s", get_id_str(get_entity_ident(get_irg_ent(current_ir_graph))));
229 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
230 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
232 fprintf (F, "%ld", get_Proj_proj(n));
236 fprintf (F, "%ld", get_Filter_proj(n));
239 assert(get_kind(get_Sel_entity(n)) == k_entity);
240 fprintf (F, "%s", get_entity_name(get_Sel_entity(n)));
243 fprintf (F, "to %s", get_type_name(get_Cast_type(n)));
251 dump_node_vcgattr (ir_node *n)
253 switch (get_irn_opcode(n)) {
260 fprintf (F, "color: blue");
263 fprintf (F, "color: lightyellow");
266 fprintf (F, "color: green");
272 fprintf (F, "color: yellow");
275 PRINT_DEFAULT_NODE_ATTR;
280 dump_node_info (ir_node *n) {
282 fprintf (F, " info1: \"");
283 fprintf (F, "visited: %ld \n", get_irn_visited(n));
286 switch(get_irn_opcode(n)) {
288 type *tp = get_entity_type(get_irg_ent(get_Start_irg(n)));
289 fprintf(F, "start of method of type %s \n", get_type_name(tp));
290 for (i = 0; i < get_method_n_params(tp); ++i)
291 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
294 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
297 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
300 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
301 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
304 type *tp = get_Call_type(n);
305 fprintf(F, "calling method of type %s \n", get_type_name(tp));
306 for (i = 0; i < get_method_n_params(tp); ++i)
307 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
308 for (i = 0; i < get_method_n_ress(tp); ++i)
309 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
312 if (!interprocedural_view) {
313 type *tp = get_entity_type(get_irg_ent(current_ir_graph));
314 fprintf(F, "return in method of type %s \n", get_type_name(tp));
315 for (i = 0; i < get_method_n_ress(tp); ++i)
316 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
320 type *tp = get_Const_type(n);
321 assert(tp != none_type);
322 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
327 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
328 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent )
329 if (get_irn_type(n) != none_type)
330 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
336 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
337 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
340 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
341 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
342 if (is_ip_cfop(pred)) {
343 ir_graph *irg = get_ip_cfop_irg(pred);
344 if (pmap_find(irgmap, irg) == NULL) return true;
353 bool is_constlike_node(ir_node *n) {
354 ir_op *op = get_irn_op(n);
355 return (op == op_Const || op == op_Bad || op == op_SymConst);
359 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
361 if (!get_opt_dump_const_local()) return;
362 /* Use visited flag to avoid outputting nodes twice.
363 initialize it first. */
364 for (i = 0; i < get_irn_arity(n); i++) {
365 ir_node *con = get_irn_n(n, i);
366 if (is_constlike_node(con)) {
367 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
368 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
371 for (i = 0; i < get_irn_arity(n); i++) {
372 ir_node *con = get_irn_n(n, i);
373 if (is_constlike_node(con) && irn_not_visited(con)) {
374 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
375 mark_irn_visited(con);
376 /* Generate a new name for the node by appending the names of
378 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
379 fprintf(F, " label: \"");
380 dump_node_opcode(con);
381 dump_node_mode (con);
382 dump_node_typeinfo(con);
384 dump_node_nodeattr(con);
386 fprintf (F, " %ld", get_irn_node_nr(con));
389 dump_node_vcgattr(con);
397 dump_node (ir_node *n, pmap * map) {
398 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
401 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
405 dump_node_typeinfo(n);
407 dump_node_nodeattr(n);
409 fprintf (F, " %ld", get_irn_node_nr(n));
412 dump_node_vcgattr(n);
415 dump_const_node_local(n, map);
418 /* dump the edge to the block this node belongs to */
420 dump_ir_block_edge(ir_node *n) {
421 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
422 if (is_no_Block(n)) {
423 fprintf (F, "edge: { sourcename: \"");
425 fprintf (F, "\" targetname: \"");
426 PRINT_NODEID(get_nodes_Block(n));
427 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
431 static void print_edge_vcgattr(ir_node *from, int to) {
434 if (is_backedge(from, to)) fprintf (F, BACK_EDGE_ATTR);
436 switch (get_irn_opcode(from)) {
438 fprintf (F, CF_EDGE_ATTR);
440 case iro_Start: break;
443 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
444 fprintf (F, CF_EDGE_ATTR);
445 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
446 fprintf (F, MEM_EDGE_ATTR);
449 case iro_EndReg: break;
450 case iro_EndExcept: break;
452 case iro_Break: break;
453 case iro_Cond: break;
456 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
458 case iro_Const: break;
459 case iro_SymConst:break;
462 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
464 case iro_CallBegin: break;
467 case iro_Minus: break;
473 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
481 case iro_Shrs: break;
484 case iro_Conv: break;
486 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
492 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
495 fprintf (F, MEM_EDGE_ATTR);
497 case iro_Tuple: break;
500 switch (get_irn_modecode(from)) {
502 fprintf (F, CF_EDGE_ATTR);
505 fprintf (F, MEM_EDGE_ATTR);
511 case iro_Unknown: break;
518 /* dump edges to our inputs */
520 dump_ir_data_edges(ir_node *n) {
521 int i, visited = get_irn_visited(n);
523 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
526 for (i = 0; i < get_irn_arity(n); i++) {
527 ir_node * pred = get_irn_n(n, i);
529 if ((interprocedural_view && get_irn_visited(pred) < visited))
530 continue; /* pred not dumped */
531 if (is_backedge(n, i))
532 fprintf (F, "backedge: {sourcename: \"");
534 fprintf (F, "edge: {sourcename: \"");
536 fprintf (F, "\" targetname: ");
537 if ((get_opt_dump_const_local()) && is_constlike_node(pred))
539 PRINT_CONSTID(n,pred);
542 {fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
544 fprintf (F, " label: \"%d\" ", i);
545 print_edge_vcgattr(n, i);
552 dump_out_edge (ir_node *n, void* env) {
554 for (i = 0; i < get_irn_n_outs(n); i++) {
555 assert(get_irn_out(n, i));
556 fprintf (F, "edge: {sourcename: \"");
558 fprintf (F, "\" targetname: \"");
559 PRINT_NODEID(get_irn_out(n, i));
560 fprintf (F, "\" color: red linestyle: dashed");
566 dump_loop_node_edge (ir_loop *loop, int i) {
568 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
569 PRINT_NODEID(get_loop_node(loop, i));
570 fprintf (F, "\" color: green");
575 void dump_loops (ir_loop *loop) {
577 /* dump this loop node */
578 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
579 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
580 /* dump edges to nodes in loop -- only if it is a real loop */
581 if (get_loop_depth(loop) != 0) {
582 for (i = 0; i < get_loop_n_nodes(loop); i++) {
583 dump_loop_node_edge(loop, i);
586 for (i = 0; i < get_loop_n_sons(loop); i++) {
587 dump_loops(get_loop_son(loop, i));
592 void dump_loop_info(ir_graph *irg) {
593 ir_graph *rem = current_ir_graph;
594 current_ir_graph = irg;
596 if (get_irg_loop(irg))
597 dump_loops(get_irg_loop(irg));
599 current_ir_graph = rem;
603 /* dumps the edges between nodes and their type or entity attributes. */
604 static void dump_node2type_edges (ir_node *n, void *env)
608 switch (get_irn_opcode(n)) {
610 /* @@@ some consts have an entity */
613 if ( (get_SymConst_kind(n) == type_tag)
614 || (get_SymConst_kind(n) == size))
616 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
620 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
623 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
626 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
629 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
632 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
640 static void dump_const_expression(ir_node *value) {
641 ir_graph *rem = current_ir_graph;
642 int rem_dump_const_local = dump_const_local;
643 dump_const_local = 0;
644 current_ir_graph = get_const_code_irg();
645 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
646 /* Decrease visited flag so that we walk with the same flag for the next
647 expresssion. This guarantees that we don't dump the same node twice,
648 as for const expressions cse is performed to save memory. */
649 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
650 current_ir_graph = rem;
651 dump_const_local = rem_dump_const_local;
655 static void print_type_info(type *tp) {
656 if (get_type_state(tp) == layout_undefined) {
657 fprintf(F, "state: layout_undefined\n");
659 fprintf(F, "state: layout_fixed,\n");
661 if (get_type_mode(tp))
662 fprintf(F, "mode: %s,\n", get_id_str(get_mode_ident(get_type_mode(tp))));
663 fprintf(F, "size: %dB,\n", get_type_size(tp));
667 static void print_typespecific_info(type *tp) {
668 switch (get_type_tpop_code(tp)) {
671 if (peculiarity_existent == get_class_peculiarity(tp))
672 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
674 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
678 fprintf (F, " " TYPE_METH_NODE_ATTR);
689 case tpo_enumeration:
702 static void print_type_node(type *tp)
704 fprintf (F, "node: {title: ");
706 fprintf (F, " label: \"%s %s\"", get_id_str(get_type_tpop_nameid(tp)), get_id_str(get_type_ident(tp)));
707 fprintf (F, " info1: \"");
710 print_typespecific_info(tp);
714 #define X(a) case a: fprintf(F, #a); break
715 void dump_entity_node(entity *ent)
717 fprintf (F, "node: {title: \"");
718 PRINT_ENTID(ent); fprintf(F, "\"");
719 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
720 fprintf (F, "label: ");
721 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_id_str(get_entity_ident(ent)));
722 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
724 fprintf (F, "\nallocation: ");
725 switch (get_entity_allocation(ent)) {
726 X(allocation_dynamic);
727 X(allocation_automatic);
728 X(allocation_static);
729 X(allocation_parameter);
732 fprintf (F, "\nvisibility: ");
733 switch (get_entity_visibility(ent)) {
735 X(visibility_external_visible);
736 X(visibility_external_allocated);
739 fprintf (F, "\nvariability: ");
740 switch (get_entity_variability(ent)) {
741 X(variability_uninitialized);
742 X(variability_initialized);
743 X(variability_part_constant);
744 X(variability_constant);
747 fprintf (F, "\nvolatility: ");
748 switch (get_entity_volatility(ent)) {
749 X(volatility_non_volatile);
750 X(volatility_is_volatile);
753 fprintf (F, "\npeculiarity: ");
754 switch (get_entity_peculiarity(ent)) {
755 X(peculiarity_description);
756 X(peculiarity_inherited);
757 X(peculiarity_existent);
759 fprintf(F, "\nname: %s\nld_name: %s",
760 get_id_str(get_entity_ident(ent)),
761 get_id_str(get_entity_ld_ident(ent)));
762 fprintf(F, "\noffset: %d", get_entity_offset(ent));
763 if (is_method_type(get_entity_type(ent))) {
764 if (get_entity_irg(ent)) /* can be null */
765 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
767 { fprintf (F, "\nirg = NULL"); }
769 fprintf(F, "\"\n}\n");
773 /* dumps a type or entity and it's edges. */
775 dump_type_info (type_or_ent *tore, void *env) {
776 int i = 0; /* to shutup gcc */
778 /* dump this type or entity */
780 switch (get_kind(tore)) {
783 entity *ent = (entity *)tore;
786 dump_entity_node(ent);
788 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
789 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
790 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
791 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
792 if(is_class_type(get_entity_owner(ent))) {
793 for(i = 0; i < get_entity_n_overwrites(ent); i++){
794 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
797 /* attached subgraphs */
798 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
799 if (is_atomic_entity(ent)) {
800 value = get_atomic_ent_value(ent);
802 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
803 /* DDMN(value); $$$ */
804 dump_const_expression(value);
807 if (is_compound_entity(ent)) {
808 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
809 value = get_compound_ent_value(ent, i);
811 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
812 dump_const_expression(value);
813 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
815 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
816 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
817 get_compound_ent_value_member(ent, i), i);
826 type *tp = (type *)tore;
828 /* and now the edges */
829 switch (get_type_tpop_code(tp)) {
832 for (i=0; i < get_class_n_supertypes(tp); i++) {
833 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
836 for (i=0; i < get_class_n_members(tp); i++) {
837 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
842 for (i=0; i < get_struct_n_members(tp); i++) {
843 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
848 for (i = 0; i < get_method_n_params(tp); i++)
850 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
852 for (i = 0; i < get_method_n_ress(tp); i++)
854 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
859 for (i = 0; i < get_union_n_members(tp); i++)
861 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
866 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
867 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
868 for (i = 0; i < get_array_n_dimensions(tp); i++) {
869 ir_node *upper = get_array_upper_bound(tp, i);
870 ir_node *lower = get_array_lower_bound(tp, i);
871 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
872 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
873 dump_const_expression(upper);
874 dump_const_expression(lower);
878 case tpo_enumeration:
883 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
891 break; /* case k_type */
894 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
896 } /* switch kind_or_entity */
899 /* dumps a class type node and a superclass edge.
900 If env != null dumps entities of classes and overwrites edges. */
902 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
903 int i = 0; /* to shutup gcc */
905 /* dump this type or entity */
906 switch (get_kind(tore)) {
908 entity *ent = (entity *)tore;
909 if (get_entity_owner(ent) == get_glob_type()) break;
910 if ((env) && is_class_type(get_entity_owner(ent))) {
912 dump_entity_node(ent);
914 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
915 for(i = 0; i < get_entity_n_overwrites(ent); i++)
917 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
920 } break; /* case k_entity */
923 type *tp = (type *)tore;
924 if (tp == get_glob_type()) break;
925 switch (get_type_tpop_code(tp)) {
928 /* and now the edges */
929 for (i=0; i < get_class_n_supertypes(tp); i++)
931 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
937 break; /* case k_type */
940 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
942 } /* switch kind_or_entity */
945 /************************************************************************/
946 /* open and close vcg file */
947 /************************************************************************/
949 static void vcg_open (ir_graph *irg, char *suffix) {
950 char *fname; /* filename to put the vcg information in */
957 /** open file for vcg graph */
958 ent = get_irg_ent(irg);
959 id = ent->ld_name ? ent->ld_name : ent->name;
960 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
961 len = get_id_strlen (id);
962 cp = get_id_str (id);
963 if (dump_file_suffix)
964 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
966 fname = malloc (len + 5 + strlen(suffix));
967 strncpy (fname, cp, len); /* copy the filename */
969 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
970 strcat (fname, suffix); /* append file suffix */
971 strcat (fname, ".vcg"); /* append the .vcg suffix */
972 F = fopen (fname, "w"); /* open file for writing */
974 panic ("cannot open %s for writing (%m)", fname); /* not reached */
978 strcpy(label, "yes");
980 strcpy (label, "no");
985 "graph: { title: \"ir graph of %s\"\n"
986 "display_edge_labels: %s\n"
987 "layoutalgorithm: mindepth\n"
988 "manhattan_edges: yes\n"
990 "orientation: bottom_to_top\n"
991 "classname 1: \"Data\"\n"
992 "classname 2: \"Block\"\n"
993 "classname 3: \"Entity type\"\n"
994 "classname 4: \"Entity owner\"\n"
995 "classname 5: \"Method Param\"\n"
996 "classname 6: \"Method Res\"\n"
997 "classname 7: \"Super\"\n"
998 "classname 8: \"Union\"\n"
999 "classname 9: \"Points-to\"\n"
1000 "classname 10: \"Array Element Type\"\n"
1001 "classname 11: \"Overwrites\"\n"
1002 "classname 12: \"Member\"\n"
1005 fprintf (F, "\n"); /* a separator */
1008 static void vcg_open_name (const char *name) {
1009 char *fname; /* filename to put the vcg information in */
1013 /** open file for vcg graph */
1015 fname = malloc (len + 5);
1016 if (dump_file_suffix)
1017 fname = malloc (len + 5 + strlen(dump_file_suffix));
1019 fname = malloc (len + 5);
1020 strcpy (fname, name); /* copy the filename */
1021 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1022 strcat (fname, ".vcg"); /* append the .vcg suffix */
1023 F = fopen (fname, "w"); /* open file for writing */
1025 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1029 strcpy(label, "yes");
1031 strcpy (label, "no");
1036 "graph: { title: \"ir graph of %s\"\n"
1037 "display_edge_labels: %s\n"
1038 "layoutalgorithm: mindepth\n"
1039 "manhattan_edges: yes\n"
1040 "port_sharing: no\n"
1041 "orientation: bottom_to_top\n"
1042 "classname 1: \"Data\"\n"
1043 "classname 2: \"Block\"\n"
1044 "classname 3: \"Entity type\"\n"
1045 "classname 4: \"Entity owner\"\n"
1046 "classname 5: \"Method Param\"\n"
1047 "classname 6: \"Method Res\"\n"
1048 "classname 7: \"Super\"\n"
1049 "classname 8: \"Union\"\n"
1050 "classname 9: \"Points-to\"\n"
1051 "classname 10: \"Array Element Type\"\n"
1052 "classname 11: \"Overwrites\"\n"
1053 "classname 12: \"Member\"\n"
1056 fprintf (F, "\n"); /* a separator */
1061 fprintf (F, "}\n"); /* print footer */
1062 fclose (F); /* close vcg file */
1065 /************************************************************************/
1066 /* routines to dump a graph, blocks as conventional nodes. */
1067 /************************************************************************/
1069 static int node_floats(ir_node *n) {
1070 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1071 (get_irg_pinned(current_ir_graph) == floats));
1075 dump_whole_node (ir_node *n, void* env) {
1077 if (!node_floats(n)) dump_ir_block_edge(n);
1078 dump_ir_data_edges(n);
1082 dump_ir_graph (ir_graph *irg)
1085 rem = current_ir_graph;
1086 current_ir_graph = irg;
1090 /* walk over the graph */
1091 /* dump_whole_node must be called in post visiting predecessors */
1092 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1094 /* dump the out edges in a separate walk */
1095 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1096 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1101 current_ir_graph = rem;
1104 /***********************************************************************/
1105 /* the following routines dump the nodes as attached to the blocks. */
1106 /***********************************************************************/
1109 dump_ir_blocks_nodes (ir_node *n, void *env) {
1110 ir_node *block = (ir_node *)env;
1112 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1114 dump_ir_data_edges(n);
1116 if (get_irn_op(n) == op_Bad)
1121 dump_ir_block (ir_node *block, void *env) {
1122 ir_graph *irg = (ir_graph *)env;
1124 if (get_irn_opcode(block) == iro_Block) {
1126 /* This is a block. So dump the vcg information to make a block. */
1127 fprintf(F, "graph: { title: \"");
1128 PRINT_NODEID(block);
1129 fprintf(F, "\" label: \"");
1130 #ifdef DEBUG_libfirm
1131 fprintf (F, "%ld", get_irn_node_nr(block));
1133 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1135 if (exc_normal != get_Block_exc (block))
1136 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1138 fprintf(F, "\" status:clustered color:%s \n",
1139 get_Block_matured (block) ? "yellow" : "red");
1140 /* dump the blocks edges */
1141 dump_ir_data_edges(block);
1143 /* dump the nodes that go into the block */
1144 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1146 /* Close the vcg information for the block */
1147 fprintf(F, "}\n\n");
1148 dump_const_node_local(block, NULL);
1154 dump_blockless_nodes (ir_node *n, void *env) {
1155 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1157 dump_ir_data_edges(n);
1158 dump_ir_block_edge(n);
1159 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1162 if (node_floats(n)) {
1164 dump_ir_data_edges(n);
1165 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1169 static void dump_ir_block_graph_2 (ir_graph *irg)
1172 /* walk over the blocks in the graph */
1173 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1175 /* dump all nodes that are not in a Block */
1176 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1178 /* dump the Bad node */
1180 dump_node(get_irg_bad(irg), NULL);
1184 dump_ir_block_graph (ir_graph *irg)
1187 rem = current_ir_graph;
1188 current_ir_graph = irg;
1192 dump_ir_block_graph_2 (irg);
1194 if (dump_loop_information_flag) dump_loop_info(irg);
1197 current_ir_graph = rem;
1201 /***********************************************************************/
1202 /* the following routines dump a control flow graph */
1203 /***********************************************************************/
1207 dump_block_to_cfg (ir_node *block, void *env) {
1211 if (get_irn_opcode(block) == iro_Block) {
1212 /* This is a block. Dump a node for the block. */
1213 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1214 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1215 #ifdef DEBUG_libfirm
1216 fprintf (F, "%ld", get_irn_node_nr(block));
1218 fprintf (F, "%p", (void*) block);
1221 if (exc_normal != get_Block_exc (block))
1222 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1225 if (dump_dominator_information_flag)
1226 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1228 /* Dump the edges */
1229 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1230 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1231 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1232 fprintf (F, "edge: { sourcename: \"");
1233 PRINT_NODEID(block);
1234 fprintf (F, "\" targetname: \"");
1236 fprintf (F, "\"}\n");
1239 /* Dump dominator edge */
1240 if (dump_dominator_information_flag && get_Block_idom(block)) {
1241 pred = get_Block_idom(block);
1242 fprintf (F, "edge: { sourcename: \"");
1243 PRINT_NODEID(block);
1244 fprintf (F, "\" targetname: \"");
1246 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1252 dump_cfg (ir_graph *irg)
1254 ir_graph *rem = current_ir_graph;
1255 int ddif = dump_dominator_information_flag;
1256 current_ir_graph = irg;
1257 vcg_open (irg, "-cfg");
1259 if (get_irg_dom_state(irg) != dom_consistent)
1260 dump_dominator_information_flag = 0;
1262 /* walk over the blocks in the graph */
1263 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1264 dump_node (get_irg_bad(irg), NULL);
1266 dump_dominator_information_flag = ddif;
1268 current_ir_graph = rem;
1272 /***********************************************************************/
1273 /* the following routine dumps all type information reachable from an */
1275 /***********************************************************************/
1279 dump_type_graph (ir_graph *irg)
1282 rem = current_ir_graph;
1283 current_ir_graph = irg;
1285 vcg_open (irg, "-type");
1287 /* walk over the blocks in the graph */
1288 type_walk_irg(irg, dump_type_info, NULL, NULL);
1289 /* The walker for the const code can be called several times for the
1290 same (sub) experssion. So that no nodes are dumped several times
1291 we decrease the visited flag of the corresponding graph after each
1292 walk. So now increase it finally. */
1293 inc_irg_visited(get_const_code_irg());
1296 current_ir_graph = rem;
1299 /***********************************************************************/
1300 /* the following routine dumps all type information */
1301 /***********************************************************************/
1305 dump_all_types (void)
1307 vcg_open_name ("All_types");
1308 type_walk(dump_type_info, NULL, NULL);
1309 inc_irg_visited(get_const_code_irg());
1314 dump_class_hierarchy (bool entities)
1316 vcg_open_name ("class_hierarchy");
1318 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1320 type_walk(dump_class_hierarchy_node, NULL, NULL);
1324 /***********************************************************************/
1325 /* dumps a graph with type information */
1326 /***********************************************************************/
1330 dump_ir_graph_w_types (ir_graph *irg)
1333 rem = current_ir_graph;
1334 current_ir_graph = irg;
1336 vcg_open (irg, "-all");
1338 /* dump common ir graph */
1339 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1340 /* dump type info */
1341 type_walk_irg(irg, dump_type_info, NULL, NULL);
1342 inc_irg_visited(get_const_code_irg());
1343 /* dump edges from graph to type info */
1344 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1347 current_ir_graph = rem;
1351 dump_ir_block_graph_w_types (ir_graph *irg)
1354 rem = current_ir_graph;
1355 current_ir_graph = irg;
1357 vcg_open (irg, "-all");
1359 /* dump common blocked ir graph */
1360 dump_ir_block_graph_2(irg);
1361 /* dump type info */
1362 type_walk_irg(irg, dump_type_info, NULL, NULL);
1363 inc_irg_visited(get_const_code_irg());
1364 /* dump edges from graph to type info */
1365 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1368 current_ir_graph = rem;
1371 /***********************************************************************/
1372 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1374 /* dump_ir_block_graph */
1376 /* dump_type_graph */
1377 /* dump_ir_graph_w_types */
1378 /***********************************************************************/
1379 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1381 for (i=0; i < get_irp_n_irgs(); i++) {
1382 dump_graph(get_irp_irg(i));
1387 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1388 abort with a segmentation fault. */
1389 void turn_off_edge_labels(void) {
1394 void dump_consts_local(bool b) {
1395 dump_const_local = b;
1398 void turn_off_constant_entity_values(void) {
1402 void dump_keepalive_edges(bool b) {
1406 bool get_opt_dump_keepalive_edges(void) {
1407 return dump_keepalive;
1410 void dump_out_edges(void) {
1411 dump_out_edge_flag = 1;
1414 void dump_dominator_information(void) {
1415 dump_dominator_information_flag = 1;
1418 void dump_loop_information(void) {
1419 dump_loop_information_flag = 1;
1422 void dont_dump_loop_information(void) {
1423 dump_loop_information_flag = 0;
1426 static void clear_link(ir_node * node, void * env) {
1427 set_irn_link(node, NULL);
1430 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1431 assert(node); assert(map);
1433 || node_floats(node)
1434 || get_irn_op(node) == op_Bad
1435 || get_irn_op(node) == op_Unknown) {
1436 pmap_entry * entry = pmap_find(map, current_ir_graph);
1442 ARR_APP1(ir_node *, arr, node);
1443 entry->value = (void *)arr;
1445 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1448 pmap_insert(map, current_ir_graph, arr);
1451 ir_node * block = get_nodes_Block(node);
1452 set_irn_link(node, get_irn_link(block));
1453 set_irn_link(block, node);
1458 static void dump_cg_ir_block(ir_node * block, void * env) {
1460 pmap *irgmap = (pmap *)env;
1461 assert(is_Block(block));
1462 fprintf(F, "graph: { title: \"");
1463 PRINT_NODEID(block);
1464 fprintf(F, "\" label: \"");
1465 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1466 #ifdef DEBUG_libfirm
1467 fprintf (F, "%ld", get_irn_node_nr(block));
1469 fprintf (F, "%p", (void*) block);
1471 if (exc_normal != get_Block_exc(block)) {
1472 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1475 fprintf(F, "\" status:clustered color:%s \n",
1476 get_Block_matured(block) ? "yellow" : "red");
1478 /* dump the blocks edges */
1479 dump_ir_data_edges(block);
1481 /* dump the nodes that go into the block */
1482 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1483 dump_node(node, irgmap);
1484 dump_ir_data_edges(node);
1487 /* Close the vcg information for the block */
1488 fprintf(F, "}\n\n");
1491 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1494 fprintf(F, "graph: { title: %p label: %s status:clustered color:white \n",
1495 (void*) irg, get_id_str(get_entity_ident(get_irg_ent(irg))));
1497 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1498 ir_node * node = arr[i];
1499 if (is_Block(node)) {
1500 /* Dumps the block and all the nodes in the block , which are to
1501 be found in Block->link. */
1502 dump_cg_ir_block(node, irgmap);
1504 /* Nodes that are not in a Block. */
1505 dump_node(node, NULL);
1506 dump_ir_data_edges(node);
1509 /* Close the vcg information for the irg */
1510 fprintf(F, "}\n\n");
1513 /* dump interprocedural graph with surrounding methods */
1514 void dump_cg_block_graph(ir_graph * irg) {
1515 pmap * map = pmap_create();
1516 pmap * map2 = pmap_create();
1521 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1522 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1523 pmap_insert(map2, entry->key, entry->value);
1524 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1525 d_cg_block_graph(entry->key, entry->value, map2);
1526 DEL_ARR_F(entry->value);
1532 if (dump_loop_information_flag) dump_loop_info(irg);
1536 static void collect_node(ir_node * node, void *env) {
1538 || node_floats(node)
1539 || get_irn_op(node) == op_Bad
1540 || get_irn_op(node) == op_Unknown) {
1541 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1542 ARR_APP1(ir_node *, arr, node);
1543 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1545 ir_node * block = get_nodes_Block(node);
1546 set_irn_link(node, get_irn_link(block));
1547 set_irn_link(block, node);
1551 /* Links all nodes that have the block field set in the link field of
1552 the block. Adds all blocks and nodes not associated with a block
1553 in a array in irg->link. */
1554 static void collect_nodes(void) {
1556 for (i = 0; i < get_irp_n_irgs(); i++)
1557 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1558 cg_walk(clear_link, collect_node, NULL);
1561 static void dump_graphs(void) {
1563 for (i = 0; i < get_irp_n_irgs(); i++) {
1564 current_ir_graph = get_irp_irg(i);
1565 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1569 /* Dump all irgs in interprocedural view to a single file. */
1570 void dump_all_cg_block_graph(void) {
1572 int rem_view = interprocedural_view;
1573 interprocedural_view = 1;
1574 vcg_open_name ("All_graphs");
1579 if (dump_loop_information_flag)
1580 for (i = 0; i < get_irp_n_irgs(); i++)
1581 dump_loop_info(get_irp_irg(i));
1584 interprocedural_view = rem_view;
1587 /* dump interprocedural block graph with surrounding methods */
1588 void dump_cg_graph(ir_graph * irg) {
1589 pmap * map = pmap_create();
1590 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1594 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1595 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1596 pmap_insert(map2, entry->key, entry->value);
1597 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1598 ir_node ** arr = entry->value;
1600 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1602 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1603 get_id_str(irg_ident), get_id_str(irg_ident));
1605 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1606 ir_node * node = arr[i];
1607 dump_node(node, map2);
1608 dump_ir_data_edges(node);
1609 if (is_Block(node)) {
1610 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1611 dump_node(node, map2);
1612 dump_ir_block_edge(node);
1613 dump_ir_data_edges(node);
1620 /* Close the vcg information for the irg */
1621 fprintf(F, "}\n\n");
1630 /* Dump the information of type field specified in ana/irtypeinfo.h.
1631 * If the flag is set, the type name is output in [] in the node label,
1632 * else it is output as info.
1634 void dump_analysed_type_info(bool b) {
1635 opt_dump_analysed_type_info = b;