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_type_name(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_mode_name(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_entity_name(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, "(%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_mode_name(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_type_tpop_name(tp), get_type_name(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_entity_name(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_entity_name(ent), get_entity_ld_name(ent));
761 fprintf(F, "\noffset: %d", get_entity_offset(ent));
762 if (is_method_type(get_entity_type(ent))) {
763 if (get_entity_irg(ent)) /* can be null */
764 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
766 { fprintf (F, "\nirg = NULL"); }
768 fprintf(F, "\"\n}\n");
772 /* dumps a type or entity and it's edges. */
774 dump_type_info (type_or_ent *tore, void *env) {
775 int i = 0; /* to shutup gcc */
777 /* dump this type or entity */
779 switch (get_kind(tore)) {
782 entity *ent = (entity *)tore;
785 dump_entity_node(ent);
787 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
788 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
789 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
790 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
791 if(is_class_type(get_entity_owner(ent))) {
792 for(i = 0; i < get_entity_n_overwrites(ent); i++){
793 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
796 /* attached subgraphs */
797 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
798 if (is_atomic_entity(ent)) {
799 value = get_atomic_ent_value(ent);
801 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
802 /* DDMN(value); $$$ */
803 dump_const_expression(value);
806 if (is_compound_entity(ent)) {
807 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
808 value = get_compound_ent_value(ent, i);
810 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
811 dump_const_expression(value);
812 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
814 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
815 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
816 get_compound_ent_value_member(ent, i), i);
825 type *tp = (type *)tore;
827 /* and now the edges */
828 switch (get_type_tpop_code(tp)) {
831 for (i=0; i < get_class_n_supertypes(tp); i++) {
832 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
835 for (i=0; i < get_class_n_members(tp); i++) {
836 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
841 for (i=0; i < get_struct_n_members(tp); i++) {
842 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
847 for (i = 0; i < get_method_n_params(tp); i++)
849 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
851 for (i = 0; i < get_method_n_ress(tp); i++)
853 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
858 for (i = 0; i < get_union_n_members(tp); i++)
860 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
865 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
866 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
867 for (i = 0; i < get_array_n_dimensions(tp); i++) {
868 ir_node *upper = get_array_upper_bound(tp, i);
869 ir_node *lower = get_array_lower_bound(tp, i);
870 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
871 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
872 dump_const_expression(upper);
873 dump_const_expression(lower);
877 case tpo_enumeration:
882 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
890 break; /* case k_type */
893 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
895 } /* switch kind_or_entity */
898 /* dumps a class type node and a superclass edge.
899 If env != null dumps entities of classes and overwrites edges. */
901 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
902 int i = 0; /* to shutup gcc */
904 /* dump this type or entity */
905 switch (get_kind(tore)) {
907 entity *ent = (entity *)tore;
908 if (get_entity_owner(ent) == get_glob_type()) break;
909 if ((env) && is_class_type(get_entity_owner(ent))) {
911 dump_entity_node(ent);
913 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
914 for(i = 0; i < get_entity_n_overwrites(ent); i++)
916 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
919 } break; /* case k_entity */
922 type *tp = (type *)tore;
923 if (tp == get_glob_type()) break;
924 switch (get_type_tpop_code(tp)) {
927 /* and now the edges */
928 for (i=0; i < get_class_n_supertypes(tp); i++)
930 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
936 break; /* case k_type */
939 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
941 } /* switch kind_or_entity */
944 /************************************************************************/
945 /* open and close vcg file */
946 /************************************************************************/
948 static void vcg_open (ir_graph *irg, char *suffix) {
949 char *fname; /* filename to put the vcg information in */
956 /** open file for vcg graph */
957 ent = get_irg_ent(irg);
958 id = ent->ld_name ? ent->ld_name : ent->name;
959 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
960 len = get_id_strlen (id);
961 cp = get_id_str (id);
962 if (dump_file_suffix)
963 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
965 fname = malloc (len + 5 + strlen(suffix));
966 strncpy (fname, cp, len); /* copy the filename */
968 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
969 strcat (fname, suffix); /* append file suffix */
970 strcat (fname, ".vcg"); /* append the .vcg suffix */
971 F = fopen (fname, "w"); /* open file for writing */
973 panic ("cannot open %s for writing (%m)", fname); /* not reached */
977 strcpy(label, "yes");
979 strcpy (label, "no");
984 "graph: { title: \"ir graph of %s\"\n"
985 "display_edge_labels: %s\n"
986 "layoutalgorithm: mindepth\n"
987 "manhattan_edges: yes\n"
989 "orientation: bottom_to_top\n"
990 "classname 1: \"Data\"\n"
991 "classname 2: \"Block\"\n"
992 "classname 3: \"Entity type\"\n"
993 "classname 4: \"Entity owner\"\n"
994 "classname 5: \"Method Param\"\n"
995 "classname 6: \"Method Res\"\n"
996 "classname 7: \"Super\"\n"
997 "classname 8: \"Union\"\n"
998 "classname 9: \"Points-to\"\n"
999 "classname 10: \"Array Element Type\"\n"
1000 "classname 11: \"Overwrites\"\n"
1001 "classname 12: \"Member\"\n"
1004 fprintf (F, "\n"); /* a separator */
1007 static void vcg_open_name (const char *name) {
1008 char *fname; /* filename to put the vcg information in */
1012 /** open file for vcg graph */
1014 fname = malloc (len + 5);
1015 if (dump_file_suffix)
1016 fname = malloc (len + 5 + strlen(dump_file_suffix));
1018 fname = malloc (len + 5);
1019 strcpy (fname, name); /* copy the filename */
1020 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1021 strcat (fname, ".vcg"); /* append the .vcg suffix */
1022 F = fopen (fname, "w"); /* open file for writing */
1024 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1028 strcpy(label, "yes");
1030 strcpy (label, "no");
1035 "graph: { title: \"ir graph of %s\"\n"
1036 "display_edge_labels: %s\n"
1037 "layoutalgorithm: mindepth\n"
1038 "manhattan_edges: yes\n"
1039 "port_sharing: no\n"
1040 "orientation: bottom_to_top\n"
1041 "classname 1: \"Data\"\n"
1042 "classname 2: \"Block\"\n"
1043 "classname 3: \"Entity type\"\n"
1044 "classname 4: \"Entity owner\"\n"
1045 "classname 5: \"Method Param\"\n"
1046 "classname 6: \"Method Res\"\n"
1047 "classname 7: \"Super\"\n"
1048 "classname 8: \"Union\"\n"
1049 "classname 9: \"Points-to\"\n"
1050 "classname 10: \"Array Element Type\"\n"
1051 "classname 11: \"Overwrites\"\n"
1052 "classname 12: \"Member\"\n"
1055 fprintf (F, "\n"); /* a separator */
1060 fprintf (F, "}\n"); /* print footer */
1061 fclose (F); /* close vcg file */
1064 /************************************************************************/
1065 /* routines to dump a graph, blocks as conventional nodes. */
1066 /************************************************************************/
1068 static int node_floats(ir_node *n) {
1069 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1070 (get_irg_pinned(current_ir_graph) == floats));
1074 dump_whole_node (ir_node *n, void* env) {
1076 if (!node_floats(n)) dump_ir_block_edge(n);
1077 dump_ir_data_edges(n);
1081 dump_ir_graph (ir_graph *irg)
1084 rem = current_ir_graph;
1085 current_ir_graph = irg;
1089 /* walk over the graph */
1090 /* dump_whole_node must be called in post visiting predecessors */
1091 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1093 /* dump the out edges in a separate walk */
1094 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1095 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1100 current_ir_graph = rem;
1103 /***********************************************************************/
1104 /* the following routines dump the nodes as attached to the blocks. */
1105 /***********************************************************************/
1108 dump_ir_blocks_nodes (ir_node *n, void *env) {
1109 ir_node *block = (ir_node *)env;
1111 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1113 dump_ir_data_edges(n);
1115 if (get_irn_op(n) == op_Bad)
1120 dump_ir_block (ir_node *block, void *env) {
1121 ir_graph *irg = (ir_graph *)env;
1123 if (get_irn_opcode(block) == iro_Block) {
1125 /* This is a block. So dump the vcg information to make a block. */
1126 fprintf(F, "graph: { title: \"");
1127 PRINT_NODEID(block);
1128 fprintf(F, "\" label: \"");
1129 #ifdef DEBUG_libfirm
1130 fprintf (F, "%ld", get_irn_node_nr(block));
1132 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1134 if (exc_normal != get_Block_exc (block))
1135 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1137 fprintf(F, "\" status:clustered color:%s \n",
1138 get_Block_matured (block) ? "yellow" : "red");
1139 /* dump the blocks edges */
1140 dump_ir_data_edges(block);
1142 /* dump the nodes that go into the block */
1143 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1145 /* Close the vcg information for the block */
1146 fprintf(F, "}\n\n");
1147 dump_const_node_local(block, NULL);
1153 dump_blockless_nodes (ir_node *n, void *env) {
1154 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1156 dump_ir_data_edges(n);
1157 dump_ir_block_edge(n);
1158 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1161 if (node_floats(n)) {
1163 dump_ir_data_edges(n);
1164 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1168 static void dump_ir_block_graph_2 (ir_graph *irg)
1171 /* walk over the blocks in the graph */
1172 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1174 /* dump all nodes that are not in a Block */
1175 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1177 /* dump the Bad node */
1179 dump_node(get_irg_bad(irg), NULL);
1183 dump_ir_block_graph (ir_graph *irg)
1186 rem = current_ir_graph;
1187 current_ir_graph = irg;
1191 dump_ir_block_graph_2 (irg);
1193 if (dump_loop_information_flag) dump_loop_info(irg);
1196 current_ir_graph = rem;
1200 /***********************************************************************/
1201 /* the following routines dump a control flow graph */
1202 /***********************************************************************/
1206 dump_block_to_cfg (ir_node *block, void *env) {
1210 if (get_irn_opcode(block) == iro_Block) {
1211 /* This is a block. Dump a node for the block. */
1212 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1213 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1214 #ifdef DEBUG_libfirm
1215 fprintf (F, "%ld", get_irn_node_nr(block));
1217 fprintf (F, "%p", (void*) block);
1220 if (exc_normal != get_Block_exc (block))
1221 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1224 if (dump_dominator_information_flag)
1225 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1227 /* Dump the edges */
1228 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1229 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1230 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1231 fprintf (F, "edge: { sourcename: \"");
1232 PRINT_NODEID(block);
1233 fprintf (F, "\" targetname: \"");
1235 fprintf (F, "\"}\n");
1238 /* Dump dominator edge */
1239 if (dump_dominator_information_flag && get_Block_idom(block)) {
1240 pred = get_Block_idom(block);
1241 fprintf (F, "edge: { sourcename: \"");
1242 PRINT_NODEID(block);
1243 fprintf (F, "\" targetname: \"");
1245 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1251 dump_cfg (ir_graph *irg)
1253 ir_graph *rem = current_ir_graph;
1254 int ddif = dump_dominator_information_flag;
1255 current_ir_graph = irg;
1256 vcg_open (irg, "-cfg");
1258 if (get_irg_dom_state(irg) != dom_consistent)
1259 dump_dominator_information_flag = 0;
1261 /* walk over the blocks in the graph */
1262 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1263 dump_node (get_irg_bad(irg), NULL);
1265 dump_dominator_information_flag = ddif;
1267 current_ir_graph = rem;
1271 /***********************************************************************/
1272 /* the following routine dumps all type information reachable from an */
1274 /***********************************************************************/
1278 dump_type_graph (ir_graph *irg)
1281 rem = current_ir_graph;
1282 current_ir_graph = irg;
1284 vcg_open (irg, "-type");
1286 /* walk over the blocks in the graph */
1287 type_walk_irg(irg, dump_type_info, NULL, NULL);
1288 /* The walker for the const code can be called several times for the
1289 same (sub) experssion. So that no nodes are dumped several times
1290 we decrease the visited flag of the corresponding graph after each
1291 walk. So now increase it finally. */
1292 inc_irg_visited(get_const_code_irg());
1295 current_ir_graph = rem;
1298 /***********************************************************************/
1299 /* the following routine dumps all type information */
1300 /***********************************************************************/
1304 dump_all_types (void)
1306 vcg_open_name ("All_types");
1307 type_walk(dump_type_info, NULL, NULL);
1308 inc_irg_visited(get_const_code_irg());
1313 dump_class_hierarchy (bool entities)
1315 vcg_open_name ("class_hierarchy");
1317 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1319 type_walk(dump_class_hierarchy_node, NULL, NULL);
1323 /***********************************************************************/
1324 /* dumps a graph with type information */
1325 /***********************************************************************/
1329 dump_ir_graph_w_types (ir_graph *irg)
1332 rem = current_ir_graph;
1333 current_ir_graph = irg;
1335 vcg_open (irg, "-all");
1337 /* dump common ir graph */
1338 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1339 /* dump type info */
1340 type_walk_irg(irg, dump_type_info, NULL, NULL);
1341 inc_irg_visited(get_const_code_irg());
1342 /* dump edges from graph to type info */
1343 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1346 current_ir_graph = rem;
1350 dump_ir_block_graph_w_types (ir_graph *irg)
1353 rem = current_ir_graph;
1354 current_ir_graph = irg;
1356 vcg_open (irg, "-all");
1358 /* dump common blocked ir graph */
1359 dump_ir_block_graph_2(irg);
1360 /* dump type info */
1361 type_walk_irg(irg, dump_type_info, NULL, NULL);
1362 inc_irg_visited(get_const_code_irg());
1363 /* dump edges from graph to type info */
1364 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1367 current_ir_graph = rem;
1370 /***********************************************************************/
1371 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1373 /* dump_ir_block_graph */
1375 /* dump_type_graph */
1376 /* dump_ir_graph_w_types */
1377 /***********************************************************************/
1378 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1380 for (i=0; i < get_irp_n_irgs(); i++) {
1381 dump_graph(get_irp_irg(i));
1386 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1387 abort with a segmentation fault. */
1388 void turn_off_edge_labels(void) {
1393 void dump_consts_local(bool b) {
1394 dump_const_local = b;
1397 void turn_off_constant_entity_values(void) {
1401 void dump_keepalive_edges(bool b) {
1405 bool get_opt_dump_keepalive_edges(void) {
1406 return dump_keepalive;
1409 void dump_out_edges(void) {
1410 dump_out_edge_flag = 1;
1413 void dump_dominator_information(void) {
1414 dump_dominator_information_flag = 1;
1417 void dump_loop_information(void) {
1418 dump_loop_information_flag = 1;
1421 void dont_dump_loop_information(void) {
1422 dump_loop_information_flag = 0;
1425 static void clear_link(ir_node * node, void * env) {
1426 set_irn_link(node, NULL);
1429 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1430 assert(node); assert(map);
1432 || node_floats(node)
1433 || get_irn_op(node) == op_Bad
1434 || get_irn_op(node) == op_Unknown) {
1435 pmap_entry * entry = pmap_find(map, current_ir_graph);
1441 ARR_APP1(ir_node *, arr, node);
1442 entry->value = (void *)arr;
1444 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1447 pmap_insert(map, current_ir_graph, arr);
1450 ir_node * block = get_nodes_Block(node);
1451 set_irn_link(node, get_irn_link(block));
1452 set_irn_link(block, node);
1457 static void dump_cg_ir_block(ir_node * block, void * env) {
1459 pmap *irgmap = (pmap *)env;
1460 assert(is_Block(block));
1461 fprintf(F, "graph: { title: \"");
1462 PRINT_NODEID(block);
1463 fprintf(F, "\" label: \"");
1464 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1465 #ifdef DEBUG_libfirm
1466 fprintf (F, "%ld", get_irn_node_nr(block));
1468 fprintf (F, "%p", (void*) block);
1470 if (exc_normal != get_Block_exc(block)) {
1471 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1474 fprintf(F, "\" status:clustered color:%s \n",
1475 get_Block_matured(block) ? "yellow" : "red");
1477 /* dump the blocks edges */
1478 dump_ir_data_edges(block);
1480 /* dump the nodes that go into the block */
1481 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1482 dump_node(node, irgmap);
1483 dump_ir_data_edges(node);
1486 /* Close the vcg information for the block */
1487 fprintf(F, "}\n\n");
1490 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1493 fprintf(F, "graph: { title: %p label: %s status:clustered color:white \n",
1494 (void*) irg, get_entity_name(get_irg_ent(irg)));
1496 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1497 ir_node * node = arr[i];
1498 if (is_Block(node)) {
1499 /* Dumps the block and all the nodes in the block , which are to
1500 be found in Block->link. */
1501 dump_cg_ir_block(node, irgmap);
1503 /* Nodes that are not in a Block. */
1504 dump_node(node, NULL);
1505 dump_ir_data_edges(node);
1508 /* Close the vcg information for the irg */
1509 fprintf(F, "}\n\n");
1512 /* dump interprocedural graph with surrounding methods */
1513 void dump_cg_block_graph(ir_graph * irg) {
1514 pmap * map = pmap_create();
1515 pmap * map2 = pmap_create();
1520 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1521 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1522 pmap_insert(map2, entry->key, entry->value);
1523 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1524 d_cg_block_graph(entry->key, entry->value, map2);
1525 DEL_ARR_F(entry->value);
1531 if (dump_loop_information_flag) dump_loop_info(irg);
1535 static void collect_node(ir_node * node, void *env) {
1537 || node_floats(node)
1538 || get_irn_op(node) == op_Bad
1539 || get_irn_op(node) == op_Unknown) {
1540 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1541 ARR_APP1(ir_node *, arr, node);
1542 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1544 ir_node * block = get_nodes_Block(node);
1545 set_irn_link(node, get_irn_link(block));
1546 set_irn_link(block, node);
1550 /* Links all nodes that have the block field set in the link field of
1551 the block. Adds all blocks and nodes not associated with a block
1552 in a array in irg->link. */
1553 static void collect_nodes(void) {
1555 for (i = 0; i < get_irp_n_irgs(); i++)
1556 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1557 cg_walk(clear_link, collect_node, NULL);
1560 static void dump_graphs(void) {
1562 for (i = 0; i < get_irp_n_irgs(); i++) {
1563 current_ir_graph = get_irp_irg(i);
1564 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1568 /* Dump all irgs in interprocedural view to a single file. */
1569 void dump_all_cg_block_graph(void) {
1571 int rem_view = interprocedural_view;
1572 interprocedural_view = 1;
1573 vcg_open_name ("All_graphs");
1578 if (dump_loop_information_flag)
1579 for (i = 0; i < get_irp_n_irgs(); i++)
1580 dump_loop_info(get_irp_irg(i));
1583 interprocedural_view = rem_view;
1586 /* dump interprocedural block graph with surrounding methods */
1587 void dump_cg_graph(ir_graph * irg) {
1588 pmap * map = pmap_create();
1589 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1593 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1594 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1595 pmap_insert(map2, entry->key, entry->value);
1596 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1597 ir_node ** arr = entry->value;
1599 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1601 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1602 get_id_str(irg_ident), get_id_str(irg_ident));
1604 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1605 ir_node * node = arr[i];
1606 dump_node(node, map2);
1607 dump_ir_data_edges(node);
1608 if (is_Block(node)) {
1609 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1610 dump_node(node, map2);
1611 dump_ir_block_edge(node);
1612 dump_ir_data_edges(node);
1619 /* Close the vcg information for the irg */
1620 fprintf(F, "}\n\n");
1629 /* Dump the information of type field specified in ana/irtypeinfo.h.
1630 * If the flag is set, the type name is output in [] in the node label,
1631 * else it is output as info.
1633 void dump_analysed_type_info(bool b) {
1634 opt_dump_analysed_type_info = b;