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.
22 # include "irnode_t.h"
23 # include "irgraph_t.h"
24 # include "entity_t.h"
26 # include "firm_common_t.h"
31 # include "typewalk.h"
34 # include "type_or_entity.h"
47 void dump_chi_term(FILE *FL, ir_node *n);
48 void dump_state(FILE *FL, ir_node *n);
49 int get_opt_dump_abstvals(void);
50 typedef unsigned long SeqNo;
51 SeqNo get_Block_seqno(ir_node *n);
54 /* Attributes of nodes */
55 #define PRINT_DEFAULT_NODE_ATTR
56 #define DEFAULT_NODE_ATTR " "
57 #define DEFAULT_TYPE_ATTRIBUTE " "
59 /* Attributes of edges between Firm nodes */
60 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
61 #define CF_EDGE_ATTR "color: red"
62 #define MEM_EDGE_ATTR "color: blue"
63 #define DOMINATOR_EDGE_ATTR "color: red"
65 #define BACK_EDGE_ATTR "linestyle: dashed "
67 /* Attributes of edges between Firm nodes and type/entity nodes */
68 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
70 /* Attributes of edges in type/entity graphs. */
71 #define TYPE_METH_NODE_ATTR "color: lightyellow"
72 #define TYPE_CLASS_NODE_ATTR "color: green"
73 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
74 #define ENTITY_NODE_ATTR "color: yellow"
75 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
76 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
77 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
78 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
79 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
80 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
81 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
82 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
83 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
84 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
85 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
86 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
87 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
90 #if DEBUG_libfirm && NODEID_AS_LABEL
91 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
92 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
93 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
94 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
95 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
96 #define PRINT_LOOPID(X) fprintf(F, "l%p", (void *)X)
99 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
100 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
101 #define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
102 #define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
103 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
104 #define PRINT_LOOPID(X) fprintf(F, "l%p", (void *)X)
107 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
112 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
113 fprintf(F, " targetname: "); PRINT_TYPEID(T);
114 vfprintf(F, fmt, ap);
119 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
124 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
125 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
126 vfprintf(F, fmt, ap);
131 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, const char *fmt, ...)
136 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
137 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
138 vfprintf(F, fmt, ap);
143 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
148 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
149 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
150 vfprintf(F, fmt, ap);
155 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
160 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
161 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
162 vfprintf(F, fmt, ap);
167 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
172 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
173 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
175 vfprintf(F, fmt, ap);
180 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
185 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
186 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
187 vfprintf(F, fmt, ap);
192 /*******************************************************************/
193 /* global and ahead declarations */
194 /*******************************************************************/
196 /* A suffix to manipulate the file name. */
197 char *dump_file_suffix = "";
199 /* file to dump to */
202 static void dump_whole_node(ir_node *n, void* env);
203 static INLINE void dump_loop_info(ir_graph *irg);
205 /*******************************************************************/
206 /* Helper functions. */
207 /*******************************************************************/
209 /* Use private link attr to be able to call dumper anywhere without
210 destroying link fields. */
212 static pmap *irdump_link_map = NULL;
214 static void init_irdump(void) {
215 /* We need a new, empty map. */
216 if (irdump_link_map) pmap_destroy(irdump_link_map);
217 irdump_link_map = pmap_create();
221 void *ird_get_irn_link(ir_node *n) {
223 if (!irdump_link_map) return NULL;
225 if (pmap_contains(irdump_link_map, (void *)n))
226 res = pmap_get(irdump_link_map, (void *)n);
230 void ird_set_irn_link(ir_node *n, void *x) {
231 if (!irdump_link_map) init_irdump();
232 pmap_insert(irdump_link_map, (void *)n, x);
235 void *ird_get_irg_link(ir_graph *irg) {
237 if (!irdump_link_map) return NULL;
239 if (pmap_contains(irdump_link_map, (void *)irg))
240 res = pmap_get(irdump_link_map, (void *)irg);
244 void ird_set_irg_link(ir_graph *irg, void *x) {
245 if (!irdump_link_map) init_irdump();
246 pmap_insert(irdump_link_map, (void *)irg, x);
249 static void clear_link(ir_node * node, void * env) {
250 ird_set_irn_link(node, NULL);
254 static int node_floats(ir_node *n) {
255 return ((get_op_pinned(get_irn_op(n)) == floats) &&
256 (get_irg_pinned(current_ir_graph) == floats));
259 static const char *get_ent_dump_name (entity *ent) {
260 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
261 if (ent->ld_name) return get_id_str(ent->ld_name);
262 return get_id_str(ent->name);
265 static const char *get_irg_dump_name (ir_graph *irg) {
266 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
267 entity *ent = get_irg_ent(irg);
268 return get_ent_dump_name(ent);
271 static void collect_node(ir_node * node, void *env) {
274 || get_irn_op(node) == op_Bad
275 || get_irn_op(node) == op_Unknown) {
276 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
277 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
278 ARR_APP1(ir_node *, arr, node);
279 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
281 ir_node * block = get_nodes_block(node);
282 ird_set_irn_link(node, ird_get_irn_link(block));
283 ird_set_irn_link(block, node);
287 /** Construct lists to walk ir block-wise.
289 * Collects all blocks, nodes not pinned,
290 * Bad and Unknown into a flexible array in link field of
291 * irg they belong to. Sets the irg link field to NULL in all
292 * graphs not visited.
293 * Free the list with DEL_ARR_F. */
294 static ir_node ** construct_block_lists(ir_graph *irg) {
296 ir_graph *rem = current_ir_graph;
297 current_ir_graph = irg;
299 for (i = 0; i < get_irp_n_irgs(); i++)
300 ird_set_irg_link(get_irp_irg(i), NULL);
302 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
304 current_ir_graph = rem;
305 return ird_get_irg_link(irg);
308 /*******************************************************************/
309 /* flags to steer output */
310 /*******************************************************************/
312 /* A compiler option to turn off edge labels */
314 /* A compiler option to turn off dumping values of constant entities */
315 int const_entities = 1;
316 /* A compiler option to dump the keep alive edges */
317 int dump_keepalive = 0;
318 /* Compiler options to dump analysis information in dump_ir_graph */
319 int dump_out_edge_flag = 0;
320 int dump_dominator_information_flag = 0;
321 int dump_loop_information_flag = 0;
322 int dump_backedge_information_flag = 1;
323 int dump_const_local = 0;
324 bool opt_dump_analysed_type_info = 1;
325 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
327 INLINE bool get_opt_dump_const_local(void) {
328 if (!dump_out_edge_flag && !dump_loop_information_flag)
329 return dump_const_local;
334 /* To turn off display of edge labels. Edge labels offen cause xvcg to
335 abort with a segmentation fault. */
336 void turn_off_edge_labels(void) {
340 void dump_consts_local(bool b) {
341 dump_const_local = b;
344 void turn_off_constant_entity_values(void) {
348 void dump_keepalive_edges(bool b) {
352 bool get_opt_dump_keepalive_edges(void) {
353 return dump_keepalive;
356 void dump_out_edges(void) {
357 dump_out_edge_flag = 1;
360 void dump_dominator_information(void) {
361 dump_dominator_information_flag = 1;
364 void dump_loop_information(void) {
365 dump_loop_information_flag = 1;
368 void dont_dump_loop_information(void) {
369 dump_loop_information_flag = 0;
372 void dump_backedge_information(bool b) {
373 dump_backedge_information_flag = b;
376 /* Dump the information of type field specified in ana/irtypeinfo.h.
377 * If the flag is set, the type name is output in [] in the node label,
378 * else it is output as info.
380 void dump_analysed_type_info(bool b) {
381 opt_dump_analysed_type_info = b;
384 void dump_pointer_values_to_info(bool b) {
385 opt_dump_pointer_values_to_info = b;
388 /*******************************************************************/
389 /* Routines to dump information about a single ir node. */
390 /*******************************************************************/
393 dump_node_opcode (ir_node *n)
396 switch(get_irn_opcode(n)) {
401 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
402 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
407 if (get_SymConst_kind(n) == linkage_ptr_info) {
408 /* don't use get_SymConst_ptr_info as it mangles the name. */
409 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
411 assert(get_kind(get_SymConst_type(n)) == k_type);
412 assert(get_type_ident(get_SymConst_type(n)));
413 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
414 if (get_SymConst_kind(n) == type_tag)
422 if (!interprocedural_view) fprintf(F, "Proj'");
423 else fprintf(F, "%s", get_irn_opname(n));
427 if (interprocedural_view) {
428 fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_ent(get_irn_irg(n))));
434 fprintf (F, "%s", get_irn_opname(n));
441 dump_node_mode (ir_node *n)
443 switch (get_irn_opcode(n)) {
462 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
469 static void dump_node_typeinfo(ir_node *n) {
470 if (!opt_dump_analysed_type_info) return;
471 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
472 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
473 type *tp = get_irn_type(n);
475 fprintf (F, " [%s]", get_type_name(tp));
482 dump_node_nodeattr (ir_node *n)
484 switch (get_irn_opcode(n)) {
486 if (false && interprocedural_view) {
487 fprintf (F, "%s", get_ent_dump_name(get_irg_ent(current_ir_graph)));
491 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
492 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
494 fprintf (F, "%ld", get_Proj_proj(n));
498 fprintf (F, "%ld", get_Filter_proj(n));
501 fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
504 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
507 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
516 dump_node_vcgattr (ir_node *n)
518 switch (get_irn_opcode(n)) {
525 fprintf (F, "color: blue");
528 fprintf (F, "color: lightyellow");
531 fprintf (F, "color: green");
537 fprintf (F, "color: yellow");
540 PRINT_DEFAULT_NODE_ATTR;
545 dump_node_info (ir_node *n) {
548 fprintf (F, " info1: \"");
549 if (opt_dump_pointer_values_to_info)
550 fprintf (F, "addr: %p \n", (void *)n);
551 fprintf (F, "visited: %ld \n", get_irn_visited(n));
552 irg = get_irn_irg(n);
553 if (irg != get_const_code_irg())
554 fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
557 switch (get_irn_opcode(n)) {
559 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
560 fprintf(F, "start of method of type %s \n", get_type_name(tp));
561 for (i = 0; i < get_method_n_params(tp); ++i)
562 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
565 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
568 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
571 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
572 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
575 type *tp = get_Call_type(n);
576 fprintf(F, "calling method of type %s \n", get_type_name(tp));
577 for (i = 0; i < get_method_n_params(tp); ++i)
578 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
579 for (i = 0; i < get_method_n_ress(tp); ++i)
580 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
581 if (Call_has_callees(n)) {
582 fprintf(F, "possible callees: \n");
583 for (i = 0; i < get_Call_n_callees(n); i++) {
584 if (!get_Call_callee(n, i)) {
585 fprintf(F, " %d external method\n", i);
587 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
592 case iro_CallBegin: {
593 ir_node *call = get_CallBegin_call(n);
594 if (Call_has_callees(call)) {
595 fprintf(F, "possible callees: \n");
596 for (i = 0; i < get_Call_n_callees(call); i++) {
597 if (!get_Call_callee(call, i)) {
598 fprintf(F, " %d external method\n", i);
600 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
606 if (!interprocedural_view) {
607 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
608 fprintf(F, "return in method of type %s \n", get_type_name(tp));
609 for (i = 0; i < get_method_n_ress(tp); ++i)
610 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
614 type *tp = get_Const_type(n);
615 assert(tp != none_type);
616 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
620 if (interprocedural_view) {
621 fprintf(F, "intra predecessor nodes:\n");
622 for (i = 0; i < get_irn_intra_arity(n); i++) {
623 ir_node *pred = get_irn_intra_n(n, i);
624 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
627 fprintf(F, "inter predecessor nodes:\n");
628 for (i = 0; i < get_irn_inter_arity(n); i++) {
629 ir_node *pred = get_irn_inter_n(n, i);
630 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
631 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
639 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
640 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
641 if (get_irn_type(n) != none_type)
642 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
649 bool is_constlike_node(ir_node *n) {
650 ir_op *op = get_irn_op(n);
651 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
655 /* outputs the predecessors of n, that are constants, local. I.e.,
656 generates a copy of the constant predecessors for each node called with. */
657 static void dump_const_node_local(ir_node *n) {
659 if (!get_opt_dump_const_local()) return;
661 /* Use visited flag to avoid outputting nodes twice.
662 initialize it first. */
663 for (i = 0; i < get_irn_arity(n); i++) {
664 ir_node *con = get_irn_n(n, i);
665 if (is_constlike_node(con)) {
666 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
670 for (i = 0; i < get_irn_arity(n); i++) {
671 ir_node *con = get_irn_n(n, i);
672 if (is_constlike_node(con) && irn_not_visited(con)) {
673 mark_irn_visited(con);
674 /* Generate a new name for the node by appending the names of
676 fprintf (F, "node: {title: "); PRINT_CONSTID(n, con);
677 fprintf(F, " label: \"");
678 dump_node_opcode(con);
679 dump_node_mode (con);
680 dump_node_typeinfo(con);
682 dump_node_nodeattr(con);
683 fprintf (F, " %ld", get_irn_node_nr(con));
685 dump_node_vcgattr(con);
693 dump_node (ir_node *n) {
694 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
696 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
700 dump_node_typeinfo(n);
702 dump_node_nodeattr(n);
703 fprintf (F, " %ld", get_irn_node_nr(n));
705 dump_node_vcgattr(n);
708 dump_const_node_local(n);
715 /* dump the edge to the block this node belongs to */
717 dump_ir_block_edge(ir_node *n) {
718 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
719 if (is_no_Block(n)) {
720 fprintf (F, "edge: { sourcename: \"");
722 fprintf (F, "\" targetname: \"");
723 PRINT_NODEID(get_nodes_block(n));
724 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
728 static void print_edge_vcgattr(ir_node *from, int to) {
731 if (dump_backedge_information_flag && is_backedge(from, to))
732 fprintf (F, BACK_EDGE_ATTR);
734 switch (get_irn_opcode(from)) {
736 fprintf (F, CF_EDGE_ATTR);
738 case iro_Start: break;
741 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
742 fprintf (F, CF_EDGE_ATTR);
743 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
744 fprintf (F, MEM_EDGE_ATTR);
747 case iro_EndReg: break;
748 case iro_EndExcept: break;
750 case iro_Break: break;
751 case iro_Cond: break;
754 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
756 case iro_Const: break;
757 case iro_SymConst:break;
760 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
762 case iro_CallBegin: break;
765 case iro_Minus: break;
771 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
779 case iro_Shrs: break;
782 case iro_Conv: break;
784 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
790 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
793 fprintf (F, MEM_EDGE_ATTR);
795 case iro_Tuple: break;
798 switch (get_irn_modecode(from)) {
800 fprintf (F, CF_EDGE_ATTR);
803 fprintf (F, MEM_EDGE_ATTR);
809 case iro_Unknown: break;
816 /* dump edges to our inputs */
818 dump_ir_data_edges(ir_node *n) {
819 int i, visited = get_irn_visited(n);
821 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
824 for (i = 0; i < get_irn_arity(n); i++) {
825 ir_node * pred = get_irn_n(n, i);
828 if ((interprocedural_view && get_irn_visited(pred) < visited))
829 continue; /* pred not dumped */
831 if (dump_backedge_information_flag && is_backedge(n, i))
832 fprintf (F, "backedge: {sourcename: \"");
834 fprintf (F, "edge: {sourcename: \"");
836 fprintf (F, "\" targetname: ");
837 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
838 PRINT_CONSTID(n, pred);
840 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
842 fprintf (F, " label: \"%d\" ", i);
843 print_edge_vcgattr(n, i);
848 /** Dumps a node and its edges but not the block edge
851 dump_node_wo_blockedge (ir_node *n, void* env) {
853 dump_ir_data_edges(n);
856 /** Dumps a node and its edges.
859 dump_whole_node (ir_node *n, void* env) {
860 dump_node_wo_blockedge(n, env);
861 if (!node_floats(n)) dump_ir_block_edge(n);
865 dump_const_node(ir_node *n, void *env) {
866 if (is_Block(n)) return;
867 dump_node_wo_blockedge(n, env);
870 /***********************************************************************/
871 /* the following routines dump the nodes/irgs bracketed to graphs. */
872 /***********************************************************************/
874 /** Dumps a constant expression as entity initializer, array bound ...
876 static void dump_const_expression(ir_node *value) {
877 ir_graph *rem = current_ir_graph;
878 int rem_dump_const_local = dump_const_local;
879 dump_const_local = 0;
880 current_ir_graph = get_const_code_irg();
881 irg_walk(value, dump_const_node, NULL, NULL);
882 /* Decrease visited flag so that we walk with the same flag for the next
883 expresssion. This guarantees that we don't dump the same node twice,
884 as for const expressions cse is performed to save memory. */
885 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
886 current_ir_graph = rem;
887 dump_const_local = rem_dump_const_local;
890 /** Dump a block as graph containing its nodes.
892 * Expects to find nodes belonging to the block as list in its
894 * Dumps the edges of all nodes including itself. */
896 dump_whole_block(ir_node *block) {
898 assert(is_Block(block));
900 fprintf(F, "graph: { title: \"");
902 fprintf(F, "\" label: \"");
903 dump_node_opcode(block);
904 fprintf (F, " %ld", get_irn_node_nr(block));
906 if (get_opt_dump_abstvals())
907 fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
909 fprintf(F, "\" status:clustered color:%s \n",
910 get_Block_matured(block) ? "yellow" : "red");
912 /* dump the blocks edges */
913 dump_ir_data_edges(block);
915 /* dump the nodes that go into the block */
916 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
918 dump_ir_data_edges(node);
921 /* Close the vcg information for the block */
923 dump_const_node_local(block);
925 dump_chi_term(F, block);
930 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
931 * The outermost nodes: blocks and nodes not pinned, Bad, Unknown. */
933 dump_block_graph (ir_graph *irg) {
935 ir_graph *rem = current_ir_graph;
936 ir_node **arr = ird_get_irg_link(irg);
937 current_ir_graph = irg;
939 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
940 ir_node * node = arr[i];
941 if (is_Block(node)) {
942 /* Dumps the block and all the nodes in the block, which are to
943 be found in Block->link. */
944 dump_whole_block(node);
946 /* Nodes that are not in a Block. */
948 dump_ir_data_edges(node);
952 if (dump_loop_information_flag) dump_loop_info(irg);
954 current_ir_graph = rem;
957 /** Dumps an irg as a graph.
958 * If interprocedural view edges can point to nodes out of this graph.
960 static void dump_graph(ir_graph *irg) {
962 fprintf(F, "graph: { title: \"");
964 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
965 get_ent_dump_name(get_irg_ent(irg)));
967 dump_block_graph (irg);
969 /* Close the vcg information for the irg */
973 /*******************************************************************/
974 /* Basic type and entity nodes and edges. */
975 /*******************************************************************/
977 /* dumps the edges between nodes and their type or entity attributes. */
978 static void dump_node2type_edges (ir_node *n, void *env)
982 switch (get_irn_opcode(n)) {
984 /* @@@ some consts have an entity */
987 if ( (get_SymConst_kind(n) == type_tag)
988 || (get_SymConst_kind(n) == size))
990 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
994 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
997 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1000 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1003 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1006 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1014 static void print_type_info(type *tp) {
1015 if (get_type_state(tp) == layout_undefined) {
1016 fprintf(F, "state: layout_undefined\n");
1018 fprintf(F, "state: layout_fixed,\n");
1020 if (get_type_mode(tp))
1021 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
1022 fprintf(F, "size: %dB,\n", get_type_size(tp));
1025 static void print_typespecific_info(type *tp) {
1026 switch (get_type_tpop_code(tp)) {
1029 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1043 case tpo_enumeration:
1057 static void print_typespecific_vcgattr(type *tp) {
1058 switch (get_type_tpop_code(tp)) {
1061 if (peculiarity_existent == get_class_peculiarity(tp))
1062 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1064 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1068 fprintf (F, " " TYPE_METH_NODE_ATTR);
1079 case tpo_enumeration:
1092 static void print_type_node(type *tp)
1094 fprintf (F, "node: {title: ");
1096 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
1097 fprintf (F, " info1: \"");
1098 print_type_info(tp);
1099 print_typespecific_info(tp);
1101 print_typespecific_vcgattr(tp);
1105 #define X(a) case a: fprintf(F, #a); break
1106 void dump_entity_node(entity *ent)
1108 fprintf (F, "node: {title: \"");
1109 PRINT_ENTID(ent); fprintf(F, "\"");
1110 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1111 fprintf (F, "label: ");
1112 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
1113 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
1115 fprintf (F, "\nallocation: ");
1116 switch (get_entity_allocation(ent)) {
1117 X(allocation_dynamic);
1118 X(allocation_automatic);
1119 X(allocation_static);
1120 X(allocation_parameter);
1123 fprintf (F, "\nvisibility: ");
1124 switch (get_entity_visibility(ent)) {
1125 X(visibility_local);
1126 X(visibility_external_visible);
1127 X(visibility_external_allocated);
1130 fprintf (F, "\nvariability: ");
1131 switch (get_entity_variability(ent)) {
1132 X(variability_uninitialized);
1133 X(variability_initialized);
1134 X(variability_part_constant);
1135 X(variability_constant);
1138 fprintf (F, "\nvolatility: ");
1139 switch (get_entity_volatility(ent)) {
1140 X(volatility_non_volatile);
1141 X(volatility_is_volatile);
1144 fprintf(F, "\npeculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent)));
1145 fprintf(F, "\nname: %s\nld_name: %s",
1146 get_ent_dump_name(ent), ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
1147 fprintf(F, "\noffset: %d", get_entity_offset(ent));
1148 if (is_method_type(get_entity_type(ent))) {
1149 if (get_entity_irg(ent)) /* can be null */
1150 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
1152 { fprintf (F, "\nirg = NULL"); }
1154 fprintf(F, "\"\n}\n");
1158 /* dumps a type or entity and it's edges. */
1160 dump_type_info (type_or_ent *tore, void *env) {
1161 int i = 0; /* to shutup gcc */
1163 /* dump this type or entity */
1165 switch (get_kind(tore)) {
1168 entity *ent = (entity *)tore;
1171 dump_entity_node(ent);
1173 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1174 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1175 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1176 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1177 if(is_class_type(get_entity_owner(ent))) {
1178 for(i = 0; i < get_entity_n_overwrites(ent); i++){
1179 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
1182 /* attached subgraphs */
1183 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1184 if (is_atomic_entity(ent)) {
1185 value = get_atomic_ent_value(ent);
1187 print_ent_node_edge(F,ent, value, ENT_VALUE_EDGE_ATTR, i);
1188 /* DDMN(value); $$$ */
1189 dump_const_expression(value);
1192 if (is_compound_entity(ent)) {
1193 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1194 value = get_compound_ent_value(ent, i);
1196 print_ent_node_edge(F,ent,value,ENT_VALUE_EDGE_ATTR,i);
1197 dump_const_expression(value);
1198 print_ent_ent_edge(F,ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
1200 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1201 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1202 get_compound_ent_value_member(ent, i), i);
1211 type *tp = (type *)tore;
1212 print_type_node(tp);
1213 /* and now the edges */
1214 switch (get_type_tpop_code(tp)) {
1217 for (i=0; i < get_class_n_supertypes(tp); i++) {
1218 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1221 for (i=0; i < get_class_n_members(tp); i++) {
1222 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1227 for (i=0; i < get_struct_n_members(tp); i++) {
1228 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1233 for (i = 0; i < get_method_n_params(tp); i++)
1235 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1237 for (i = 0; i < get_method_n_ress(tp); i++)
1239 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1244 for (i = 0; i < get_union_n_members(tp); i++)
1246 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1251 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1252 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1253 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1254 ir_node *upper = get_array_upper_bound(tp, i);
1255 ir_node *lower = get_array_lower_bound(tp, i);
1256 print_node_type_edge(F,upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1257 print_node_type_edge(F,lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1258 dump_const_expression(upper);
1259 dump_const_expression(lower);
1263 case tpo_enumeration:
1268 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1276 break; /* case k_type */
1279 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1281 } /* switch kind_or_entity */
1284 /** For dumping class hierarchies.
1285 * Dumps a class type node and a superclass edge.
1286 * If env != null dumps entities of classes and overwrites edges.
1289 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1290 int i = 0; /* to shutup gcc */
1292 /* dump this type or entity */
1293 switch (get_kind(tore)) {
1295 entity *ent = (entity *)tore;
1296 if (get_entity_owner(ent) == get_glob_type()) break;
1297 if ((env) && is_class_type(get_entity_owner(ent))) {
1299 dump_entity_node(ent);
1301 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1302 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1304 print_ent_ent_edge(F,get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1307 } break; /* case k_entity */
1310 type *tp = (type *)tore;
1311 if (tp == get_glob_type()) break;
1312 switch (get_type_tpop_code(tp)) {
1314 print_type_node(tp);
1315 /* and now the edges */
1316 for (i=0; i < get_class_n_supertypes(tp); i++)
1318 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1324 break; /* case k_type */
1327 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1329 } /* switch kind_or_entity */
1332 /*******************************************************************/
1333 /* dump analysis information that is expressed in graph terms. */
1334 /*******************************************************************/
1336 /* dump out edges */
1338 dump_out_edge (ir_node *n, void* env) {
1340 for (i = 0; i < get_irn_n_outs(n); i++) {
1341 assert(get_irn_out(n, i));
1342 fprintf (F, "edge: {sourcename: \"");
1344 fprintf (F, "\" targetname: \"");
1345 PRINT_NODEID(get_irn_out(n, i));
1346 fprintf (F, "\" color: red linestyle: dashed");
1352 dump_loop_node_edge (ir_loop *loop, int i) {
1354 fprintf (F, "edge: {sourcename: \"");
1356 fprintf (F, "\" targetname: \"");
1357 PRINT_NODEID(get_loop_node(loop, i));
1358 fprintf (F, "\" color: green");
1363 dump_loop_son_edge (ir_loop *loop, int i) {
1365 fprintf (F, "edge: {sourcename: \"");
1367 fprintf (F, "\" targetname: \"");
1368 PRINT_LOOPID(get_loop_son(loop, i));
1369 fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1370 get_loop_element_nr(loop, get_loop_son(loop, i)));
1374 void dump_loops (ir_loop *loop) {
1376 /* dump this loop node */
1377 fprintf (F, "node: {title: \"");
1379 fprintf (F, "\" label: \"loop %d, %d sons, %d nodes\" }\n",
1380 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1381 /* dump edges to nodes in loop -- only if it is a real loop */
1382 if (get_loop_depth(loop) != 0) {
1383 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1384 dump_loop_node_edge(loop, i);
1387 for (i = 0; i < get_loop_n_sons(loop); i++) {
1388 dump_loops(get_loop_son(loop, i));
1389 dump_loop_son_edge(loop, i);
1394 void dump_loop_info(ir_graph *irg) {
1395 ir_graph *rem = current_ir_graph;
1396 current_ir_graph = irg;
1398 if (get_irg_loop(irg)) dump_loops(get_irg_loop(irg));
1400 current_ir_graph = rem;
1404 /************************************************************************/
1405 /* open and close vcg file */
1406 /************************************************************************/
1409 dump_vcg_header(const char *name, const char *orientation) {
1418 if (!orientation) orientation = "bottom_to_top";
1422 "graph: { title: \"ir graph of %s\"\n"
1423 "display_edge_labels: %s\n"
1424 "layoutalgorithm: mindepth\n"
1425 "manhattan_edges: yes\n"
1426 "port_sharing: no\n"
1428 "classname 1: \"Data\"\n"
1429 "classname 2: \"Block\"\n"
1430 "classname 3: \"Entity type\"\n"
1431 "classname 4: \"Entity owner\"\n"
1432 "classname 5: \"Method Param\"\n"
1433 "classname 6: \"Method Res\"\n"
1434 "classname 7: \"Super\"\n"
1435 "classname 8: \"Union\"\n"
1436 "classname 9: \"Points-to\"\n"
1437 "classname 10: \"Array Element Type\"\n"
1438 "classname 11: \"Overwrites\"\n"
1439 "classname 12: \"Member\"\n",
1440 name, label, orientation);
1442 fprintf (F, "\n"); /* a separator */
1445 static void vcg_open (ir_graph *irg, char * suffix1, char *suffix2) {
1446 const char *nm = get_irg_dump_name(irg);
1447 int len = strlen(nm);
1448 char *fname; /* filename to put the vcg information in */
1450 if (!suffix1) suffix1 = "";
1451 if (!suffix2) suffix2 = "";
1453 /** open file for vcg graph */
1454 fname = malloc (len + strlen(suffix1) + strlen(suffix2) + 5);
1455 strncpy (fname, nm, len); /* copy the filename */
1457 strcat (fname, suffix1); /* append file suffix */
1458 strcat (fname, suffix2); /* append file suffix */
1459 strcat (fname, ".vcg"); /* append the .vcg suffix */
1460 F = fopen (fname, "w"); /* open file for writing */
1462 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1467 static void vcg_open_name (const char *name, char *suffix) {
1468 char *fname; /* filename to put the vcg information in */
1470 if (!suffix) suffix = "";
1472 /** open file for vcg graph */
1473 fname = malloc (strlen(name) + 5 + strlen(suffix));
1474 strcpy (fname, name); /* copy the filename */
1475 strcat (fname, suffix);
1476 strcat (fname, ".vcg"); /* append the .vcg suffix */
1477 F = fopen (fname, "w"); /* open file for writing */
1479 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1484 static INLINE void dump_vcg_footer (void) {
1490 dump_vcg_footer(); /* print footer */
1491 fclose (F); /* close vcg file */
1494 /************************************************************************/
1495 /************************************************************************/
1496 /* Routines that dump all or parts of the firm representation to a file */
1497 /************************************************************************/
1498 /************************************************************************/
1500 /************************************************************************/
1501 /* Dump ir graphs, differnt formats and additional information. */
1502 /************************************************************************/
1504 /** Routine to dump a graph, blocks as conventional nodes.
1507 dump_ir_graph (ir_graph *irg)
1511 rem = current_ir_graph;
1512 current_ir_graph = irg;
1514 if (interprocedural_view) suffix = "-pure-ip";
1515 else suffix = "-pure";
1516 vcg_open (irg, dump_file_suffix, suffix);
1517 dump_vcg_header(get_irg_dump_name(irg), NULL);
1519 /* walk over the graph */
1520 /* dump_whole_node must be called in post visiting predecessors */
1521 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1523 /* dump the out edges in a separate walk */
1524 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1525 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1530 current_ir_graph = rem;
1535 dump_ir_block_graph (ir_graph *irg)
1540 if (interprocedural_view) suffix = "-ip";
1542 vcg_open (irg, dump_file_suffix, suffix);
1543 dump_vcg_header(get_irg_dump_name(irg), NULL);
1545 construct_block_lists(irg);
1547 for (i = 0; i < get_irp_n_irgs(); i++) {
1548 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1550 dump_graph(get_irp_irg(i));
1558 /** dumps a graph with type information
1561 dump_ir_graph_w_types (ir_graph *irg)
1563 ir_graph *rem = current_ir_graph;
1565 current_ir_graph = irg;
1567 if (interprocedural_view) suffix = "-pure-wtypes-ip";
1568 else suffix = "-pure-wtypes";
1569 vcg_open (irg, dump_file_suffix, suffix);
1570 dump_vcg_header(get_irg_dump_name(irg), NULL);
1572 /* dump common ir graph */
1573 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1574 /* dump type info */
1575 type_walk_irg(irg, dump_type_info, NULL, NULL);
1576 inc_irg_visited(get_const_code_irg());
1577 /* dump edges from graph to type info */
1578 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1581 current_ir_graph = rem;
1585 dump_ir_block_graph_w_types (ir_graph *irg)
1589 ir_graph *rem = current_ir_graph;
1591 if (interprocedural_view) suffix = "-wtypes-ip";
1592 else suffix = "-wtypes";
1593 vcg_open (irg, dump_file_suffix, suffix);
1594 dump_vcg_header(get_irg_dump_name(irg), NULL);
1596 /* dump common blocked ir graph */
1597 construct_block_lists(irg);
1599 for (i = 0; i < get_irp_n_irgs(); i++) {
1600 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1602 dump_graph(get_irp_irg(i));
1607 /* dump type info */
1608 current_ir_graph = irg;
1609 type_walk_irg(irg, dump_type_info, NULL, NULL);
1610 inc_irg_visited(get_const_code_irg());
1612 /* dump edges from graph to type info */
1613 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1615 current_ir_graph = rem;
1619 /***********************************************************************/
1620 /* The following routines dump a control flow graph. */
1621 /***********************************************************************/
1624 dump_block_to_cfg (ir_node *block, void *env) {
1628 if (is_Block(block)) {
1629 /* This is a block. Dump a node for the block. */
1630 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1631 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1632 PRINT_NODEID(block);
1634 if (dump_dominator_information_flag)
1635 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1637 /* Dump the edges */
1638 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1639 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1640 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1641 fprintf (F, "edge: { sourcename: \"");
1642 PRINT_NODEID(block);
1643 fprintf (F, "\" targetname: \"");
1645 fprintf (F, "\"}\n");
1648 /* Dump dominator edge */
1649 if (dump_dominator_information_flag && get_Block_idom(block)) {
1650 pred = get_Block_idom(block);
1651 fprintf (F, "edge: { sourcename: \"");
1652 PRINT_NODEID(block);
1653 fprintf (F, "\" targetname: \"");
1655 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1661 dump_cfg (ir_graph *irg)
1663 ir_graph *rem = current_ir_graph;
1664 int ddif = dump_dominator_information_flag;
1665 int ipv = interprocedural_view;
1666 current_ir_graph = irg;
1668 vcg_open (irg, dump_file_suffix, "-cfg");
1669 dump_vcg_header(get_irg_dump_name(irg), NULL);
1671 if (interprocedural_view) {
1672 printf("Warning: dumping cfg not in interprocedural view!\n");
1673 interprocedural_view = 0;
1676 if (get_irg_dom_state(irg) != dom_consistent)
1677 dump_dominator_information_flag = 0;
1679 /* walk over the blocks in the graph */
1680 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1681 dump_node (get_irg_bad(irg));
1683 dump_dominator_information_flag = ddif;
1684 interprocedural_view = ipv;
1686 current_ir_graph = rem;
1691 /* Dump all irgs in interprocedural view to a single file. */
1692 void dump_all_cg_block_graph(void) {
1694 int rem_view = interprocedural_view;
1695 interprocedural_view = 1;
1697 vcg_open_name ("All_graphs", dump_file_suffix);
1698 dump_vcg_header("All_graphs", NULL);
1700 /* collect nodes in all irgs reachable in call graph*/
1701 for (i = 0; i < get_irp_n_irgs(); i++)
1702 ird_set_irg_link(get_irp_irg(i), NULL);
1704 cg_walk(clear_link, collect_node, NULL);
1706 /* dump all graphs */
1707 for (i = 0; i < get_irp_n_irgs(); i++) {
1708 current_ir_graph = get_irp_irg(i);
1709 assert(ird_get_irg_link(current_ir_graph));
1710 dump_graph(current_ir_graph);
1711 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
1715 interprocedural_view = rem_view;
1718 /***********************************************************************/
1719 /* the following routines dumps type information without any ir nodes. */
1720 /***********************************************************************/
1723 dump_type_graph (ir_graph *irg)
1726 rem = current_ir_graph;
1727 current_ir_graph = irg;
1729 vcg_open (irg, dump_file_suffix, "-type");
1730 dump_vcg_header(get_irg_dump_name(irg), NULL);
1732 /* walk over the blocks in the graph */
1733 type_walk_irg(irg, dump_type_info, NULL, NULL);
1734 /* The walker for the const code can be called several times for the
1735 same (sub) experssion. So that no nodes are dumped several times
1736 we decrease the visited flag of the corresponding graph after each
1737 walk. So now increase it finally. */
1738 inc_irg_visited(get_const_code_irg());
1741 current_ir_graph = rem;
1745 dump_all_types (void)
1747 vcg_open_name ("All_types", dump_file_suffix);
1748 dump_vcg_header("All_types", NULL);
1749 type_walk(dump_type_info, NULL, NULL);
1750 inc_irg_visited(get_const_code_irg());
1755 dump_class_hierarchy (bool entities)
1757 vcg_open_name ("class_hierarchy", dump_file_suffix);
1758 dump_vcg_header("class_hierarchy", NULL);
1760 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1762 type_walk(dump_class_hierarchy_node, NULL, NULL);
1766 /***********************************************************************/
1767 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1769 /* dump_ir_block_graph */
1771 /* dump_type_graph */
1772 /* dump_ir_graph_w_types */
1773 /***********************************************************************/
1775 void dump_all_ir_graphs (dump_graph_func *dmp_grph) {
1777 for (i=0; i < get_irp_n_irgs(); i++) {
1778 dmp_grph(get_irp_irg(i));
1783 /**********************************************************************************
1784 * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes *
1785 * packed together in one subgraph *
1786 **********************************************************************************/
1790 void dump_loops_standalone (ir_loop *loop) {
1791 int i, loop_node_started = 0, son_number = 0, chunk_nr = 0;
1794 /* Start a new loop node */
1795 fprintf (F, "node: {title: \"");
1797 fprintf (F, "\" color: yellow label: \"loop %d, %d sons, %d nodes\" }\n",
1798 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1800 for(i = 0; i < get_loop_n_elements(loop); i++)
1802 le = get_loop_element(loop, i);
1804 ir_loop *son = le.son;
1805 if (get_kind(son) == k_ir_loop)
1807 /* We are a loop son -> Recurse */
1809 if(loop_node_started) /* Close the "firm-nodes" node first if we started one. */
1812 loop_node_started = 0;
1814 dump_loops_standalone(son);
1815 dump_loop_son_edge(loop, son_number++);
1819 /* We are a loop node -> Collect firm nodes */
1821 ir_node *n = le.node;
1823 if (!loop_node_started)
1825 /* Start a new node which contains all firm nodes of the current loop */
1827 fprintf (F, "edge: {sourcename: \"");
1829 fprintf (F, "\" targetname: \"");
1831 fprintf (F, "-%d-nodes\" label:\"%d ...\"}\n", chunk_nr, i);
1833 fprintf (F, "node: { title: \"");
1835 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", chunk_nr++);
1836 loop_node_started = 1;
1841 dump_node_opcode(n);
1843 dump_node_typeinfo(n);
1845 dump_node_nodeattr(n);
1846 fprintf (F, " %ld", get_irn_node_nr(n));
1850 if(loop_node_started)
1853 loop_node_started = 0;
1857 void dump_loop_tree(ir_graph *irg, char *suffix)
1859 ir_graph *rem = current_ir_graph;
1860 int el_rem = edge_label;
1863 current_ir_graph = irg;
1865 vcg_open(irg, suffix, "-looptree");
1866 dump_vcg_header(get_irg_dump_name(irg), "top_to_bottom");
1868 if (get_irg_loop(irg)) dump_loops_standalone(get_irg_loop(irg));
1872 edge_label = el_rem;
1873 current_ir_graph = rem;