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_backedge_information_flag = 1;
122 int dump_const_local = 0;
123 bool opt_dump_analysed_type_info = 1;
125 INLINE bool get_opt_dump_const_local(void) {
126 if (!dump_out_edge_flag && !dump_loop_information_flag)
127 return dump_const_local;
132 /* A global variable to record output of the Bad node. */
133 static int Bad_dumped;
135 static void dump_ir_blocks_nodes (ir_node *n, void *env);
136 static void dump_whole_node(ir_node *n, void* env);
138 /*******************************************************************/
139 /* routines to dump information about a single node */
140 /*******************************************************************/
145 dump_node_opcode (ir_node *n)
150 switch(get_irn_opcode(n)) {
153 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
154 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
159 if (get_SymConst_kind(n) == linkage_ptr_info) {
160 /* don't use get_SymConst_ptr_info as it mangles the name. */
161 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
163 assert(get_kind(get_SymConst_type(n)) == k_type);
164 assert(get_type_ident(get_SymConst_type(n)));
165 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
166 if (get_SymConst_kind(n) == type_tag)
174 if (!interprocedural_view) fprintf(F, "Proj'");
178 fprintf (F, "%s", get_id_str(get_irn_opident(n)));
185 dump_node_mode (ir_node *n)
187 switch (get_irn_opcode(n)) {
206 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
213 static void dump_node_typeinfo(ir_node *n) {
214 if (!opt_dump_analysed_type_info) return;
215 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
216 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
217 type *tp = get_irn_type(n);
219 fprintf (F, " [%s]", get_type_name(tp));
226 dump_node_nodeattr (ir_node *n)
228 switch (get_irn_opcode(n)) {
230 if (false && interprocedural_view) {
231 fprintf (F, "%s", get_entity_name(get_irg_ent(current_ir_graph)));
235 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
236 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
238 fprintf (F, "%ld", get_Proj_proj(n));
242 fprintf (F, "%ld", get_Filter_proj(n));
245 assert(get_kind(get_Sel_entity(n)) == k_entity);
246 fprintf (F, "%s", get_entity_name(get_Sel_entity(n)));
249 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
252 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
261 dump_node_vcgattr (ir_node *n)
263 switch (get_irn_opcode(n)) {
270 fprintf (F, "color: blue");
273 fprintf (F, "color: lightyellow");
276 fprintf (F, "color: green");
282 fprintf (F, "color: yellow");
285 PRINT_DEFAULT_NODE_ATTR;
290 dump_node_info (ir_node *n) {
292 fprintf (F, " info1: \"");
293 fprintf (F, "visited: %ld \n", get_irn_visited(n));
296 switch(get_irn_opcode(n)) {
298 type *tp = get_entity_type(get_irg_ent(get_Start_irg(n)));
299 fprintf(F, "start of method of type %s \n", get_type_name(tp));
300 for (i = 0; i < get_method_n_params(tp); ++i)
301 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
304 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
307 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
310 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
311 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
314 type *tp = get_Call_type(n);
315 fprintf(F, "calling method of type %s \n", get_type_name(tp));
316 for (i = 0; i < get_method_n_params(tp); ++i)
317 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
318 for (i = 0; i < get_method_n_ress(tp); ++i)
319 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
322 if (!interprocedural_view) {
323 type *tp = get_entity_type(get_irg_ent(current_ir_graph));
324 fprintf(F, "return in method of type %s \n", get_type_name(tp));
325 for (i = 0; i < get_method_n_ress(tp); ++i)
326 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
330 type *tp = get_Const_type(n);
331 assert(tp != none_type);
332 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
337 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
338 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent )
339 if (get_irn_type(n) != none_type)
340 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
346 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
347 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
350 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
351 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
352 if (is_ip_cfop(pred)) {
353 ir_graph *irg = get_ip_cfop_irg(pred);
354 if (pmap_find(irgmap, irg) == NULL) return true;
363 bool is_constlike_node(ir_node *n) {
364 ir_op *op = get_irn_op(n);
365 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
369 /* outputs the predecessors of n, that are constants, local. I.e.,
370 generates a copy of the constant for each node called with. */
371 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
373 if (!get_opt_dump_const_local()) return;
374 /* Use visited flag to avoid outputting nodes twice.
375 initialize it first. */
376 for (i = 0; i < get_irn_arity(n); i++) {
377 ir_node *con = get_irn_n(n, i);
378 if (is_constlike_node(con)) {
379 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
380 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
383 for (i = 0; i < get_irn_arity(n); i++) {
384 ir_node *con = get_irn_n(n, i);
385 if (is_constlike_node(con) && irn_not_visited(con)) {
386 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
387 mark_irn_visited(con);
388 /* Generate a new name for the node by appending the names of
390 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
391 fprintf(F, " label: \"");
392 dump_node_opcode(con);
393 dump_node_mode (con);
394 dump_node_typeinfo(con);
396 dump_node_nodeattr(con);
398 fprintf (F, " %ld", get_irn_node_nr(con));
401 dump_node_vcgattr(con);
409 dump_node (ir_node *n, pmap * map) {
410 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
413 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
417 dump_node_typeinfo(n);
419 dump_node_nodeattr(n);
421 fprintf (F, " %ld", get_irn_node_nr(n));
424 dump_node_vcgattr(n);
427 dump_const_node_local(n, map);
430 /* dump the edge to the block this node belongs to */
432 dump_ir_block_edge(ir_node *n) {
433 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
434 if (is_no_Block(n)) {
435 fprintf (F, "edge: { sourcename: \"");
437 fprintf (F, "\" targetname: \"");
438 PRINT_NODEID(get_nodes_Block(n));
439 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
443 static void print_edge_vcgattr(ir_node *from, int to) {
446 if (dump_backedge_information_flag && is_backedge(from, to))
447 fprintf (F, BACK_EDGE_ATTR);
449 switch (get_irn_opcode(from)) {
451 fprintf (F, CF_EDGE_ATTR);
453 case iro_Start: break;
456 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
457 fprintf (F, CF_EDGE_ATTR);
458 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
459 fprintf (F, MEM_EDGE_ATTR);
462 case iro_EndReg: break;
463 case iro_EndExcept: break;
465 case iro_Break: break;
466 case iro_Cond: break;
469 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
471 case iro_Const: break;
472 case iro_SymConst:break;
475 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
477 case iro_CallBegin: break;
480 case iro_Minus: break;
486 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
494 case iro_Shrs: break;
497 case iro_Conv: break;
499 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
505 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
508 fprintf (F, MEM_EDGE_ATTR);
510 case iro_Tuple: break;
513 switch (get_irn_modecode(from)) {
515 fprintf (F, CF_EDGE_ATTR);
518 fprintf (F, MEM_EDGE_ATTR);
524 case iro_Unknown: break;
531 /* dump edges to our inputs */
533 dump_ir_data_edges(ir_node *n, pmap *irgmap) {
534 int i, visited = get_irn_visited(n);
536 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
539 for (i = 0; i < get_irn_arity(n); i++) {
540 ir_node * pred = get_irn_n(n, i);
542 if ((interprocedural_view && get_irn_visited(pred) < visited))
543 continue; /* pred not dumped */
544 if (dump_backedge_information_flag && is_backedge(n, i))
545 fprintf (F, "backedge: {sourcename: \"");
547 fprintf (F, "edge: {sourcename: \"");
549 fprintf (F, "\" targetname: ");
550 if ((get_opt_dump_const_local()) && is_constlike_node(pred) &&
551 !pred_in_wrong_graph(n, i, irgmap)) {
552 PRINT_CONSTID(n, pred);
554 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
556 fprintf (F, " label: \"%d\" ", i);
557 print_edge_vcgattr(n, i);
564 dump_out_edge (ir_node *n, void* env) {
566 for (i = 0; i < get_irn_n_outs(n); i++) {
567 assert(get_irn_out(n, i));
568 fprintf (F, "edge: {sourcename: \"");
570 fprintf (F, "\" targetname: \"");
571 PRINT_NODEID(get_irn_out(n, i));
572 fprintf (F, "\" color: red linestyle: dashed");
578 dump_loop_node_edge (ir_loop *loop, int i) {
580 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
581 PRINT_NODEID(get_loop_node(loop, i));
582 fprintf (F, "\" color: green");
587 dump_loop_son_edge (ir_loop *loop, int i) {
589 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\" color: darkgreen}\n",
590 (void *)loop, (void *)get_loop_son(loop, i));
594 void dump_loops (ir_loop *loop) {
596 /* dump this loop node */
597 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
598 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
599 /* dump edges to nodes in loop -- only if it is a real loop */
600 if (get_loop_depth(loop) != 0) {
601 for (i = 0; i < get_loop_n_nodes(loop); i++) {
602 dump_loop_node_edge(loop, i);
605 for (i = 0; i < get_loop_n_sons(loop); i++) {
606 dump_loops(get_loop_son(loop, i));
607 dump_loop_son_edge(loop, i);
612 void dump_loop_info(ir_graph *irg) {
613 ir_graph *rem = current_ir_graph;
614 current_ir_graph = irg;
616 if (get_irg_loop(irg))
617 dump_loops(get_irg_loop(irg));
619 current_ir_graph = rem;
623 /* dumps the edges between nodes and their type or entity attributes. */
624 static void dump_node2type_edges (ir_node *n, void *env)
628 switch (get_irn_opcode(n)) {
630 /* @@@ some consts have an entity */
633 if ( (get_SymConst_kind(n) == type_tag)
634 || (get_SymConst_kind(n) == size))
636 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
640 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
643 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
646 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
649 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
652 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
660 static void dump_const_expression(ir_node *value) {
661 ir_graph *rem = current_ir_graph;
662 int rem_dump_const_local = dump_const_local;
663 dump_const_local = 0;
664 current_ir_graph = get_const_code_irg();
665 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
666 /* Decrease visited flag so that we walk with the same flag for the next
667 expresssion. This guarantees that we don't dump the same node twice,
668 as for const expressions cse is performed to save memory. */
669 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
670 current_ir_graph = rem;
671 dump_const_local = rem_dump_const_local;
675 static void print_type_info(type *tp) {
676 if (get_type_state(tp) == layout_undefined) {
677 fprintf(F, "state: layout_undefined\n");
679 fprintf(F, "state: layout_fixed,\n");
681 if (get_type_mode(tp))
682 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
683 fprintf(F, "size: %dB,\n", get_type_size(tp));
687 static void print_typespecific_info(type *tp) {
688 switch (get_type_tpop_code(tp)) {
691 if (peculiarity_existent == get_class_peculiarity(tp))
692 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
694 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
698 fprintf (F, " " TYPE_METH_NODE_ATTR);
709 case tpo_enumeration:
722 static void print_type_node(type *tp)
724 fprintf (F, "node: {title: ");
726 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
727 fprintf (F, " info1: \"");
730 print_typespecific_info(tp);
734 #define X(a) case a: fprintf(F, #a); break
735 void dump_entity_node(entity *ent)
737 fprintf (F, "node: {title: \"");
738 PRINT_ENTID(ent); fprintf(F, "\"");
739 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
740 fprintf (F, "label: ");
741 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
742 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
744 fprintf (F, "\nallocation: ");
745 switch (get_entity_allocation(ent)) {
746 X(allocation_dynamic);
747 X(allocation_automatic);
748 X(allocation_static);
749 X(allocation_parameter);
752 fprintf (F, "\nvisibility: ");
753 switch (get_entity_visibility(ent)) {
755 X(visibility_external_visible);
756 X(visibility_external_allocated);
759 fprintf (F, "\nvariability: ");
760 switch (get_entity_variability(ent)) {
761 X(variability_uninitialized);
762 X(variability_initialized);
763 X(variability_part_constant);
764 X(variability_constant);
767 fprintf (F, "\nvolatility: ");
768 switch (get_entity_volatility(ent)) {
769 X(volatility_non_volatile);
770 X(volatility_is_volatile);
773 fprintf (F, "\npeculiarity: ");
774 switch (get_entity_peculiarity(ent)) {
775 X(peculiarity_description);
776 X(peculiarity_inherited);
777 X(peculiarity_existent);
779 fprintf(F, "\nname: %s\nld_name: %s",
780 get_entity_name(ent), get_entity_ld_name(ent));
781 fprintf(F, "\noffset: %d", get_entity_offset(ent));
782 if (is_method_type(get_entity_type(ent))) {
783 if (get_entity_irg(ent)) /* can be null */
784 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
786 { fprintf (F, "\nirg = NULL"); }
788 fprintf(F, "\"\n}\n");
792 /* dumps a type or entity and it's edges. */
794 dump_type_info (type_or_ent *tore, void *env) {
795 int i = 0; /* to shutup gcc */
797 /* dump this type or entity */
799 switch (get_kind(tore)) {
802 entity *ent = (entity *)tore;
805 dump_entity_node(ent);
807 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
808 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
809 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
810 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
811 if(is_class_type(get_entity_owner(ent))) {
812 for(i = 0; i < get_entity_n_overwrites(ent); i++){
813 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
816 /* attached subgraphs */
817 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
818 if (is_atomic_entity(ent)) {
819 value = get_atomic_ent_value(ent);
821 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
822 /* DDMN(value); $$$ */
823 dump_const_expression(value);
826 if (is_compound_entity(ent)) {
827 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
828 value = get_compound_ent_value(ent, i);
830 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
831 dump_const_expression(value);
832 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
834 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
835 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
836 get_compound_ent_value_member(ent, i), i);
845 type *tp = (type *)tore;
847 /* and now the edges */
848 switch (get_type_tpop_code(tp)) {
851 for (i=0; i < get_class_n_supertypes(tp); i++) {
852 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
855 for (i=0; i < get_class_n_members(tp); i++) {
856 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
861 for (i=0; i < get_struct_n_members(tp); i++) {
862 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
867 for (i = 0; i < get_method_n_params(tp); i++)
869 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
871 for (i = 0; i < get_method_n_ress(tp); i++)
873 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
878 for (i = 0; i < get_union_n_members(tp); i++)
880 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
885 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
886 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
887 for (i = 0; i < get_array_n_dimensions(tp); i++) {
888 ir_node *upper = get_array_upper_bound(tp, i);
889 ir_node *lower = get_array_lower_bound(tp, i);
890 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
891 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
892 dump_const_expression(upper);
893 dump_const_expression(lower);
897 case tpo_enumeration:
902 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
910 break; /* case k_type */
913 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
915 } /* switch kind_or_entity */
918 /* dumps a class type node and a superclass edge.
919 If env != null dumps entities of classes and overwrites edges. */
921 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
922 int i = 0; /* to shutup gcc */
924 /* dump this type or entity */
925 switch (get_kind(tore)) {
927 entity *ent = (entity *)tore;
928 if (get_entity_owner(ent) == get_glob_type()) break;
929 if ((env) && is_class_type(get_entity_owner(ent))) {
931 dump_entity_node(ent);
933 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
934 for(i = 0; i < get_entity_n_overwrites(ent); i++)
936 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
939 } break; /* case k_entity */
942 type *tp = (type *)tore;
943 if (tp == get_glob_type()) break;
944 switch (get_type_tpop_code(tp)) {
947 /* and now the edges */
948 for (i=0; i < get_class_n_supertypes(tp); i++)
950 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
956 break; /* case k_type */
959 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
961 } /* switch kind_or_entity */
964 /************************************************************************/
965 /* open and close vcg file */
966 /************************************************************************/
968 static void vcg_open (ir_graph *irg, char *suffix) {
969 char *fname; /* filename to put the vcg information in */
976 /** open file for vcg graph */
977 ent = get_irg_ent(irg);
978 id = ent->ld_name ? ent->ld_name : ent->name;
979 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
980 len = get_id_strlen (id);
981 cp = get_id_str (id);
982 if (dump_file_suffix)
983 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
985 fname = malloc (len + 5 + strlen(suffix));
986 strncpy (fname, cp, len); /* copy the filename */
988 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
989 strcat (fname, suffix); /* append file suffix */
990 strcat (fname, ".vcg"); /* append the .vcg suffix */
991 F = fopen (fname, "w"); /* open file for writing */
993 panic ("cannot open %s for writing (%m)", fname); /* not reached */
997 strcpy(label, "yes");
999 strcpy (label, "no");
1004 "graph: { title: \"ir graph of %s\"\n"
1005 "display_edge_labels: %s\n"
1006 "layoutalgorithm: mindepth\n"
1007 "manhattan_edges: yes\n"
1008 "port_sharing: no\n"
1009 "orientation: bottom_to_top\n"
1010 "classname 1: \"Data\"\n"
1011 "classname 2: \"Block\"\n"
1012 "classname 3: \"Entity type\"\n"
1013 "classname 4: \"Entity owner\"\n"
1014 "classname 5: \"Method Param\"\n"
1015 "classname 6: \"Method Res\"\n"
1016 "classname 7: \"Super\"\n"
1017 "classname 8: \"Union\"\n"
1018 "classname 9: \"Points-to\"\n"
1019 "classname 10: \"Array Element Type\"\n"
1020 "classname 11: \"Overwrites\"\n"
1021 "classname 12: \"Member\"\n"
1024 fprintf (F, "\n"); /* a separator */
1027 static void vcg_open_name (const char *name) {
1028 char *fname; /* filename to put the vcg information in */
1032 /** open file for vcg graph */
1034 fname = malloc (len + 5);
1035 if (dump_file_suffix)
1036 fname = malloc (len + 5 + strlen(dump_file_suffix));
1038 fname = malloc (len + 5);
1039 strcpy (fname, name); /* copy the filename */
1040 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1041 strcat (fname, ".vcg"); /* append the .vcg suffix */
1042 F = fopen (fname, "w"); /* open file for writing */
1044 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1048 strcpy(label, "yes");
1050 strcpy (label, "no");
1055 "graph: { title: \"ir graph of %s\"\n"
1056 "display_edge_labels: %s\n"
1057 "layoutalgorithm: mindepth\n"
1058 "manhattan_edges: yes\n"
1059 "port_sharing: no\n"
1060 "orientation: bottom_to_top\n"
1061 "classname 1: \"Data\"\n"
1062 "classname 2: \"Block\"\n"
1063 "classname 3: \"Entity type\"\n"
1064 "classname 4: \"Entity owner\"\n"
1065 "classname 5: \"Method Param\"\n"
1066 "classname 6: \"Method Res\"\n"
1067 "classname 7: \"Super\"\n"
1068 "classname 8: \"Union\"\n"
1069 "classname 9: \"Points-to\"\n"
1070 "classname 10: \"Array Element Type\"\n"
1071 "classname 11: \"Overwrites\"\n"
1072 "classname 12: \"Member\"\n"
1075 fprintf (F, "\n"); /* a separator */
1080 fprintf (F, "}\n"); /* print footer */
1081 fclose (F); /* close vcg file */
1084 /************************************************************************/
1085 /* routines to dump a graph, blocks as conventional nodes. */
1086 /************************************************************************/
1088 static int node_floats(ir_node *n) {
1089 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1090 (get_irg_pinned(current_ir_graph) == floats));
1094 dump_whole_node (ir_node *n, void* env) {
1096 if (!node_floats(n)) dump_ir_block_edge(n);
1097 dump_ir_data_edges(n, NULL);
1101 dump_ir_graph (ir_graph *irg)
1104 rem = current_ir_graph;
1105 current_ir_graph = irg;
1109 /* walk over the graph */
1110 /* dump_whole_node must be called in post visiting predecessors */
1111 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1113 /* dump the out edges in a separate walk */
1114 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1115 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1120 current_ir_graph = rem;
1123 /***********************************************************************/
1124 /* the following routines dump the nodes as attached to the blocks. */
1125 /***********************************************************************/
1128 dump_ir_blocks_nodes (ir_node *n, void *env) {
1129 ir_node *block = (ir_node *)env;
1131 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1133 dump_ir_data_edges(n, NULL);
1135 if (get_irn_op(n) == op_Bad)
1140 dump_ir_block (ir_node *block, void *env) {
1141 ir_graph *irg = (ir_graph *)env;
1143 if (get_irn_opcode(block) == iro_Block) {
1145 /* This is a block. So dump the vcg information to make a block. */
1146 fprintf(F, "graph: { title: \"");
1147 PRINT_NODEID(block);
1148 fprintf(F, "\" label: \"");
1149 #ifdef DEBUG_libfirm
1150 fprintf (F, "%ld", get_irn_node_nr(block));
1152 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1154 // if (exc_normal != get_Block_exc (block))
1155 // fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1157 fprintf(F, "\" status:clustered color:%s \n",
1158 get_Block_matured (block) ? "yellow" : "red");
1159 /* dump the blocks edges */
1160 dump_ir_data_edges(block, NULL);
1162 /* dump the nodes that go into the block */
1163 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1165 /* Close the vcg information for the block */
1166 fprintf(F, "}\n\n");
1167 dump_const_node_local(block, NULL);
1173 dump_blockless_nodes (ir_node *n, void *env) {
1174 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1176 dump_ir_data_edges(n, NULL);
1177 dump_ir_block_edge(n);
1178 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1181 if (node_floats(n)) {
1183 dump_ir_data_edges(n, NULL);
1184 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1188 static void dump_ir_block_graph_2 (ir_graph *irg)
1191 /* walk over the blocks in the graph */
1192 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1194 /* dump all nodes that are not in a Block */
1195 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1197 /* dump the Bad node */
1199 dump_node(get_irg_bad(irg), NULL);
1203 dump_ir_block_graph (ir_graph *irg)
1206 rem = current_ir_graph;
1207 current_ir_graph = irg;
1211 dump_ir_block_graph_2 (irg);
1213 if (dump_loop_information_flag) dump_loop_info(irg);
1216 current_ir_graph = rem;
1220 /***********************************************************************/
1221 /* the following routines dump a control flow graph */
1222 /***********************************************************************/
1226 dump_block_to_cfg (ir_node *block, void *env) {
1230 if (get_irn_opcode(block) == iro_Block) {
1231 /* This is a block. Dump a node for the block. */
1232 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1233 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1234 #ifdef DEBUG_libfirm
1235 fprintf (F, "%ld", get_irn_node_nr(block));
1237 fprintf (F, "%p", (void*) block);
1240 // if (exc_normal != get_Block_exc (block))
1241 // fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1244 if (dump_dominator_information_flag)
1245 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1247 /* Dump the edges */
1248 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1249 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1250 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1251 fprintf (F, "edge: { sourcename: \"");
1252 PRINT_NODEID(block);
1253 fprintf (F, "\" targetname: \"");
1255 fprintf (F, "\"}\n");
1258 /* Dump dominator edge */
1259 if (dump_dominator_information_flag && get_Block_idom(block)) {
1260 pred = get_Block_idom(block);
1261 fprintf (F, "edge: { sourcename: \"");
1262 PRINT_NODEID(block);
1263 fprintf (F, "\" targetname: \"");
1265 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1271 dump_cfg (ir_graph *irg)
1273 ir_graph *rem = current_ir_graph;
1274 int ddif = dump_dominator_information_flag;
1275 current_ir_graph = irg;
1276 vcg_open (irg, "-cfg");
1278 if (get_irg_dom_state(irg) != dom_consistent)
1279 dump_dominator_information_flag = 0;
1281 /* walk over the blocks in the graph */
1282 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1283 dump_node (get_irg_bad(irg), NULL);
1285 dump_dominator_information_flag = ddif;
1287 current_ir_graph = rem;
1291 /***********************************************************************/
1292 /* the following routine dumps all type information reachable from an */
1294 /***********************************************************************/
1298 dump_type_graph (ir_graph *irg)
1301 rem = current_ir_graph;
1302 current_ir_graph = irg;
1304 vcg_open (irg, "-type");
1306 /* walk over the blocks in the graph */
1307 type_walk_irg(irg, dump_type_info, NULL, NULL);
1308 /* The walker for the const code can be called several times for the
1309 same (sub) experssion. So that no nodes are dumped several times
1310 we decrease the visited flag of the corresponding graph after each
1311 walk. So now increase it finally. */
1312 inc_irg_visited(get_const_code_irg());
1315 current_ir_graph = rem;
1318 /***********************************************************************/
1319 /* the following routine dumps all type information */
1320 /***********************************************************************/
1324 dump_all_types (void)
1326 vcg_open_name ("All_types");
1327 type_walk(dump_type_info, NULL, NULL);
1328 inc_irg_visited(get_const_code_irg());
1333 dump_class_hierarchy (bool entities)
1335 vcg_open_name ("class_hierarchy");
1337 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1339 type_walk(dump_class_hierarchy_node, NULL, NULL);
1343 /***********************************************************************/
1344 /* dumps a graph with type information */
1345 /***********************************************************************/
1349 dump_ir_graph_w_types (ir_graph *irg)
1352 rem = current_ir_graph;
1353 current_ir_graph = irg;
1355 vcg_open (irg, "-all");
1357 /* dump common ir graph */
1358 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1359 /* dump type info */
1360 type_walk_irg(irg, dump_type_info, NULL, NULL);
1361 inc_irg_visited(get_const_code_irg());
1362 /* dump edges from graph to type info */
1363 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1366 current_ir_graph = rem;
1370 dump_ir_block_graph_w_types (ir_graph *irg)
1373 rem = current_ir_graph;
1374 current_ir_graph = irg;
1376 vcg_open (irg, "-all");
1378 /* dump common blocked ir graph */
1379 dump_ir_block_graph_2(irg);
1380 /* dump type info */
1381 type_walk_irg(irg, dump_type_info, NULL, NULL);
1382 inc_irg_visited(get_const_code_irg());
1383 /* dump edges from graph to type info */
1384 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1387 current_ir_graph = rem;
1390 /***********************************************************************/
1391 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1393 /* dump_ir_block_graph */
1395 /* dump_type_graph */
1396 /* dump_ir_graph_w_types */
1397 /***********************************************************************/
1398 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1400 for (i=0; i < get_irp_n_irgs(); i++) {
1401 dump_graph(get_irp_irg(i));
1406 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1407 abort with a segmentation fault. */
1408 void turn_off_edge_labels(void) {
1413 void dump_consts_local(bool b) {
1414 dump_const_local = b;
1417 void turn_off_constant_entity_values(void) {
1421 void dump_keepalive_edges(bool b) {
1425 bool get_opt_dump_keepalive_edges(void) {
1426 return dump_keepalive;
1429 void dump_out_edges(void) {
1430 dump_out_edge_flag = 1;
1433 void dump_dominator_information(void) {
1434 dump_dominator_information_flag = 1;
1437 void dump_loop_information(void) {
1438 dump_loop_information_flag = 1;
1441 void dont_dump_loop_information(void) {
1442 dump_loop_information_flag = 0;
1445 void dump_backedge_information(bool b) {
1446 dump_backedge_information_flag = b;
1449 static void clear_link(ir_node * node, void * env) {
1450 set_irn_link(node, NULL);
1454 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1455 assert(node); assert(map);
1457 || node_floats(node)
1458 || get_irn_op(node) == op_Bad
1459 || get_irn_op(node) == op_Unknown) {
1460 pmap_entry * entry = pmap_find(map, current_ir_graph);
1466 ARR_APP1(ir_node *, arr, node);
1467 entry->value = (void *)arr;
1469 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1472 pmap_insert(map, current_ir_graph, arr);
1475 ir_node * block = get_nodes_Block(node);
1476 set_irn_link(node, get_irn_link(block));
1477 set_irn_link(block, node);
1482 static void dump_cg_ir_block(ir_node * block, void * env) {
1484 pmap *irgmap = (pmap *)env;
1485 assert(is_Block(block));
1487 fprintf(F, "graph: { title: \"");
1488 PRINT_NODEID(block);
1489 fprintf(F, "\" label: \"");
1490 dump_node_opcode(block);
1491 fprintf (F, " %ld", get_irn_node_nr(block));
1493 // if (exc_normal != get_Block_exc(block)) {
1494 // fprintf (F, " (%s)", exc_to_string (get_Block_exc(block))); }
1496 fprintf(F, "\" status:clustered color:%s \n",
1497 get_Block_matured(block) ? "yellow" : "red");
1499 /* dump the blocks edges */
1500 dump_ir_data_edges(block, irgmap);
1502 /* dump the nodes that go into the block */
1503 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1504 dump_node(node, irgmap);
1505 dump_ir_data_edges(node, irgmap);
1508 /* Close the vcg information for the block */
1510 dump_const_node_local(block, irgmap);
1514 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1517 fprintf(F, "graph: { title: \"%p\" label: \"%s\" status:clustered color:white \n",
1518 (void*) irg, get_entity_name(get_irg_ent(irg)));
1520 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1521 ir_node * node = arr[i];
1522 if (is_Block(node)) {
1523 /* Dumps the block and all the nodes in the block, which are to
1524 be found in Block->link. */
1525 dump_cg_ir_block(node, irgmap);
1527 /* Nodes that are not in a Block. */
1528 dump_node(node, NULL);
1529 dump_ir_data_edges(node, NULL);
1532 /* Close the vcg information for the irg */
1533 fprintf(F, "}\n\n");
1536 /* dump interprocedural graph with surrounding methods */
1537 void dump_cg_block_graph(ir_graph * irg) {
1538 pmap * map = pmap_create();
1539 pmap * map2 = pmap_create();
1544 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1545 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1546 pmap_insert(map2, entry->key, entry->value);
1547 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1548 d_cg_block_graph(entry->key, entry->value, map2);
1549 DEL_ARR_F(entry->value);
1555 if (dump_loop_information_flag) dump_loop_info(irg);
1559 static void collect_node(ir_node * node, void *env) {
1561 || node_floats(node)
1562 || get_irn_op(node) == op_Bad
1563 || get_irn_op(node) == op_Unknown) {
1564 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1565 ARR_APP1(ir_node *, arr, node);
1566 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1568 ir_node * block = get_nodes_Block(node);
1569 set_irn_link(node, get_irn_link(block));
1570 set_irn_link(block, node);
1574 /* Links all nodes that have the block field set in the link field of
1575 the block. Adds all blocks and nodes not associated with a block
1576 in a array in irg->link. */
1577 static void collect_nodes(void) {
1579 for (i = 0; i < get_irp_n_irgs(); i++)
1580 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1581 cg_walk(clear_link, collect_node, NULL);
1584 static void dump_graphs(void) {
1586 for (i = 0; i < get_irp_n_irgs(); i++) {
1587 current_ir_graph = get_irp_irg(i);
1588 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1592 /* Dump all irgs in interprocedural view to a single file. */
1593 void dump_all_cg_block_graph(void) {
1595 int rem_view = interprocedural_view;
1596 interprocedural_view = 1;
1597 vcg_open_name ("All_graphs");
1602 if (dump_loop_information_flag)
1603 for (i = 0; i < get_irp_n_irgs(); i++)
1604 dump_loop_info(get_irp_irg(i));
1607 interprocedural_view = rem_view;
1610 /* dump interprocedural block graph with surrounding methods */
1611 void dump_cg_graph(ir_graph * irg) {
1612 pmap * map = pmap_create();
1613 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1617 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1618 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1619 pmap_insert(map2, entry->key, entry->value);
1620 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1621 ir_node ** arr = entry->value;
1623 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1625 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1626 get_id_str(irg_ident), get_id_str(irg_ident));
1628 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1629 ir_node * node = arr[i];
1630 dump_node(node, map2);
1631 dump_ir_data_edges(node, NULL);
1632 if (is_Block(node)) {
1633 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1634 dump_node(node, map2);
1635 dump_ir_block_edge(node);
1636 dump_ir_data_edges(node, NULL);
1643 /* Close the vcg information for the irg */
1644 fprintf(F, "}\n\n");
1653 /* Dump the information of type field specified in ana/irtypeinfo.h.
1654 * If the flag is set, the type name is output in [] in the node label,
1655 * else it is output as info.
1657 void dump_analysed_type_info(bool b) {
1658 opt_dump_analysed_type_info = b;