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 || op == op_Unknown);
359 /* outputs the predecessors of n, that are constants, local. I.e.,
360 generates a copy of the constant for each node called with. */
361 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
363 if (!get_opt_dump_const_local()) return;
364 /* Use visited flag to avoid outputting nodes twice.
365 initialize it first. */
366 for (i = 0; i < get_irn_arity(n); i++) {
367 ir_node *con = get_irn_n(n, i);
368 if (is_constlike_node(con)) {
369 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
370 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
373 for (i = 0; i < get_irn_arity(n); i++) {
374 ir_node *con = get_irn_n(n, i);
375 if (is_constlike_node(con) && irn_not_visited(con)) {
376 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
377 mark_irn_visited(con);
378 /* Generate a new name for the node by appending the names of
380 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
381 fprintf(F, " label: \"");
382 dump_node_opcode(con);
383 dump_node_mode (con);
384 dump_node_typeinfo(con);
386 dump_node_nodeattr(con);
388 fprintf (F, " %ld", get_irn_node_nr(con));
391 dump_node_vcgattr(con);
399 dump_node (ir_node *n, pmap * map) {
400 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
403 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
407 dump_node_typeinfo(n);
409 dump_node_nodeattr(n);
411 fprintf (F, " %ld", get_irn_node_nr(n));
414 dump_node_vcgattr(n);
417 dump_const_node_local(n, map);
420 /* dump the edge to the block this node belongs to */
422 dump_ir_block_edge(ir_node *n) {
423 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
424 if (is_no_Block(n)) {
425 fprintf (F, "edge: { sourcename: \"");
427 fprintf (F, "\" targetname: \"");
428 PRINT_NODEID(get_nodes_Block(n));
429 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
433 static void print_edge_vcgattr(ir_node *from, int to) {
436 if (is_backedge(from, to)) fprintf (F, BACK_EDGE_ATTR);
438 switch (get_irn_opcode(from)) {
440 fprintf (F, CF_EDGE_ATTR);
442 case iro_Start: break;
445 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
446 fprintf (F, CF_EDGE_ATTR);
447 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
448 fprintf (F, MEM_EDGE_ATTR);
451 case iro_EndReg: break;
452 case iro_EndExcept: break;
454 case iro_Break: break;
455 case iro_Cond: break;
458 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
460 case iro_Const: break;
461 case iro_SymConst:break;
464 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
466 case iro_CallBegin: break;
469 case iro_Minus: break;
475 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
483 case iro_Shrs: break;
486 case iro_Conv: break;
488 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
494 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
497 fprintf (F, MEM_EDGE_ATTR);
499 case iro_Tuple: break;
502 switch (get_irn_modecode(from)) {
504 fprintf (F, CF_EDGE_ATTR);
507 fprintf (F, MEM_EDGE_ATTR);
513 case iro_Unknown: break;
520 /* dump edges to our inputs */
522 dump_ir_data_edges(ir_node *n, pmap *irgmap) {
523 int i, visited = get_irn_visited(n);
525 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
528 for (i = 0; i < get_irn_arity(n); i++) {
529 ir_node * pred = get_irn_n(n, i);
531 if ((interprocedural_view && get_irn_visited(pred) < visited))
532 continue; /* pred not dumped */
533 if (is_backedge(n, i))
534 fprintf (F, "backedge: {sourcename: \"");
536 fprintf (F, "edge: {sourcename: \"");
538 fprintf (F, "\" targetname: ");
539 if ((get_opt_dump_const_local()) && is_constlike_node(pred) &&
540 !pred_in_wrong_graph(n, i, irgmap))
542 PRINT_CONSTID(n, pred);
545 {fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
547 fprintf (F, " label: \"%d\" ", i);
548 print_edge_vcgattr(n, i);
555 dump_out_edge (ir_node *n, void* env) {
557 for (i = 0; i < get_irn_n_outs(n); i++) {
558 assert(get_irn_out(n, i));
559 fprintf (F, "edge: {sourcename: \"");
561 fprintf (F, "\" targetname: \"");
562 PRINT_NODEID(get_irn_out(n, i));
563 fprintf (F, "\" color: red linestyle: dashed");
569 dump_loop_node_edge (ir_loop *loop, int i) {
571 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
572 PRINT_NODEID(get_loop_node(loop, i));
573 fprintf (F, "\" color: green");
578 void dump_loops (ir_loop *loop) {
580 /* dump this loop node */
581 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
582 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
583 /* dump edges to nodes in loop -- only if it is a real loop */
584 if (get_loop_depth(loop) != 0) {
585 for (i = 0; i < get_loop_n_nodes(loop); i++) {
586 dump_loop_node_edge(loop, i);
589 for (i = 0; i < get_loop_n_sons(loop); i++) {
590 dump_loops(get_loop_son(loop, i));
595 void dump_loop_info(ir_graph *irg) {
596 ir_graph *rem = current_ir_graph;
597 current_ir_graph = irg;
599 if (get_irg_loop(irg))
600 dump_loops(get_irg_loop(irg));
602 current_ir_graph = rem;
606 /* dumps the edges between nodes and their type or entity attributes. */
607 static void dump_node2type_edges (ir_node *n, void *env)
611 switch (get_irn_opcode(n)) {
613 /* @@@ some consts have an entity */
616 if ( (get_SymConst_kind(n) == type_tag)
617 || (get_SymConst_kind(n) == size))
619 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
623 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
626 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
629 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
632 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
635 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
643 static void dump_const_expression(ir_node *value) {
644 ir_graph *rem = current_ir_graph;
645 int rem_dump_const_local = dump_const_local;
646 dump_const_local = 0;
647 current_ir_graph = get_const_code_irg();
648 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
649 /* Decrease visited flag so that we walk with the same flag for the next
650 expresssion. This guarantees that we don't dump the same node twice,
651 as for const expressions cse is performed to save memory. */
652 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
653 current_ir_graph = rem;
654 dump_const_local = rem_dump_const_local;
658 static void print_type_info(type *tp) {
659 if (get_type_state(tp) == layout_undefined) {
660 fprintf(F, "state: layout_undefined\n");
662 fprintf(F, "state: layout_fixed,\n");
664 if (get_type_mode(tp))
665 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
666 fprintf(F, "size: %dB,\n", get_type_size(tp));
670 static void print_typespecific_info(type *tp) {
671 switch (get_type_tpop_code(tp)) {
674 if (peculiarity_existent == get_class_peculiarity(tp))
675 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
677 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
681 fprintf (F, " " TYPE_METH_NODE_ATTR);
692 case tpo_enumeration:
705 static void print_type_node(type *tp)
707 fprintf (F, "node: {title: ");
709 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
710 fprintf (F, " info1: \"");
713 print_typespecific_info(tp);
717 #define X(a) case a: fprintf(F, #a); break
718 void dump_entity_node(entity *ent)
720 fprintf (F, "node: {title: \"");
721 PRINT_ENTID(ent); fprintf(F, "\"");
722 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
723 fprintf (F, "label: ");
724 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
725 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
727 fprintf (F, "\nallocation: ");
728 switch (get_entity_allocation(ent)) {
729 X(allocation_dynamic);
730 X(allocation_automatic);
731 X(allocation_static);
732 X(allocation_parameter);
735 fprintf (F, "\nvisibility: ");
736 switch (get_entity_visibility(ent)) {
738 X(visibility_external_visible);
739 X(visibility_external_allocated);
742 fprintf (F, "\nvariability: ");
743 switch (get_entity_variability(ent)) {
744 X(variability_uninitialized);
745 X(variability_initialized);
746 X(variability_part_constant);
747 X(variability_constant);
750 fprintf (F, "\nvolatility: ");
751 switch (get_entity_volatility(ent)) {
752 X(volatility_non_volatile);
753 X(volatility_is_volatile);
756 fprintf (F, "\npeculiarity: ");
757 switch (get_entity_peculiarity(ent)) {
758 X(peculiarity_description);
759 X(peculiarity_inherited);
760 X(peculiarity_existent);
762 fprintf(F, "\nname: %s\nld_name: %s",
763 get_entity_name(ent), get_entity_ld_name(ent));
764 fprintf(F, "\noffset: %d", get_entity_offset(ent));
765 if (is_method_type(get_entity_type(ent))) {
766 if (get_entity_irg(ent)) /* can be null */
767 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
769 { fprintf (F, "\nirg = NULL"); }
771 fprintf(F, "\"\n}\n");
775 /* dumps a type or entity and it's edges. */
777 dump_type_info (type_or_ent *tore, void *env) {
778 int i = 0; /* to shutup gcc */
780 /* dump this type or entity */
782 switch (get_kind(tore)) {
785 entity *ent = (entity *)tore;
788 dump_entity_node(ent);
790 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
791 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
792 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
793 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
794 if(is_class_type(get_entity_owner(ent))) {
795 for(i = 0; i < get_entity_n_overwrites(ent); i++){
796 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
799 /* attached subgraphs */
800 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
801 if (is_atomic_entity(ent)) {
802 value = get_atomic_ent_value(ent);
804 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
805 /* DDMN(value); $$$ */
806 dump_const_expression(value);
809 if (is_compound_entity(ent)) {
810 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
811 value = get_compound_ent_value(ent, i);
813 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
814 dump_const_expression(value);
815 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
817 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
818 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
819 get_compound_ent_value_member(ent, i), i);
828 type *tp = (type *)tore;
830 /* and now the edges */
831 switch (get_type_tpop_code(tp)) {
834 for (i=0; i < get_class_n_supertypes(tp); i++) {
835 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
838 for (i=0; i < get_class_n_members(tp); i++) {
839 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
844 for (i=0; i < get_struct_n_members(tp); i++) {
845 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
850 for (i = 0; i < get_method_n_params(tp); i++)
852 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
854 for (i = 0; i < get_method_n_ress(tp); i++)
856 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
861 for (i = 0; i < get_union_n_members(tp); i++)
863 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
868 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
869 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
870 for (i = 0; i < get_array_n_dimensions(tp); i++) {
871 ir_node *upper = get_array_upper_bound(tp, i);
872 ir_node *lower = get_array_lower_bound(tp, i);
873 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
874 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
875 dump_const_expression(upper);
876 dump_const_expression(lower);
880 case tpo_enumeration:
885 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
893 break; /* case k_type */
896 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
898 } /* switch kind_or_entity */
901 /* dumps a class type node and a superclass edge.
902 If env != null dumps entities of classes and overwrites edges. */
904 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
905 int i = 0; /* to shutup gcc */
907 /* dump this type or entity */
908 switch (get_kind(tore)) {
910 entity *ent = (entity *)tore;
911 if (get_entity_owner(ent) == get_glob_type()) break;
912 if ((env) && is_class_type(get_entity_owner(ent))) {
914 dump_entity_node(ent);
916 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
917 for(i = 0; i < get_entity_n_overwrites(ent); i++)
919 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
922 } break; /* case k_entity */
925 type *tp = (type *)tore;
926 if (tp == get_glob_type()) break;
927 switch (get_type_tpop_code(tp)) {
930 /* and now the edges */
931 for (i=0; i < get_class_n_supertypes(tp); i++)
933 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
939 break; /* case k_type */
942 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
944 } /* switch kind_or_entity */
947 /************************************************************************/
948 /* open and close vcg file */
949 /************************************************************************/
951 static void vcg_open (ir_graph *irg, char *suffix) {
952 char *fname; /* filename to put the vcg information in */
959 /** open file for vcg graph */
960 ent = get_irg_ent(irg);
961 id = ent->ld_name ? ent->ld_name : ent->name;
962 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
963 len = get_id_strlen (id);
964 cp = get_id_str (id);
965 if (dump_file_suffix)
966 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
968 fname = malloc (len + 5 + strlen(suffix));
969 strncpy (fname, cp, len); /* copy the filename */
971 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
972 strcat (fname, suffix); /* append file suffix */
973 strcat (fname, ".vcg"); /* append the .vcg suffix */
974 F = fopen (fname, "w"); /* open file for writing */
976 panic ("cannot open %s for writing (%m)", fname); /* not reached */
980 strcpy(label, "yes");
982 strcpy (label, "no");
987 "graph: { title: \"ir graph of %s\"\n"
988 "display_edge_labels: %s\n"
989 "layoutalgorithm: mindepth\n"
990 "manhattan_edges: yes\n"
992 "orientation: bottom_to_top\n"
993 "classname 1: \"Data\"\n"
994 "classname 2: \"Block\"\n"
995 "classname 3: \"Entity type\"\n"
996 "classname 4: \"Entity owner\"\n"
997 "classname 5: \"Method Param\"\n"
998 "classname 6: \"Method Res\"\n"
999 "classname 7: \"Super\"\n"
1000 "classname 8: \"Union\"\n"
1001 "classname 9: \"Points-to\"\n"
1002 "classname 10: \"Array Element Type\"\n"
1003 "classname 11: \"Overwrites\"\n"
1004 "classname 12: \"Member\"\n"
1007 fprintf (F, "\n"); /* a separator */
1010 static void vcg_open_name (const char *name) {
1011 char *fname; /* filename to put the vcg information in */
1015 /** open file for vcg graph */
1017 fname = malloc (len + 5);
1018 if (dump_file_suffix)
1019 fname = malloc (len + 5 + strlen(dump_file_suffix));
1021 fname = malloc (len + 5);
1022 strcpy (fname, name); /* copy the filename */
1023 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1024 strcat (fname, ".vcg"); /* append the .vcg suffix */
1025 F = fopen (fname, "w"); /* open file for writing */
1027 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1031 strcpy(label, "yes");
1033 strcpy (label, "no");
1038 "graph: { title: \"ir graph of %s\"\n"
1039 "display_edge_labels: %s\n"
1040 "layoutalgorithm: mindepth\n"
1041 "manhattan_edges: yes\n"
1042 "port_sharing: no\n"
1043 "orientation: bottom_to_top\n"
1044 "classname 1: \"Data\"\n"
1045 "classname 2: \"Block\"\n"
1046 "classname 3: \"Entity type\"\n"
1047 "classname 4: \"Entity owner\"\n"
1048 "classname 5: \"Method Param\"\n"
1049 "classname 6: \"Method Res\"\n"
1050 "classname 7: \"Super\"\n"
1051 "classname 8: \"Union\"\n"
1052 "classname 9: \"Points-to\"\n"
1053 "classname 10: \"Array Element Type\"\n"
1054 "classname 11: \"Overwrites\"\n"
1055 "classname 12: \"Member\"\n"
1058 fprintf (F, "\n"); /* a separator */
1063 fprintf (F, "}\n"); /* print footer */
1064 fclose (F); /* close vcg file */
1067 /************************************************************************/
1068 /* routines to dump a graph, blocks as conventional nodes. */
1069 /************************************************************************/
1071 static int node_floats(ir_node *n) {
1072 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1073 (get_irg_pinned(current_ir_graph) == floats));
1077 dump_whole_node (ir_node *n, void* env) {
1079 if (!node_floats(n)) dump_ir_block_edge(n);
1080 dump_ir_data_edges(n, NULL);
1084 dump_ir_graph (ir_graph *irg)
1087 rem = current_ir_graph;
1088 current_ir_graph = irg;
1092 /* walk over the graph */
1093 /* dump_whole_node must be called in post visiting predecessors */
1094 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1096 /* dump the out edges in a separate walk */
1097 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1098 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1103 current_ir_graph = rem;
1106 /***********************************************************************/
1107 /* the following routines dump the nodes as attached to the blocks. */
1108 /***********************************************************************/
1111 dump_ir_blocks_nodes (ir_node *n, void *env) {
1112 ir_node *block = (ir_node *)env;
1114 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1116 dump_ir_data_edges(n, NULL);
1118 if (get_irn_op(n) == op_Bad)
1123 dump_ir_block (ir_node *block, void *env) {
1124 ir_graph *irg = (ir_graph *)env;
1126 if (get_irn_opcode(block) == iro_Block) {
1128 /* This is a block. So dump the vcg information to make a block. */
1129 fprintf(F, "graph: { title: \"");
1130 PRINT_NODEID(block);
1131 fprintf(F, "\" label: \"");
1132 #ifdef DEBUG_libfirm
1133 fprintf (F, "%ld", get_irn_node_nr(block));
1135 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1137 if (exc_normal != get_Block_exc (block))
1138 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1140 fprintf(F, "\" status:clustered color:%s \n",
1141 get_Block_matured (block) ? "yellow" : "red");
1142 /* dump the blocks edges */
1143 dump_ir_data_edges(block, NULL);
1145 /* dump the nodes that go into the block */
1146 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1148 /* Close the vcg information for the block */
1149 fprintf(F, "}\n\n");
1150 dump_const_node_local(block, NULL);
1156 dump_blockless_nodes (ir_node *n, void *env) {
1157 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1159 dump_ir_data_edges(n, NULL);
1160 dump_ir_block_edge(n);
1161 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1164 if (node_floats(n)) {
1166 dump_ir_data_edges(n, NULL);
1167 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1171 static void dump_ir_block_graph_2 (ir_graph *irg)
1174 /* walk over the blocks in the graph */
1175 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1177 /* dump all nodes that are not in a Block */
1178 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1180 /* dump the Bad node */
1182 dump_node(get_irg_bad(irg), NULL);
1186 dump_ir_block_graph (ir_graph *irg)
1189 rem = current_ir_graph;
1190 current_ir_graph = irg;
1194 dump_ir_block_graph_2 (irg);
1196 if (dump_loop_information_flag) dump_loop_info(irg);
1199 current_ir_graph = rem;
1203 /***********************************************************************/
1204 /* the following routines dump a control flow graph */
1205 /***********************************************************************/
1209 dump_block_to_cfg (ir_node *block, void *env) {
1213 if (get_irn_opcode(block) == iro_Block) {
1214 /* This is a block. Dump a node for the block. */
1215 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1216 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1217 #ifdef DEBUG_libfirm
1218 fprintf (F, "%ld", get_irn_node_nr(block));
1220 fprintf (F, "%p", (void*) block);
1223 if (exc_normal != get_Block_exc (block))
1224 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1227 if (dump_dominator_information_flag)
1228 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1230 /* Dump the edges */
1231 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1232 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1233 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1234 fprintf (F, "edge: { sourcename: \"");
1235 PRINT_NODEID(block);
1236 fprintf (F, "\" targetname: \"");
1238 fprintf (F, "\"}\n");
1241 /* Dump dominator edge */
1242 if (dump_dominator_information_flag && get_Block_idom(block)) {
1243 pred = get_Block_idom(block);
1244 fprintf (F, "edge: { sourcename: \"");
1245 PRINT_NODEID(block);
1246 fprintf (F, "\" targetname: \"");
1248 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1254 dump_cfg (ir_graph *irg)
1256 ir_graph *rem = current_ir_graph;
1257 int ddif = dump_dominator_information_flag;
1258 current_ir_graph = irg;
1259 vcg_open (irg, "-cfg");
1261 if (get_irg_dom_state(irg) != dom_consistent)
1262 dump_dominator_information_flag = 0;
1264 /* walk over the blocks in the graph */
1265 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1266 dump_node (get_irg_bad(irg), NULL);
1268 dump_dominator_information_flag = ddif;
1270 current_ir_graph = rem;
1274 /***********************************************************************/
1275 /* the following routine dumps all type information reachable from an */
1277 /***********************************************************************/
1281 dump_type_graph (ir_graph *irg)
1284 rem = current_ir_graph;
1285 current_ir_graph = irg;
1287 vcg_open (irg, "-type");
1289 /* walk over the blocks in the graph */
1290 type_walk_irg(irg, dump_type_info, NULL, NULL);
1291 /* The walker for the const code can be called several times for the
1292 same (sub) experssion. So that no nodes are dumped several times
1293 we decrease the visited flag of the corresponding graph after each
1294 walk. So now increase it finally. */
1295 inc_irg_visited(get_const_code_irg());
1298 current_ir_graph = rem;
1301 /***********************************************************************/
1302 /* the following routine dumps all type information */
1303 /***********************************************************************/
1307 dump_all_types (void)
1309 vcg_open_name ("All_types");
1310 type_walk(dump_type_info, NULL, NULL);
1311 inc_irg_visited(get_const_code_irg());
1316 dump_class_hierarchy (bool entities)
1318 vcg_open_name ("class_hierarchy");
1320 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1322 type_walk(dump_class_hierarchy_node, NULL, NULL);
1326 /***********************************************************************/
1327 /* dumps a graph with type information */
1328 /***********************************************************************/
1332 dump_ir_graph_w_types (ir_graph *irg)
1335 rem = current_ir_graph;
1336 current_ir_graph = irg;
1338 vcg_open (irg, "-all");
1340 /* dump common ir graph */
1341 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1342 /* dump type info */
1343 type_walk_irg(irg, dump_type_info, NULL, NULL);
1344 inc_irg_visited(get_const_code_irg());
1345 /* dump edges from graph to type info */
1346 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1349 current_ir_graph = rem;
1353 dump_ir_block_graph_w_types (ir_graph *irg)
1356 rem = current_ir_graph;
1357 current_ir_graph = irg;
1359 vcg_open (irg, "-all");
1361 /* dump common blocked ir graph */
1362 dump_ir_block_graph_2(irg);
1363 /* dump type info */
1364 type_walk_irg(irg, dump_type_info, NULL, NULL);
1365 inc_irg_visited(get_const_code_irg());
1366 /* dump edges from graph to type info */
1367 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1370 current_ir_graph = rem;
1373 /***********************************************************************/
1374 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1376 /* dump_ir_block_graph */
1378 /* dump_type_graph */
1379 /* dump_ir_graph_w_types */
1380 /***********************************************************************/
1381 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1383 for (i=0; i < get_irp_n_irgs(); i++) {
1384 dump_graph(get_irp_irg(i));
1389 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1390 abort with a segmentation fault. */
1391 void turn_off_edge_labels(void) {
1396 void dump_consts_local(bool b) {
1397 dump_const_local = b;
1400 void turn_off_constant_entity_values(void) {
1404 void dump_keepalive_edges(bool b) {
1408 bool get_opt_dump_keepalive_edges(void) {
1409 return dump_keepalive;
1412 void dump_out_edges(void) {
1413 dump_out_edge_flag = 1;
1416 void dump_dominator_information(void) {
1417 dump_dominator_information_flag = 1;
1420 void dump_loop_information(void) {
1421 dump_loop_information_flag = 1;
1424 void dont_dump_loop_information(void) {
1425 dump_loop_information_flag = 0;
1428 static void clear_link(ir_node * node, void * env) {
1429 set_irn_link(node, NULL);
1433 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1434 assert(node); assert(map);
1436 || node_floats(node)
1437 || get_irn_op(node) == op_Bad
1438 || get_irn_op(node) == op_Unknown) {
1439 pmap_entry * entry = pmap_find(map, current_ir_graph);
1445 ARR_APP1(ir_node *, arr, node);
1446 entry->value = (void *)arr;
1448 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1451 pmap_insert(map, current_ir_graph, arr);
1454 ir_node * block = get_nodes_Block(node);
1455 set_irn_link(node, get_irn_link(block));
1456 set_irn_link(block, node);
1461 static void dump_cg_ir_block(ir_node * block, void * env) {
1463 pmap *irgmap = (pmap *)env;
1464 assert(is_Block(block));
1466 fprintf(F, "graph: { title: \"");
1467 PRINT_NODEID(block);
1468 fprintf(F, "\" label: \"");
1469 dump_node_opcode(block);
1470 fprintf (F, " %ld", get_irn_node_nr(block));
1472 if (exc_normal != get_Block_exc(block)) {
1473 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1476 fprintf(F, "\" status:clustered color:%s \n",
1477 get_Block_matured(block) ? "yellow" : "red");
1479 /* dump the blocks edges */
1480 dump_ir_data_edges(block, irgmap);
1482 /* dump the nodes that go into the block */
1483 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1484 dump_node(node, irgmap);
1485 dump_ir_data_edges(node, irgmap);
1488 /* Close the vcg information for the block */
1490 dump_const_node_local(block, irgmap);
1494 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1497 fprintf(F, "graph: { title: \"%p\" label: \"%s\" status:clustered color:white \n",
1498 (void*) irg, get_entity_name(get_irg_ent(irg)));
1500 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1501 ir_node * node = arr[i];
1502 if (is_Block(node)) {
1503 /* Dumps the block and all the nodes in the block, which are to
1504 be found in Block->link. */
1505 dump_cg_ir_block(node, irgmap);
1507 /* Nodes that are not in a Block. */
1508 dump_node(node, NULL);
1509 dump_ir_data_edges(node, NULL);
1512 /* Close the vcg information for the irg */
1513 fprintf(F, "}\n\n");
1516 /* dump interprocedural graph with surrounding methods */
1517 void dump_cg_block_graph(ir_graph * irg) {
1518 pmap * map = pmap_create();
1519 pmap * map2 = pmap_create();
1524 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1525 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1526 pmap_insert(map2, entry->key, entry->value);
1527 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1528 d_cg_block_graph(entry->key, entry->value, map2);
1529 DEL_ARR_F(entry->value);
1535 if (dump_loop_information_flag) dump_loop_info(irg);
1539 static void collect_node(ir_node * node, void *env) {
1541 || node_floats(node)
1542 || get_irn_op(node) == op_Bad
1543 || get_irn_op(node) == op_Unknown) {
1544 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1545 ARR_APP1(ir_node *, arr, node);
1546 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1548 ir_node * block = get_nodes_Block(node);
1549 set_irn_link(node, get_irn_link(block));
1550 set_irn_link(block, node);
1554 /* Links all nodes that have the block field set in the link field of
1555 the block. Adds all blocks and nodes not associated with a block
1556 in a array in irg->link. */
1557 static void collect_nodes(void) {
1559 for (i = 0; i < get_irp_n_irgs(); i++)
1560 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1561 cg_walk(clear_link, collect_node, NULL);
1564 static void dump_graphs(void) {
1566 for (i = 0; i < get_irp_n_irgs(); i++) {
1567 current_ir_graph = get_irp_irg(i);
1568 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1572 /* Dump all irgs in interprocedural view to a single file. */
1573 void dump_all_cg_block_graph(void) {
1575 int rem_view = interprocedural_view;
1576 interprocedural_view = 1;
1577 vcg_open_name ("All_graphs");
1582 if (dump_loop_information_flag)
1583 for (i = 0; i < get_irp_n_irgs(); i++)
1584 dump_loop_info(get_irp_irg(i));
1587 interprocedural_view = rem_view;
1590 /* dump interprocedural block graph with surrounding methods */
1591 void dump_cg_graph(ir_graph * irg) {
1592 pmap * map = pmap_create();
1593 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1597 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1598 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1599 pmap_insert(map2, entry->key, entry->value);
1600 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1601 ir_node ** arr = entry->value;
1603 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1605 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1606 get_id_str(irg_ident), get_id_str(irg_ident));
1608 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1609 ir_node * node = arr[i];
1610 dump_node(node, map2);
1611 dump_ir_data_edges(node, NULL);
1612 if (is_Block(node)) {
1613 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1614 dump_node(node, map2);
1615 dump_ir_block_edge(node);
1616 dump_ir_data_edges(node, NULL);
1623 /* Close the vcg information for the irg */
1624 fprintf(F, "}\n\n");
1633 /* Dump the information of type field specified in ana/irtypeinfo.h.
1634 * If the flag is set, the type name is output in [] in the node label,
1635 * else it is output as info.
1637 void dump_analysed_type_info(bool b) {
1638 opt_dump_analysed_type_info = b;