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 type *tp = get_Const_type(n);
313 assert(tp != none_type);
314 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
319 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
320 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent )
321 if (get_irn_type(n) != none_type)
322 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
328 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
329 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
332 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
333 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
334 if (is_ip_cfop(pred)) {
335 ir_graph *irg = get_ip_cfop_irg(pred);
336 if (pmap_find(irgmap, irg) == NULL) return true;
345 bool is_constlike_node(ir_node *n) {
346 ir_op *op = get_irn_op(n);
347 return (op == op_Const || op == op_Bad || op == op_SymConst);
351 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
353 if (!get_opt_dump_const_local()) return;
354 /* Use visited flag to avoid outputting nodes twice.
355 initialize it first. */
356 for (i = 0; i < get_irn_arity(n); i++) {
357 ir_node *con = get_irn_n(n, i);
358 if (is_constlike_node(con)) {
359 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
360 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
363 for (i = 0; i < get_irn_arity(n); i++) {
364 ir_node *con = get_irn_n(n, i);
365 if (is_constlike_node(con) && irn_not_visited(con)) {
366 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
367 mark_irn_visited(con);
368 /* Generate a new name for the node by appending the names of
370 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
371 fprintf(F, " label: \"");
372 dump_node_opcode(con);
373 dump_node_mode (con);
374 dump_node_typeinfo(con);
376 dump_node_nodeattr(con);
378 fprintf (F, " %ld", get_irn_node_nr(con));
381 dump_node_vcgattr(con);
389 dump_node (ir_node *n, pmap * map) {
390 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
393 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
397 dump_node_typeinfo(n);
399 dump_node_nodeattr(n);
401 fprintf (F, " %ld", get_irn_node_nr(n));
404 dump_node_vcgattr(n);
407 dump_const_node_local(n, map);
410 /* dump the edge to the block this node belongs to */
412 dump_ir_block_edge(ir_node *n) {
413 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
414 if (is_no_Block(n)) {
415 fprintf (F, "edge: { sourcename: \"");
417 fprintf (F, "\" targetname: \"");
418 PRINT_NODEID(get_nodes_Block(n));
419 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
423 static void print_edge_vcgattr(ir_node *from, int to) {
426 if (is_backedge(from, to)) fprintf (F, BACK_EDGE_ATTR);
428 switch (get_irn_opcode(from)) {
430 fprintf (F, CF_EDGE_ATTR);
432 case iro_Start: break;
435 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
436 fprintf (F, CF_EDGE_ATTR);
437 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
438 fprintf (F, MEM_EDGE_ATTR);
441 case iro_EndReg: break;
442 case iro_EndExcept: break;
444 case iro_Break: break;
445 case iro_Cond: break;
448 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
450 case iro_Const: break;
451 case iro_SymConst:break;
454 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
456 case iro_CallBegin: break;
459 case iro_Minus: break;
465 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
473 case iro_Shrs: break;
476 case iro_Conv: break;
478 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
484 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
487 fprintf (F, MEM_EDGE_ATTR);
489 case iro_Tuple: break;
492 switch (get_irn_modecode(from)) {
494 fprintf (F, CF_EDGE_ATTR);
497 fprintf (F, MEM_EDGE_ATTR);
503 case iro_Unknown: break;
510 /* dump edges to our inputs */
512 dump_ir_data_edges(ir_node *n) {
513 int i, visited = get_irn_visited(n);
515 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
518 for (i = 0; i < get_irn_arity(n); i++) {
519 ir_node * pred = get_irn_n(n, i);
521 if ((interprocedural_view && get_irn_visited(pred) < visited))
522 continue; /* pred not dumped */
523 if (is_backedge(n, i))
524 fprintf (F, "backedge: {sourcename: \"");
526 fprintf (F, "edge: {sourcename: \"");
528 fprintf (F, "\" targetname: ");
529 if ((get_opt_dump_const_local()) && is_constlike_node(pred))
531 PRINT_CONSTID(n,pred);
534 {fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
536 fprintf (F, " label: \"%d\" ", i);
537 print_edge_vcgattr(n, i);
544 dump_out_edge (ir_node *n, void* env) {
546 for (i = 0; i < get_irn_n_outs(n); i++) {
547 assert(get_irn_out(n, i));
548 fprintf (F, "edge: {sourcename: \"");
550 fprintf (F, "\" targetname: \"");
551 PRINT_NODEID(get_irn_out(n, i));
552 fprintf (F, "\" color: red linestyle: dashed");
558 dump_loop_node_edge (ir_loop *loop, int i) {
560 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
561 PRINT_NODEID(get_loop_node(loop, i));
562 fprintf (F, "\" color: green");
567 void dump_loops (ir_loop *loop) {
569 /* dump this loop node */
570 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
571 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
572 /* dump edges to nodes in loop -- only if it is a real loop */
573 if (get_loop_depth(loop) != 0) {
574 for (i = 0; i < get_loop_n_nodes(loop); i++) {
575 dump_loop_node_edge(loop, i);
578 for (i = 0; i < get_loop_n_sons(loop); i++) {
579 dump_loops(get_loop_son(loop, i));
584 void dump_loop_info(ir_graph *irg) {
585 ir_graph *rem = current_ir_graph;
586 current_ir_graph = irg;
588 if (get_irg_loop(irg))
589 dump_loops(get_irg_loop(irg));
591 current_ir_graph = rem;
595 /* dumps the edges between nodes and their type or entity attributes. */
596 static void dump_node2type_edges (ir_node *n, void *env)
600 switch (get_irn_opcode(n)) {
602 /* @@@ some consts have an entity */
605 if ( (get_SymConst_kind(n) == type_tag)
606 || (get_SymConst_kind(n) == size))
608 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
612 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
615 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
618 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
621 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
624 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
632 static void dump_const_expression(ir_node *value) {
633 ir_graph *rem = current_ir_graph;
634 int rem_dump_const_local = dump_const_local;
635 dump_const_local = 0;
636 current_ir_graph = get_const_code_irg();
637 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
638 /* Decrease visited flag so that we walk with the same flag for the next
639 expresssion. This guarantees that we don't dump the same node twice,
640 as for const expressions cse is performed to save memory. */
641 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
642 current_ir_graph = rem;
643 dump_const_local = rem_dump_const_local;
647 static void print_type_info(type *tp) {
648 if (get_type_state(tp) == layout_undefined) {
649 fprintf(F, "state: layout_undefined\n");
651 fprintf(F, "state: layout_fixed,\n");
653 if (get_type_mode(tp))
654 fprintf(F, "mode: %s,\n", get_id_str(get_mode_ident(get_type_mode(tp))));
655 fprintf(F, "size: %dB,\n", get_type_size(tp));
659 static void print_typespecific_info(type *tp) {
660 switch (get_type_tpop_code(tp)) {
663 if (peculiarity_existent == get_class_peculiarity(tp))
664 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
666 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
670 fprintf (F, " " TYPE_METH_NODE_ATTR);
681 case tpo_enumeration:
694 static void print_type_node(type *tp)
696 fprintf (F, "node: {title: ");
698 fprintf (F, " label: \"%s %s\"", get_id_str(get_type_tpop_nameid(tp)), get_id_str(get_type_ident(tp)));
699 fprintf (F, " info1: \"");
702 print_typespecific_info(tp);
706 #define X(a) case a: fprintf(F, #a); break
707 void dump_entity_node(entity *ent)
709 fprintf (F, "node: {title: \"");
710 PRINT_ENTID(ent); fprintf(F, "\"");
711 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
712 fprintf (F, "label: ");
713 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_id_str(get_entity_ident(ent)));
714 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
716 fprintf (F, "\nallocation: ");
717 switch (get_entity_allocation(ent)) {
718 X(allocation_dynamic);
719 X(allocation_automatic);
720 X(allocation_static);
721 X(allocation_parameter);
724 fprintf (F, "\nvisibility: ");
725 switch (get_entity_visibility(ent)) {
727 X(visibility_external_visible);
728 X(visibility_external_allocated);
731 fprintf (F, "\nvariability: ");
732 switch (get_entity_variability(ent)) {
733 X(variability_uninitialized);
734 X(variability_initialized);
735 X(variability_part_constant);
736 X(variability_constant);
739 fprintf (F, "\nvolatility: ");
740 switch (get_entity_volatility(ent)) {
741 X(volatility_non_volatile);
742 X(volatility_is_volatile);
745 fprintf (F, "\npeculiarity: ");
746 switch (get_entity_peculiarity(ent)) {
747 X(peculiarity_description);
748 X(peculiarity_inherited);
749 X(peculiarity_existent);
751 fprintf(F, "\nname: %s\nld_name: %s",
752 get_id_str(get_entity_ident(ent)),
753 get_id_str(get_entity_ld_ident(ent)));
754 fprintf(F, "\noffset: %d", get_entity_offset(ent));
755 if (is_method_type(get_entity_type(ent))) {
756 if (get_entity_irg(ent)) /* can be null */
757 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
759 { fprintf (F, "\nirg = NULL"); }
761 fprintf(F, "\"\n}\n");
765 /* dumps a type or entity and it's edges. */
767 dump_type_info (type_or_ent *tore, void *env) {
768 int i = 0; /* to shutup gcc */
770 /* dump this type or entity */
772 switch (get_kind(tore)) {
775 entity *ent = (entity *)tore;
778 dump_entity_node(ent);
780 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
781 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
782 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
783 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
784 if(is_class_type(get_entity_owner(ent))) {
785 for(i = 0; i < get_entity_n_overwrites(ent); i++){
786 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
789 /* attached subgraphs */
790 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
791 if (is_atomic_entity(ent)) {
792 value = get_atomic_ent_value(ent);
794 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
795 /* DDMN(value); $$$ */
796 dump_const_expression(value);
799 if (is_compound_entity(ent)) {
800 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
801 value = get_compound_ent_value(ent, i);
803 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
804 dump_const_expression(value);
805 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
807 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
808 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
809 get_compound_ent_value_member(ent, i), i);
818 type *tp = (type *)tore;
820 /* and now the edges */
821 switch (get_type_tpop_code(tp)) {
824 for (i=0; i < get_class_n_supertypes(tp); i++) {
825 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
828 for (i=0; i < get_class_n_members(tp); i++) {
829 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
834 for (i=0; i < get_struct_n_members(tp); i++) {
835 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
840 for (i = 0; i < get_method_n_params(tp); i++)
842 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
844 for (i = 0; i < get_method_n_ress(tp); i++)
846 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
851 for (i = 0; i < get_union_n_members(tp); i++)
853 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
858 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
859 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
860 for (i = 0; i < get_array_n_dimensions(tp); i++) {
861 ir_node *upper = get_array_upper_bound(tp, i);
862 ir_node *lower = get_array_lower_bound(tp, i);
863 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
864 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
865 dump_const_expression(upper);
866 dump_const_expression(lower);
870 case tpo_enumeration:
875 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
883 break; /* case k_type */
886 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
888 } /* switch kind_or_entity */
891 /* dumps a class type node and a superclass edge.
892 If env != null dumps entities of classes and overwrites edges. */
894 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
895 int i = 0; /* to shutup gcc */
897 /* dump this type or entity */
898 switch (get_kind(tore)) {
900 entity *ent = (entity *)tore;
901 if (get_entity_owner(ent) == get_glob_type()) break;
902 if ((env) && is_class_type(get_entity_owner(ent))) {
904 dump_entity_node(ent);
906 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
907 for(i = 0; i < get_entity_n_overwrites(ent); i++)
909 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
912 } break; /* case k_entity */
915 type *tp = (type *)tore;
916 if (tp == get_glob_type()) break;
917 switch (get_type_tpop_code(tp)) {
920 /* and now the edges */
921 for (i=0; i < get_class_n_supertypes(tp); i++)
923 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
929 break; /* case k_type */
932 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
934 } /* switch kind_or_entity */
937 /************************************************************************/
938 /* open and close vcg file */
939 /************************************************************************/
941 static void vcg_open (ir_graph *irg, char *suffix) {
942 char *fname; /* filename to put the vcg information in */
949 /** open file for vcg graph */
950 ent = get_irg_ent(irg);
951 id = ent->ld_name ? ent->ld_name : ent->name;
952 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
953 len = get_id_strlen (id);
954 cp = get_id_str (id);
955 if (dump_file_suffix)
956 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
958 fname = malloc (len + 5 + strlen(suffix));
959 strncpy (fname, cp, len); /* copy the filename */
961 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
962 strcat (fname, suffix); /* append file suffix */
963 strcat (fname, ".vcg"); /* append the .vcg suffix */
964 F = fopen (fname, "w"); /* open file for writing */
966 panic ("cannot open %s for writing (%m)", fname); /* not reached */
970 strcpy(label, "yes");
972 strcpy (label, "no");
977 "graph: { title: \"ir graph of %s\"\n"
978 "display_edge_labels: %s\n"
979 "layoutalgorithm: mindepth\n"
980 "manhattan_edges: yes\n"
982 "orientation: bottom_to_top\n"
983 "classname 1: \"Data\"\n"
984 "classname 2: \"Block\"\n"
985 "classname 3: \"Entity type\"\n"
986 "classname 4: \"Entity owner\"\n"
987 "classname 5: \"Method Param\"\n"
988 "classname 6: \"Method Res\"\n"
989 "classname 7: \"Super\"\n"
990 "classname 8: \"Union\"\n"
991 "classname 9: \"Points-to\"\n"
992 "classname 10: \"Array Element Type\"\n"
993 "classname 11: \"Overwrites\"\n"
994 "classname 12: \"Member\"\n"
997 fprintf (F, "\n"); /* a separator */
1000 static void vcg_open_name (const char *name) {
1001 char *fname; /* filename to put the vcg information in */
1005 /** open file for vcg graph */
1007 fname = malloc (len + 5);
1008 if (dump_file_suffix)
1009 fname = malloc (len + 5 + strlen(dump_file_suffix));
1011 fname = malloc (len + 5);
1012 strcpy (fname, name); /* copy the filename */
1013 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1014 strcat (fname, ".vcg"); /* append the .vcg suffix */
1015 F = fopen (fname, "w"); /* open file for writing */
1017 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1021 strcpy(label, "yes");
1023 strcpy (label, "no");
1028 "graph: { title: \"ir graph of %s\"\n"
1029 "display_edge_labels: %s\n"
1030 "layoutalgorithm: mindepth\n"
1031 "manhattan_edges: yes\n"
1032 "port_sharing: no\n"
1033 "orientation: bottom_to_top\n"
1034 "classname 1: \"Data\"\n"
1035 "classname 2: \"Block\"\n"
1036 "classname 3: \"Entity type\"\n"
1037 "classname 4: \"Entity owner\"\n"
1038 "classname 5: \"Method Param\"\n"
1039 "classname 6: \"Method Res\"\n"
1040 "classname 7: \"Super\"\n"
1041 "classname 8: \"Union\"\n"
1042 "classname 9: \"Points-to\"\n"
1043 "classname 10: \"Array Element Type\"\n"
1044 "classname 11: \"Overwrites\"\n"
1045 "classname 12: \"Member\"\n"
1048 fprintf (F, "\n"); /* a separator */
1053 fprintf (F, "}\n"); /* print footer */
1054 fclose (F); /* close vcg file */
1057 /************************************************************************/
1058 /* routines to dump a graph, blocks as conventional nodes. */
1059 /************************************************************************/
1061 static int node_floats(ir_node *n) {
1062 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1063 (get_irg_pinned(current_ir_graph) == floats));
1067 dump_whole_node (ir_node *n, void* env) {
1069 if (!node_floats(n)) dump_ir_block_edge(n);
1070 dump_ir_data_edges(n);
1074 dump_ir_graph (ir_graph *irg)
1077 rem = current_ir_graph;
1078 current_ir_graph = irg;
1082 /* walk over the graph */
1083 /* dump_whole_node must be called in post visiting predecessors */
1084 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1086 /* dump the out edges in a separate walk */
1087 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1088 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1093 current_ir_graph = rem;
1096 /***********************************************************************/
1097 /* the following routines dump the nodes as attached to the blocks. */
1098 /***********************************************************************/
1101 dump_ir_blocks_nodes (ir_node *n, void *env) {
1102 ir_node *block = (ir_node *)env;
1104 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1106 dump_ir_data_edges(n);
1108 if (get_irn_op(n) == op_Bad)
1113 dump_ir_block (ir_node *block, void *env) {
1114 ir_graph *irg = (ir_graph *)env;
1116 if (get_irn_opcode(block) == iro_Block) {
1118 /* This is a block. So dump the vcg information to make a block. */
1119 fprintf(F, "graph: { title: \"");
1120 PRINT_NODEID(block);
1121 fprintf(F, "\" label: \"");
1122 #ifdef DEBUG_libfirm
1123 fprintf (F, "%ld", get_irn_node_nr(block));
1125 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1127 if (exc_normal != get_Block_exc (block))
1128 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1130 fprintf(F, "\" status:clustered color:%s \n",
1131 get_Block_matured (block) ? "yellow" : "red");
1132 /* dump the blocks edges */
1133 dump_ir_data_edges(block);
1135 /* dump the nodes that go into the block */
1136 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1138 /* Close the vcg information for the block */
1139 fprintf(F, "}\n\n");
1140 dump_const_node_local(block, NULL);
1146 dump_blockless_nodes (ir_node *n, void *env) {
1147 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1149 dump_ir_data_edges(n);
1150 dump_ir_block_edge(n);
1151 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1154 if (node_floats(n)) {
1156 dump_ir_data_edges(n);
1157 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1161 static void dump_ir_block_graph_2 (ir_graph *irg)
1164 /* walk over the blocks in the graph */
1165 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1167 /* dump all nodes that are not in a Block */
1168 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1170 /* dump the Bad node */
1172 dump_node(get_irg_bad(irg), NULL);
1176 dump_ir_block_graph (ir_graph *irg)
1179 rem = current_ir_graph;
1180 current_ir_graph = irg;
1184 dump_ir_block_graph_2 (irg);
1186 if (dump_loop_information_flag) dump_loop_info(irg);
1189 current_ir_graph = rem;
1193 /***********************************************************************/
1194 /* the following routines dump a control flow graph */
1195 /***********************************************************************/
1199 dump_block_to_cfg (ir_node *block, void *env) {
1203 if (get_irn_opcode(block) == iro_Block) {
1204 /* This is a block. Dump a node for the block. */
1205 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1206 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1207 #ifdef DEBUG_libfirm
1208 fprintf (F, "%ld", get_irn_node_nr(block));
1210 fprintf (F, "%p", (void*) block);
1213 if (exc_normal != get_Block_exc (block))
1214 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1217 if (dump_dominator_information_flag)
1218 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1220 /* Dump the edges */
1221 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1222 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1223 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1224 fprintf (F, "edge: { sourcename: \"");
1225 PRINT_NODEID(block);
1226 fprintf (F, "\" targetname: \"");
1228 fprintf (F, "\"}\n");
1231 /* Dump dominator edge */
1232 if (dump_dominator_information_flag && get_Block_idom(block)) {
1233 pred = get_Block_idom(block);
1234 fprintf (F, "edge: { sourcename: \"");
1235 PRINT_NODEID(block);
1236 fprintf (F, "\" targetname: \"");
1238 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1244 dump_cfg (ir_graph *irg)
1246 ir_graph *rem = current_ir_graph;
1247 int ddif = dump_dominator_information_flag;
1248 current_ir_graph = irg;
1249 vcg_open (irg, "-cfg");
1251 if (get_irg_dom_state(irg) != dom_consistent)
1252 dump_dominator_information_flag = 0;
1254 /* walk over the blocks in the graph */
1255 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1256 dump_node (get_irg_bad(irg), NULL);
1258 dump_dominator_information_flag = ddif;
1260 current_ir_graph = rem;
1264 /***********************************************************************/
1265 /* the following routine dumps all type information reachable from an */
1267 /***********************************************************************/
1271 dump_type_graph (ir_graph *irg)
1274 rem = current_ir_graph;
1275 current_ir_graph = irg;
1277 vcg_open (irg, "-type");
1279 /* walk over the blocks in the graph */
1280 type_walk_irg(irg, dump_type_info, NULL, NULL);
1281 /* The walker for the const code can be called several times for the
1282 same (sub) experssion. So that no nodes are dumped several times
1283 we decrease the visited flag of the corresponding graph after each
1284 walk. So now increase it finally. */
1285 inc_irg_visited(get_const_code_irg());
1288 current_ir_graph = rem;
1291 /***********************************************************************/
1292 /* the following routine dumps all type information */
1293 /***********************************************************************/
1297 dump_all_types (void)
1299 vcg_open_name ("All_types");
1300 type_walk(dump_type_info, NULL, NULL);
1301 inc_irg_visited(get_const_code_irg());
1306 dump_class_hierarchy (bool entities)
1308 vcg_open_name ("class_hierarchy");
1310 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1312 type_walk(dump_class_hierarchy_node, NULL, NULL);
1316 /***********************************************************************/
1317 /* dumps a graph with type information */
1318 /***********************************************************************/
1322 dump_ir_graph_w_types (ir_graph *irg)
1325 rem = current_ir_graph;
1326 current_ir_graph = irg;
1328 vcg_open (irg, "-all");
1330 /* dump common ir graph */
1331 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1332 /* dump type info */
1333 type_walk_irg(irg, dump_type_info, NULL, NULL);
1334 inc_irg_visited(get_const_code_irg());
1335 /* dump edges from graph to type info */
1336 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1339 current_ir_graph = rem;
1343 dump_ir_block_graph_w_types (ir_graph *irg)
1346 rem = current_ir_graph;
1347 current_ir_graph = irg;
1349 vcg_open (irg, "-all");
1351 /* dump common blocked ir graph */
1352 dump_ir_block_graph_2(irg);
1353 /* dump type info */
1354 type_walk_irg(irg, dump_type_info, NULL, NULL);
1355 inc_irg_visited(get_const_code_irg());
1356 /* dump edges from graph to type info */
1357 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1360 current_ir_graph = rem;
1363 /***********************************************************************/
1364 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1366 /* dump_ir_block_graph */
1368 /* dump_type_graph */
1369 /* dump_ir_graph_w_types */
1370 /***********************************************************************/
1371 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1373 for (i=0; i < get_irp_n_irgs(); i++) {
1374 dump_graph(get_irp_irg(i));
1379 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1380 abort with a segmentation fault. */
1381 void turn_off_edge_labels(void) {
1386 void dump_consts_local(bool b) {
1387 dump_const_local = b;
1390 void turn_off_constant_entity_values(void) {
1394 void dump_keepalive_edges(bool b) {
1398 bool get_opt_dump_keepalive_edges(void) {
1399 return dump_keepalive;
1402 void dump_out_edges(void) {
1403 dump_out_edge_flag = 1;
1406 void dump_dominator_information(void) {
1407 dump_dominator_information_flag = 1;
1410 void dump_loop_information(void) {
1411 dump_loop_information_flag = 1;
1414 void dont_dump_loop_information(void) {
1415 dump_loop_information_flag = 0;
1418 static void clear_link(ir_node * node, void * env) {
1419 set_irn_link(node, NULL);
1422 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1423 assert(node); assert(map);
1425 || node_floats(node)
1426 || get_irn_op(node) == op_Bad
1427 || get_irn_op(node) == op_Unknown) {
1428 pmap_entry * entry = pmap_find(map, current_ir_graph);
1434 ARR_APP1(ir_node *, arr, node);
1435 entry->value = (void *)arr;
1437 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1440 pmap_insert(map, current_ir_graph, arr);
1443 ir_node * block = get_nodes_Block(node);
1444 set_irn_link(node, get_irn_link(block));
1445 set_irn_link(block, node);
1450 static void dump_cg_ir_block(ir_node * block, void * env) {
1452 pmap *irgmap = (pmap *)env;
1453 assert(is_Block(block));
1454 fprintf(F, "graph: { title: \"");
1455 PRINT_NODEID(block);
1456 fprintf(F, "\" label: \"");
1457 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1458 #ifdef DEBUG_libfirm
1459 fprintf (F, "%ld", get_irn_node_nr(block));
1461 fprintf (F, "%p", (void*) block);
1463 if (exc_normal != get_Block_exc(block)) {
1464 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1467 fprintf(F, "\" status:clustered color:%s \n",
1468 get_Block_matured(block) ? "yellow" : "red");
1470 /* dump the blocks edges */
1471 dump_ir_data_edges(block);
1473 /* dump the nodes that go into the block */
1474 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1475 dump_node(node, irgmap);
1476 dump_ir_data_edges(node);
1479 /* Close the vcg information for the block */
1480 fprintf(F, "}\n\n");
1483 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1486 fprintf(F, "graph: { title: %p label: %s status:clustered color:white \n",
1487 (void*) irg, get_id_str(get_entity_ident(get_irg_ent(irg))));
1489 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1490 ir_node * node = arr[i];
1491 if (is_Block(node)) {
1492 /* Dumps the block and all the nodes in the block , which are to
1493 be found in Block->link. */
1494 dump_cg_ir_block(node, irgmap);
1496 /* Nodes that are not in a Block. */
1497 dump_node(node, NULL);
1498 dump_ir_data_edges(node);
1501 /* Close the vcg information for the irg */
1502 fprintf(F, "}\n\n");
1505 /* dump interprocedural graph with surrounding methods */
1506 void dump_cg_block_graph(ir_graph * irg) {
1507 pmap * map = pmap_create();
1508 pmap * map2 = pmap_create();
1513 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1514 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1515 pmap_insert(map2, entry->key, entry->value);
1516 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1517 d_cg_block_graph(entry->key, entry->value, map2);
1518 DEL_ARR_F(entry->value);
1524 if (dump_loop_information_flag) dump_loop_info(irg);
1528 static void collect_node(ir_node * node, void *env) {
1530 || node_floats(node)
1531 || get_irn_op(node) == op_Bad
1532 || get_irn_op(node) == op_Unknown) {
1533 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1534 ARR_APP1(ir_node *, arr, node);
1535 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1537 ir_node * block = get_nodes_Block(node);
1538 set_irn_link(node, get_irn_link(block));
1539 set_irn_link(block, node);
1543 /* Links all nodes that have the block field set in the link field of
1544 the block. Adds all blocks and nodes not associated with a block
1545 in a array in irg->link. */
1546 static void collect_nodes(void) {
1548 for (i = 0; i < get_irp_n_irgs(); i++)
1549 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1550 cg_walk(clear_link, collect_node, NULL);
1553 static void dump_graphs(void) {
1555 for (i = 0; i < get_irp_n_irgs(); i++) {
1556 current_ir_graph = get_irp_irg(i);
1557 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1561 /* Dump all irgs in interprocedural view to a single file. */
1562 void dump_all_cg_block_graph(void) {
1564 int rem_view = interprocedural_view;
1565 interprocedural_view = 1;
1566 vcg_open_name ("All_graphs");
1571 if (dump_loop_information_flag)
1572 for (i = 0; i < get_irp_n_irgs(); i++)
1573 dump_loop_info(get_irp_irg(i));
1576 interprocedural_view = rem_view;
1579 /* dump interprocedural block graph with surrounding methods */
1580 void dump_cg_graph(ir_graph * irg) {
1581 pmap * map = pmap_create();
1582 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1586 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1587 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1588 pmap_insert(map2, entry->key, entry->value);
1589 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1590 ir_node ** arr = entry->value;
1592 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1594 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1595 get_id_str(irg_ident), get_id_str(irg_ident));
1597 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1598 ir_node * node = arr[i];
1599 dump_node(node, map2);
1600 dump_ir_data_edges(node);
1601 if (is_Block(node)) {
1602 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1603 dump_node(node, map2);
1604 dump_ir_block_edge(node);
1605 dump_ir_data_edges(node);
1612 /* Close the vcg information for the irg */
1613 fprintf(F, "}\n\n");
1622 /* Dump the information of type field specified in ana/irtypeinfo.h.
1623 * If the flag is set, the type name is output in [] in the node label,
1624 * else it is output as info.
1626 void dump_analysed_type_info(bool b) {
1627 opt_dump_analysed_type_info = b;