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"
46 void dump_chi_term(FILE *FL, ir_node *n);
47 void dump_state(FILE *FL, ir_node *n);
48 int get_opt_dump_abstvals(void);
49 typedef unsigned long SeqNo;
50 SeqNo get_Block_seqno(ir_node *n);
53 /* Attributes of nodes */
54 #define PRINT_DEFAULT_NODE_ATTR
55 #define DEFAULT_NODE_ATTR " "
56 #define DEFAULT_TYPE_ATTRIBUTE " "
58 /* Attributes of edges between Firm nodes */
59 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
60 #define CF_EDGE_ATTR "color: red"
61 #define MEM_EDGE_ATTR "color: blue"
62 #define DOMINATOR_EDGE_ATTR "color: red"
64 #define BACK_EDGE_ATTR "linestyle: dashed "
66 /* Attributes of edges between Firm nodes and type/entity nodes */
67 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
69 /* Attributes of edges in type/entity graphs. */
70 #define TYPE_METH_NODE_ATTR "color: lightyellow"
71 #define TYPE_CLASS_NODE_ATTR "color: green"
72 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
73 #define ENTITY_NODE_ATTR "color: yellow"
74 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
75 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
76 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
77 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
78 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
79 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
80 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
81 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
82 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
83 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
84 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
85 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
86 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
89 #if DEBUG_libfirm && NODEID_AS_LABEL
90 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
91 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
92 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
93 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
94 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
95 #define PRINT_LOOPID(X) fprintf(F, "l%d", get_loop_loop_nr(X))
98 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
99 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
100 #define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
101 #define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
102 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
103 #define PRINT_LOOPID(X) fprintf(F, "l%p", (void *)X)
106 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
111 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
112 fprintf(F, " targetname: "); PRINT_TYPEID(T);
113 vfprintf(F, fmt, ap);
118 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
123 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
124 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
125 vfprintf(F, fmt, ap);
130 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, const char *fmt, ...)
135 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
136 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
137 vfprintf(F, fmt, ap);
142 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
147 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
148 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
149 vfprintf(F, fmt, ap);
154 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
159 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
160 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
161 vfprintf(F, fmt, ap);
166 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
171 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
172 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
174 vfprintf(F, fmt, ap);
179 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
184 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
185 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
186 vfprintf(F, fmt, ap);
191 /*******************************************************************/
192 /* global and ahead declarations */
193 /*******************************************************************/
195 /* A suffix to manipulate the file name. */
196 char *dump_file_suffix = "";
198 /* file to dump to */
201 static void dump_whole_node(ir_node *n, void* env);
202 static INLINE void dump_loop_nodes_into_graph(ir_graph *irg);
204 /*******************************************************************/
205 /* Helper functions. */
206 /*******************************************************************/
208 /* Use private link attr to be able to call dumper anywhere without
209 destroying link fields. */
211 static pmap *irdump_link_map = NULL;
213 static void init_irdump(void) {
214 /* We need a new, empty map. */
215 if (irdump_link_map) pmap_destroy(irdump_link_map);
216 irdump_link_map = pmap_create();
220 void *ird_get_irn_link(ir_node *n) {
222 if (!irdump_link_map) return NULL;
224 if (pmap_contains(irdump_link_map, (void *)n))
225 res = pmap_get(irdump_link_map, (void *)n);
229 void ird_set_irn_link(ir_node *n, void *x) {
230 if (!irdump_link_map) init_irdump();
231 pmap_insert(irdump_link_map, (void *)n, x);
234 void *ird_get_irg_link(ir_graph *irg) {
236 if (!irdump_link_map) return NULL;
238 if (pmap_contains(irdump_link_map, (void *)irg))
239 res = pmap_get(irdump_link_map, (void *)irg);
243 void ird_set_irg_link(ir_graph *irg, void *x) {
244 if (!irdump_link_map) init_irdump();
245 pmap_insert(irdump_link_map, (void *)irg, x);
248 static void clear_link(ir_node * node, void * env) {
249 ird_set_irn_link(node, NULL);
253 static int node_floats(ir_node *n) {
254 return ((get_op_pinned(get_irn_op(n)) == floats) &&
255 (get_irg_pinned(current_ir_graph) == floats));
258 static const char *get_ent_dump_name (entity *ent) {
259 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
260 if (ent->ld_name) return get_id_str(ent->ld_name);
261 return get_id_str(ent->name);
264 static const char *get_irg_dump_name (ir_graph *irg) {
265 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
266 entity *ent = get_irg_ent(irg);
267 return get_ent_dump_name(ent);
270 static void collect_node(ir_node * node, void *env) {
273 || get_irn_op(node) == op_Bad
274 || get_irn_op(node) == op_Unknown) {
275 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
276 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
277 ARR_APP1(ir_node *, arr, node);
278 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
280 ir_node * block = get_nodes_block(node);
281 ird_set_irn_link(node, ird_get_irn_link(block));
282 ird_set_irn_link(block, node);
286 /** Construct lists to walk ir block-wise.
288 * Collects all blocks, nodes not pinned,
289 * Bad and Unknown into a flexible array in link field of
290 * irg they belong to. Sets the irg link field to NULL in all
291 * graphs not visited.
292 * Free the list with DEL_ARR_F. */
293 static ir_node ** construct_block_lists(ir_graph *irg) {
295 ir_graph *rem = current_ir_graph;
296 current_ir_graph = irg;
298 for (i = 0; i < get_irp_n_irgs(); i++)
299 ird_set_irg_link(get_irp_irg(i), NULL);
301 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
303 current_ir_graph = rem;
304 return ird_get_irg_link(irg);
307 /*******************************************************************/
308 /* flags to steer output */
309 /*******************************************************************/
311 /* A compiler option to turn off edge labels */
313 /* A compiler option to turn off dumping values of constant entities */
314 int const_entities = 1;
315 /* A compiler option to dump the keep alive edges */
316 int dump_keepalive = 0;
317 /* Compiler options to dump analysis information in dump_ir_graph */
318 int dump_out_edge_flag = 0;
319 int dump_dominator_information_flag = 0;
320 int dump_loop_information_flag = 0;
321 int dump_backedge_information_flag = 1;
322 int dump_const_local = 0;
323 bool opt_dump_analysed_type_info = 1;
324 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
326 char* overrule_nodecolor = NULL;
328 INLINE bool get_opt_dump_const_local(void) {
329 if (!dump_out_edge_flag && !dump_loop_information_flag)
330 return dump_const_local;
335 /* To turn off display of edge labels. Edge labels offen cause xvcg to
336 abort with a segmentation fault. */
337 void turn_off_edge_labels(void) {
341 void dump_consts_local(bool b) {
342 dump_const_local = b;
345 void turn_off_constant_entity_values(void) {
349 void dump_keepalive_edges(bool b) {
353 bool get_opt_dump_keepalive_edges(void) {
354 return dump_keepalive;
357 void dump_out_edges(void) {
358 dump_out_edge_flag = 1;
361 void dump_dominator_information(void) {
362 dump_dominator_information_flag = 1;
365 void dump_loop_information(void) {
366 dump_loop_information_flag = 1;
369 void dont_dump_loop_information(void) {
370 dump_loop_information_flag = 0;
373 void dump_backedge_information(bool b) {
374 dump_backedge_information_flag = b;
377 /* Dump the information of type field specified in ana/irtypeinfo.h.
378 * If the flag is set, the type name is output in [] in the node label,
379 * else it is output as info.
381 void dump_analysed_type_info(bool b) {
382 opt_dump_analysed_type_info = b;
385 void dump_pointer_values_to_info(bool b) {
386 opt_dump_pointer_values_to_info = b;
389 /*******************************************************************/
390 /* Routines to dump information about a single ir node. */
391 /*******************************************************************/
394 dump_node_opcode (ir_node *n)
397 switch(get_irn_opcode(n)) {
402 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
403 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
408 if (get_SymConst_kind(n) == linkage_ptr_info) {
409 /* don't use get_SymConst_ptr_info as it mangles the name. */
410 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
412 assert(get_kind(get_SymConst_type(n)) == k_type);
413 assert(get_type_ident(get_SymConst_type(n)));
414 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
415 if (get_SymConst_kind(n) == type_tag)
423 if (!interprocedural_view) fprintf(F, "Proj'");
424 else fprintf(F, "%s", get_irn_opname(n));
428 if (interprocedural_view) {
429 fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_ent(get_irn_irg(n))));
435 fprintf (F, "%s", get_irn_opname(n));
442 dump_node_mode (ir_node *n)
444 switch (get_irn_opcode(n)) {
463 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
470 static void dump_node_typeinfo(ir_node *n) {
471 if (!opt_dump_analysed_type_info) return;
472 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
473 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
474 type *tp = get_irn_type(n);
476 fprintf (F, " [%s]", get_type_name(tp));
483 dump_node_nodeattr (ir_node *n)
485 switch (get_irn_opcode(n)) {
487 if (false && interprocedural_view) {
488 fprintf (F, "%s", get_ent_dump_name(get_irg_ent(current_ir_graph)));
492 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
493 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
495 fprintf (F, "%ld", get_Proj_proj(n));
499 fprintf (F, "%ld", get_Filter_proj(n));
502 fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
505 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
508 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
517 dump_node_vcgattr (ir_node *n)
519 switch (get_irn_opcode(n)) {
526 fprintf (F, "color: blue");
529 fprintf (F, "color: lightyellow");
532 fprintf (F, "color: green");
538 fprintf (F, "color: yellow");
541 PRINT_DEFAULT_NODE_ATTR;
544 if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
548 dump_node_info (ir_node *n) {
551 fprintf (F, " info1: \"");
552 if (opt_dump_pointer_values_to_info)
553 fprintf (F, "addr: %p \n", (void *)n);
554 fprintf (F, "visited: %ld \n", get_irn_visited(n));
555 irg = get_irn_irg(n);
556 if (irg != get_const_code_irg())
557 fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
560 switch (get_irn_opcode(n)) {
562 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
563 fprintf(F, "start of method of type %s \n", get_type_name(tp));
564 for (i = 0; i < get_method_n_params(tp); ++i)
565 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
568 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
571 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
574 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
575 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
578 type *tp = get_Call_type(n);
579 fprintf(F, "calling method of type %s \n", get_type_name(tp));
580 for (i = 0; i < get_method_n_params(tp); ++i)
581 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
582 for (i = 0; i < get_method_n_ress(tp); ++i)
583 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
584 if (Call_has_callees(n)) {
585 fprintf(F, "possible callees: \n");
586 for (i = 0; i < get_Call_n_callees(n); i++) {
587 if (!get_Call_callee(n, i)) {
588 fprintf(F, " %d external method\n", i);
590 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
595 case iro_CallBegin: {
596 ir_node *call = get_CallBegin_call(n);
597 if (Call_has_callees(call)) {
598 fprintf(F, "possible callees: \n");
599 for (i = 0; i < get_Call_n_callees(call); i++) {
600 if (!get_Call_callee(call, i)) {
601 fprintf(F, " %d external method\n", i);
603 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
609 if (!interprocedural_view) {
610 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
611 fprintf(F, "return in method of type %s \n", get_type_name(tp));
612 for (i = 0; i < get_method_n_ress(tp); ++i)
613 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
617 type *tp = get_Const_type(n);
618 assert(tp != none_type);
619 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
623 if (interprocedural_view) {
624 fprintf(F, "intra predecessor nodes:\n");
625 for (i = 0; i < get_irn_intra_arity(n); i++) {
626 ir_node *pred = get_irn_intra_n(n, i);
627 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
630 fprintf(F, "inter predecessor nodes:\n");
631 for (i = 0; i < get_irn_inter_arity(n); i++) {
632 ir_node *pred = get_irn_inter_n(n, i);
633 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
634 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
642 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
643 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
644 if (get_irn_type(n) != none_type)
645 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
652 bool is_constlike_node(ir_node *n) {
653 ir_op *op = get_irn_op(n);
654 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
658 /* outputs the predecessors of n, that are constants, local. I.e.,
659 generates a copy of the constant predecessors for each node called with. */
660 static void dump_const_node_local(ir_node *n) {
662 if (!get_opt_dump_const_local()) return;
664 /* Use visited flag to avoid outputting nodes twice.
665 initialize it first. */
666 for (i = 0; i < get_irn_arity(n); i++) {
667 ir_node *con = get_irn_n(n, i);
668 if (is_constlike_node(con)) {
669 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
673 for (i = 0; i < get_irn_arity(n); i++) {
674 ir_node *con = get_irn_n(n, i);
675 if (is_constlike_node(con) && irn_not_visited(con)) {
676 mark_irn_visited(con);
677 /* Generate a new name for the node by appending the names of
679 fprintf (F, "node: {title: "); PRINT_CONSTID(n, con);
680 fprintf(F, " label: \"");
681 dump_node_opcode(con);
682 dump_node_mode (con);
683 dump_node_typeinfo(con);
685 dump_node_nodeattr(con);
686 fprintf (F, " %ld", get_irn_node_nr(con));
688 dump_node_vcgattr(con);
696 dump_node (ir_node *n) {
697 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
699 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
703 dump_node_typeinfo(n);
705 dump_node_nodeattr(n);
706 fprintf (F, " %ld", get_irn_node_nr(n));
708 dump_node_vcgattr(n);
711 dump_const_node_local(n);
718 /* dump the edge to the block this node belongs to */
720 dump_ir_block_edge(ir_node *n) {
721 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
722 if (is_no_Block(n)) {
723 fprintf (F, "edge: { sourcename: \"");
725 fprintf (F, "\" targetname: \"");
726 PRINT_NODEID(get_nodes_block(n));
727 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
731 static void print_edge_vcgattr(ir_node *from, int to) {
734 if (dump_backedge_information_flag && is_backedge(from, to))
735 fprintf (F, BACK_EDGE_ATTR);
737 switch (get_irn_opcode(from)) {
739 fprintf (F, CF_EDGE_ATTR);
741 case iro_Start: break;
744 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
745 fprintf (F, CF_EDGE_ATTR);
746 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
747 fprintf (F, MEM_EDGE_ATTR);
750 case iro_EndReg: break;
751 case iro_EndExcept: break;
753 case iro_Break: break;
754 case iro_Cond: break;
757 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
759 case iro_Const: break;
760 case iro_SymConst:break;
763 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
765 case iro_CallBegin: break;
768 case iro_Minus: break;
774 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
782 case iro_Shrs: break;
785 case iro_Conv: break;
787 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
793 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
796 fprintf (F, MEM_EDGE_ATTR);
798 case iro_Tuple: break;
801 switch (get_irn_modecode(from)) {
803 fprintf (F, CF_EDGE_ATTR);
806 fprintf (F, MEM_EDGE_ATTR);
812 case iro_Unknown: break;
819 /* dump edges to our inputs */
821 dump_ir_data_edges(ir_node *n) {
822 int i, visited = get_irn_visited(n);
824 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
827 for (i = 0; i < get_irn_arity(n); i++) {
828 ir_node * pred = get_irn_n(n, i);
831 if ((interprocedural_view && get_irn_visited(pred) < visited))
832 continue; /* pred not dumped */
834 if (dump_backedge_information_flag && is_backedge(n, i))
835 fprintf (F, "backedge: {sourcename: \"");
837 fprintf (F, "edge: {sourcename: \"");
839 fprintf (F, "\" targetname: ");
840 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
841 PRINT_CONSTID(n, pred);
843 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
845 fprintf (F, " label: \"%d\" ", i);
846 print_edge_vcgattr(n, i);
851 /** Dumps a node and its edges but not the block edge
854 dump_node_wo_blockedge (ir_node *n, void* env) {
856 dump_ir_data_edges(n);
859 /** Dumps a node and its edges.
862 dump_whole_node (ir_node *n, void* env) {
863 dump_node_wo_blockedge(n, env);
864 if (!node_floats(n)) dump_ir_block_edge(n);
868 dump_const_node(ir_node *n, void *env) {
869 if (is_Block(n)) return;
870 dump_node_wo_blockedge(n, env);
873 /***********************************************************************/
874 /* the following routines dump the nodes/irgs bracketed to graphs. */
875 /***********************************************************************/
877 /** Dumps a constant expression as entity initializer, array bound ...
879 static void dump_const_expression(ir_node *value) {
880 ir_graph *rem = current_ir_graph;
881 int rem_dump_const_local = dump_const_local;
882 dump_const_local = 0;
883 current_ir_graph = get_const_code_irg();
884 irg_walk(value, dump_const_node, NULL, NULL);
885 /* Decrease visited flag so that we walk with the same flag for the next
886 expresssion. This guarantees that we don't dump the same node twice,
887 as for const expressions cse is performed to save memory. */
888 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
889 current_ir_graph = rem;
890 dump_const_local = rem_dump_const_local;
893 /** Dump a block as graph containing its nodes.
895 * Expects to find nodes belonging to the block as list in its
897 * Dumps the edges of all nodes including itself. */
899 dump_whole_block(ir_node *block) {
901 assert(is_Block(block));
903 fprintf(F, "graph: { title: \"");
905 fprintf(F, "\" label: \"");
906 dump_node_opcode(block);
907 fprintf (F, " %ld", get_irn_node_nr(block));
909 if (get_opt_dump_abstvals())
910 fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
912 fprintf(F, "\" status:clustered color:%s \n",
913 get_Block_matured(block) ? "yellow" : "red");
915 /* dump the blocks edges */
916 dump_ir_data_edges(block);
918 /* dump the nodes that go into the block */
919 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
921 dump_ir_data_edges(node);
924 /* Close the vcg information for the block */
926 dump_const_node_local(block);
928 dump_chi_term(F, block);
933 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
934 * The outermost nodes: blocks and nodes not pinned, Bad, Unknown. */
936 dump_block_graph (ir_graph *irg) {
938 ir_graph *rem = current_ir_graph;
939 ir_node **arr = ird_get_irg_link(irg);
940 current_ir_graph = irg;
942 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
943 ir_node * node = arr[i];
944 if (is_Block(node)) {
945 /* Dumps the block and all the nodes in the block, which are to
946 be found in Block->link. */
947 dump_whole_block(node);
949 /* Nodes that are not in a Block. */
951 dump_ir_data_edges(node);
955 if (dump_loop_information_flag) dump_loop_nodes_into_graph(irg);
957 current_ir_graph = rem;
960 /** Dumps an irg as a graph.
961 * If interprocedural view edges can point to nodes out of this graph.
963 static void dump_graph(ir_graph *irg) {
965 fprintf(F, "graph: { title: \"");
967 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
968 get_ent_dump_name(get_irg_ent(irg)));
970 dump_block_graph (irg);
972 /* Close the vcg information for the irg */
976 /*******************************************************************/
977 /* Basic type and entity nodes and edges. */
978 /*******************************************************************/
980 /* dumps the edges between nodes and their type or entity attributes. */
981 static void dump_node2type_edges (ir_node *n, void *env)
985 switch (get_irn_opcode(n)) {
987 /* @@@ some consts have an entity */
990 if ( (get_SymConst_kind(n) == type_tag)
991 || (get_SymConst_kind(n) == size))
993 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
997 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1000 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1003 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1006 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1009 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1017 static void print_type_info(type *tp) {
1018 if (get_type_state(tp) == layout_undefined) {
1019 fprintf(F, "state: layout_undefined\n");
1021 fprintf(F, "state: layout_fixed,\n");
1023 if (get_type_mode(tp))
1024 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
1025 fprintf(F, "size: %dB,\n", get_type_size(tp));
1028 static void print_typespecific_info(type *tp) {
1029 switch (get_type_tpop_code(tp)) {
1032 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1046 case tpo_enumeration:
1060 static void print_typespecific_vcgattr(type *tp) {
1061 switch (get_type_tpop_code(tp)) {
1064 if (peculiarity_existent == get_class_peculiarity(tp))
1065 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1067 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1071 fprintf (F, " " TYPE_METH_NODE_ATTR);
1082 case tpo_enumeration:
1095 static void print_type_node(type *tp)
1097 fprintf (F, "node: {title: ");
1099 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
1100 fprintf (F, " info1: \"");
1101 print_type_info(tp);
1102 print_typespecific_info(tp);
1104 print_typespecific_vcgattr(tp);
1108 #define X(a) case a: fprintf(F, #a); break
1109 void dump_entity_node(entity *ent)
1111 fprintf (F, "node: {title: \"");
1112 PRINT_ENTID(ent); fprintf(F, "\"");
1113 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1114 fprintf (F, "label: ");
1115 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
1116 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
1118 fprintf (F, "\nallocation: ");
1119 switch (get_entity_allocation(ent)) {
1120 X(allocation_dynamic);
1121 X(allocation_automatic);
1122 X(allocation_static);
1123 X(allocation_parameter);
1126 fprintf (F, "\nvisibility: ");
1127 switch (get_entity_visibility(ent)) {
1128 X(visibility_local);
1129 X(visibility_external_visible);
1130 X(visibility_external_allocated);
1133 fprintf (F, "\nvariability: ");
1134 switch (get_entity_variability(ent)) {
1135 X(variability_uninitialized);
1136 X(variability_initialized);
1137 X(variability_part_constant);
1138 X(variability_constant);
1141 fprintf (F, "\nvolatility: ");
1142 switch (get_entity_volatility(ent)) {
1143 X(volatility_non_volatile);
1144 X(volatility_is_volatile);
1147 fprintf(F, "\npeculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent)));
1148 fprintf(F, "\nname: %s\nld_name: %s",
1149 get_ent_dump_name(ent), ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
1150 fprintf(F, "\noffset: %d", get_entity_offset(ent));
1151 if (is_method_type(get_entity_type(ent))) {
1152 if (get_entity_irg(ent)) /* can be null */
1153 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
1155 { fprintf (F, "\nirg = NULL"); }
1157 fprintf(F, "\"\n}\n");
1161 /* dumps a type or entity and it's edges. */
1163 dump_type_info (type_or_ent *tore, void *env) {
1164 int i = 0; /* to shutup gcc */
1166 /* dump this type or entity */
1168 switch (get_kind(tore)) {
1171 entity *ent = (entity *)tore;
1174 dump_entity_node(ent);
1176 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1177 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1178 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1179 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1180 if(is_class_type(get_entity_owner(ent))) {
1181 for(i = 0; i < get_entity_n_overwrites(ent); i++){
1182 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
1185 /* attached subgraphs */
1186 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1187 if (is_atomic_entity(ent)) {
1188 value = get_atomic_ent_value(ent);
1190 print_ent_node_edge(F,ent, value, ENT_VALUE_EDGE_ATTR, i);
1191 /* DDMN(value); $$$ */
1192 dump_const_expression(value);
1195 if (is_compound_entity(ent)) {
1196 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1197 value = get_compound_ent_value(ent, i);
1199 print_ent_node_edge(F,ent,value,ENT_VALUE_EDGE_ATTR,i);
1200 dump_const_expression(value);
1201 print_ent_ent_edge(F,ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
1203 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1204 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1205 get_compound_ent_value_member(ent, i), i);
1214 type *tp = (type *)tore;
1215 print_type_node(tp);
1216 /* and now the edges */
1217 switch (get_type_tpop_code(tp)) {
1220 for (i=0; i < get_class_n_supertypes(tp); i++) {
1221 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1224 for (i=0; i < get_class_n_members(tp); i++) {
1225 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1230 for (i=0; i < get_struct_n_members(tp); i++) {
1231 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1236 for (i = 0; i < get_method_n_params(tp); i++)
1238 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1240 for (i = 0; i < get_method_n_ress(tp); i++)
1242 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1247 for (i = 0; i < get_union_n_members(tp); i++)
1249 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1254 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1255 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1256 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1257 ir_node *upper = get_array_upper_bound(tp, i);
1258 ir_node *lower = get_array_lower_bound(tp, i);
1259 print_node_type_edge(F,upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1260 print_node_type_edge(F,lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1261 dump_const_expression(upper);
1262 dump_const_expression(lower);
1266 case tpo_enumeration:
1271 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1279 break; /* case k_type */
1282 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1284 } /* switch kind_or_entity */
1287 /** For dumping class hierarchies.
1288 * Dumps a class type node and a superclass edge.
1289 * If env != null dumps entities of classes and overwrites edges.
1292 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1293 int i = 0; /* to shutup gcc */
1295 /* dump this type or entity */
1296 switch (get_kind(tore)) {
1298 entity *ent = (entity *)tore;
1299 if (get_entity_owner(ent) == get_glob_type()) break;
1300 if ((env) && is_class_type(get_entity_owner(ent))) {
1302 dump_entity_node(ent);
1304 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1305 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1307 print_ent_ent_edge(F,get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1310 } break; /* case k_entity */
1313 type *tp = (type *)tore;
1314 if (tp == get_glob_type()) break;
1315 switch (get_type_tpop_code(tp)) {
1317 print_type_node(tp);
1318 /* and now the edges */
1319 for (i=0; i < get_class_n_supertypes(tp); i++)
1321 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1327 break; /* case k_type */
1330 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1332 } /* switch kind_or_entity */
1335 /*******************************************************************/
1336 /* dump analysis information that is expressed in graph terms. */
1337 /*******************************************************************/
1339 /* dump out edges */
1341 dump_out_edge (ir_node *n, void* env) {
1343 for (i = 0; i < get_irn_n_outs(n); i++) {
1344 assert(get_irn_out(n, i));
1345 fprintf (F, "edge: {sourcename: \"");
1347 fprintf (F, "\" targetname: \"");
1348 PRINT_NODEID(get_irn_out(n, i));
1349 fprintf (F, "\" color: red linestyle: dashed");
1355 dump_loop_label(ir_loop *loop) {
1356 fprintf (F, "loop %d, %d sons, %d nodes",
1357 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1360 static INLINE void dump_loop_info(ir_loop *loop) {
1361 fprintf (F, " info1: \"");
1362 fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1367 dump_loop_node(ir_loop *loop) {
1368 fprintf (F, "node: {title: \"");
1370 fprintf (F, "\" label: \"");
1371 dump_loop_label(loop);
1373 dump_loop_info(loop);
1379 dump_loop_node_edge (ir_loop *loop, int i) {
1381 fprintf (F, "edge: {sourcename: \"");
1383 fprintf (F, "\" targetname: \"");
1384 PRINT_NODEID(get_loop_node(loop, i));
1385 fprintf (F, "\" color: green");
1390 dump_loop_son_edge (ir_loop *loop, int i) {
1392 fprintf (F, "edge: {sourcename: \"");
1394 fprintf (F, "\" targetname: \"");
1395 PRINT_LOOPID(get_loop_son(loop, i));
1396 fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1397 get_loop_element_pos(loop, get_loop_son(loop, i)));
1401 void dump_loops (ir_loop *loop) {
1403 /* dump this loop node */
1404 dump_loop_node(loop);
1406 /* dump edges to nodes in loop -- only if it is a real loop */
1407 if (get_loop_depth(loop) != 0) {
1408 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1409 dump_loop_node_edge(loop, i);
1412 for (i = 0; i < get_loop_n_sons(loop); i++) {
1413 dump_loops(get_loop_son(loop, i));
1414 dump_loop_son_edge(loop, i);
1419 void dump_loop_nodes_into_graph(ir_graph *irg) {
1420 ir_graph *rem = current_ir_graph;
1421 current_ir_graph = irg;
1423 if (get_irg_loop(irg)) dump_loops(get_irg_loop(irg));
1425 current_ir_graph = rem;
1429 /************************************************************************/
1430 /* open and close vcg file */
1431 /************************************************************************/
1434 dump_vcg_header(const char *name, const char *orientation) {
1443 if (!orientation) orientation = "bottom_to_top";
1447 "graph: { title: \"ir graph of %s\"\n"
1448 "display_edge_labels: %s\n"
1449 "layoutalgorithm: mindepth\n"
1450 "manhattan_edges: yes\n"
1451 "port_sharing: no\n"
1453 "classname 1: \"Data\"\n"
1454 "classname 2: \"Block\"\n"
1455 "classname 3: \"Entity type\"\n"
1456 "classname 4: \"Entity owner\"\n"
1457 "classname 5: \"Method Param\"\n"
1458 "classname 6: \"Method Res\"\n"
1459 "classname 7: \"Super\"\n"
1460 "classname 8: \"Union\"\n"
1461 "classname 9: \"Points-to\"\n"
1462 "classname 10: \"Array Element Type\"\n"
1463 "classname 11: \"Overwrites\"\n"
1464 "classname 12: \"Member\"\n",
1465 name, label, orientation);
1467 fprintf (F, "\n"); /* a separator */
1470 static void vcg_open (ir_graph *irg, char * suffix1, char *suffix2) {
1471 const char *nm = get_irg_dump_name(irg);
1472 int len = strlen(nm);
1473 char *fname; /* filename to put the vcg information in */
1475 if (!suffix1) suffix1 = "";
1476 if (!suffix2) suffix2 = "";
1478 /** open file for vcg graph */
1479 fname = malloc (len + strlen(suffix1) + strlen(suffix2) + 5);
1480 strncpy (fname, nm, len); /* copy the filename */
1482 strcat (fname, suffix1); /* append file suffix */
1483 strcat (fname, suffix2); /* append file suffix */
1484 strcat (fname, ".vcg"); /* append the .vcg suffix */
1485 F = fopen (fname, "w"); /* open file for writing */
1487 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1492 static void vcg_open_name (const char *name, char *suffix) {
1493 char *fname; /* filename to put the vcg information in */
1495 if (!suffix) suffix = "";
1497 /** open file for vcg graph */
1498 fname = malloc (strlen(name) + 5 + strlen(suffix));
1499 strcpy (fname, name); /* copy the filename */
1500 strcat (fname, suffix);
1501 strcat (fname, ".vcg"); /* append the .vcg suffix */
1502 F = fopen (fname, "w"); /* open file for writing */
1504 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1509 static INLINE void dump_vcg_footer (void) {
1515 dump_vcg_footer(); /* print footer */
1516 fclose (F); /* close vcg file */
1519 /************************************************************************/
1520 /************************************************************************/
1521 /* Routines that dump all or parts of the firm representation to a file */
1522 /************************************************************************/
1523 /************************************************************************/
1525 /************************************************************************/
1526 /* Dump ir graphs, differnt formats and additional information. */
1527 /************************************************************************/
1529 /** Routine to dump a graph, blocks as conventional nodes.
1532 dump_ir_graph (ir_graph *irg)
1536 rem = current_ir_graph;
1537 current_ir_graph = irg;
1539 if (interprocedural_view) suffix = "-pure-ip";
1540 else suffix = "-pure";
1541 vcg_open (irg, dump_file_suffix, suffix);
1542 dump_vcg_header(get_irg_dump_name(irg), NULL);
1544 /* walk over the graph */
1545 /* dump_whole_node must be called in post visiting predecessors */
1546 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1548 /* dump the out edges in a separate walk */
1549 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1550 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1555 current_ir_graph = rem;
1560 dump_ir_block_graph (ir_graph *irg)
1565 if (interprocedural_view) suffix = "-ip";
1567 vcg_open (irg, dump_file_suffix, suffix);
1568 dump_vcg_header(get_irg_dump_name(irg), NULL);
1570 construct_block_lists(irg);
1572 for (i = 0; i < get_irp_n_irgs(); i++) {
1573 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1575 dump_graph(get_irp_irg(i));
1583 /** dumps a graph with type information
1586 dump_ir_graph_w_types (ir_graph *irg)
1588 ir_graph *rem = current_ir_graph;
1590 current_ir_graph = irg;
1592 if (interprocedural_view) suffix = "-pure-wtypes-ip";
1593 else suffix = "-pure-wtypes";
1594 vcg_open (irg, dump_file_suffix, suffix);
1595 dump_vcg_header(get_irg_dump_name(irg), NULL);
1597 /* dump common ir graph */
1598 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1599 /* dump type info */
1600 type_walk_irg(irg, dump_type_info, NULL, NULL);
1601 inc_irg_visited(get_const_code_irg());
1602 /* dump edges from graph to type info */
1603 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1606 current_ir_graph = rem;
1610 dump_ir_block_graph_w_types (ir_graph *irg)
1614 ir_graph *rem = current_ir_graph;
1616 if (interprocedural_view) suffix = "-wtypes-ip";
1617 else suffix = "-wtypes";
1618 vcg_open (irg, dump_file_suffix, suffix);
1619 dump_vcg_header(get_irg_dump_name(irg), NULL);
1621 /* dump common blocked ir graph */
1622 construct_block_lists(irg);
1624 for (i = 0; i < get_irp_n_irgs(); i++) {
1625 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1627 dump_graph(get_irp_irg(i));
1632 /* dump type info */
1633 current_ir_graph = irg;
1634 type_walk_irg(irg, dump_type_info, NULL, NULL);
1635 inc_irg_visited(get_const_code_irg());
1637 /* dump edges from graph to type info */
1638 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1640 current_ir_graph = rem;
1644 /***********************************************************************/
1645 /* The following routines dump a control flow graph. */
1646 /***********************************************************************/
1649 dump_block_to_cfg (ir_node *block, void *env) {
1653 if (is_Block(block)) {
1654 /* This is a block. Dump a node for the block. */
1655 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1656 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1657 PRINT_NODEID(block);
1659 if (dump_dominator_information_flag)
1660 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1662 /* Dump the edges */
1663 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1664 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1665 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1666 fprintf (F, "edge: { sourcename: \"");
1667 PRINT_NODEID(block);
1668 fprintf (F, "\" targetname: \"");
1670 fprintf (F, "\"}\n");
1673 /* Dump dominator edge */
1674 if (dump_dominator_information_flag && get_Block_idom(block)) {
1675 pred = get_Block_idom(block);
1676 fprintf (F, "edge: { sourcename: \"");
1677 PRINT_NODEID(block);
1678 fprintf (F, "\" targetname: \"");
1680 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1686 dump_cfg (ir_graph *irg)
1688 ir_graph *rem = current_ir_graph;
1689 int ddif = dump_dominator_information_flag;
1690 int ipv = interprocedural_view;
1691 current_ir_graph = irg;
1693 vcg_open (irg, dump_file_suffix, "-cfg");
1694 dump_vcg_header(get_irg_dump_name(irg), NULL);
1696 if (interprocedural_view) {
1697 printf("Warning: dumping cfg not in interprocedural view!\n");
1698 interprocedural_view = 0;
1701 if (get_irg_dom_state(irg) != dom_consistent)
1702 dump_dominator_information_flag = 0;
1704 /* walk over the blocks in the graph */
1705 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1706 dump_node (get_irg_bad(irg));
1708 dump_dominator_information_flag = ddif;
1709 interprocedural_view = ipv;
1711 current_ir_graph = rem;
1716 /* Dump all irgs in interprocedural view to a single file. */
1717 void dump_all_cg_block_graph(void) {
1719 int rem_view = interprocedural_view;
1720 interprocedural_view = 1;
1722 vcg_open_name ("All_graphs", dump_file_suffix);
1723 dump_vcg_header("All_graphs", NULL);
1725 /* collect nodes in all irgs reachable in call graph*/
1726 for (i = 0; i < get_irp_n_irgs(); i++)
1727 ird_set_irg_link(get_irp_irg(i), NULL);
1729 cg_walk(clear_link, collect_node, NULL);
1731 /* dump all graphs */
1732 for (i = 0; i < get_irp_n_irgs(); i++) {
1733 current_ir_graph = get_irp_irg(i);
1734 assert(ird_get_irg_link(current_ir_graph));
1735 dump_graph(current_ir_graph);
1736 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
1740 interprocedural_view = rem_view;
1743 /***********************************************************************/
1744 /* the following routines dumps type information without any ir nodes. */
1745 /***********************************************************************/
1748 dump_type_graph (ir_graph *irg)
1751 rem = current_ir_graph;
1752 current_ir_graph = irg;
1754 vcg_open (irg, dump_file_suffix, "-type");
1755 dump_vcg_header(get_irg_dump_name(irg), NULL);
1757 /* walk over the blocks in the graph */
1758 type_walk_irg(irg, dump_type_info, NULL, NULL);
1759 /* The walker for the const code can be called several times for the
1760 same (sub) experssion. So that no nodes are dumped several times
1761 we decrease the visited flag of the corresponding graph after each
1762 walk. So now increase it finally. */
1763 inc_irg_visited(get_const_code_irg());
1766 current_ir_graph = rem;
1770 dump_all_types (void)
1772 vcg_open_name ("All_types", dump_file_suffix);
1773 dump_vcg_header("All_types", NULL);
1774 type_walk(dump_type_info, NULL, NULL);
1775 inc_irg_visited(get_const_code_irg());
1780 dump_class_hierarchy (bool entities)
1782 vcg_open_name ("class_hierarchy", dump_file_suffix);
1783 dump_vcg_header("class_hierarchy", NULL);
1785 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1787 type_walk(dump_class_hierarchy_node, NULL, NULL);
1791 /***********************************************************************/
1792 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1794 /* dump_ir_block_graph */
1796 /* dump_type_graph */
1797 /* dump_ir_graph_w_types */
1798 /***********************************************************************/
1800 void dump_all_ir_graphs (dump_graph_func *dmp_grph) {
1802 for (i=0; i < get_irp_n_irgs(); i++) {
1803 dmp_grph(get_irp_irg(i));
1808 /**********************************************************************************
1809 * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes *
1810 * packed together in one subgraph *
1811 **********************************************************************************/
1815 void dump_loops_standalone (ir_loop *loop) {
1816 int i, loop_node_started = 0, son_number = 0, first;
1819 /* Dump a new loop node. */
1820 dump_loop_node(loop);
1822 /* Dump the loop elements. */
1823 for(i = 0; i < get_loop_n_elements(loop); i++)
1825 le = get_loop_element(loop, i);
1827 ir_loop *son = le.son;
1828 if (get_kind(son) == k_ir_loop)
1830 /* We are a loop son -> Recurse */
1832 if(loop_node_started) /* Close the "firm-nodes" node first if we started one. */
1834 fprintf(F, "\" }\n");
1835 fprintf (F, "edge: {sourcename: \"");
1837 fprintf (F, "\" targetname: \"");
1839 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
1840 loop_node_started = 0;
1842 dump_loop_son_edge(loop, son_number++);
1843 dump_loops_standalone(son);
1847 /* We are a loop node -> Collect firm nodes */
1849 ir_node *n = le.node;
1851 if (!loop_node_started)
1853 /* Start a new node which contains all firm nodes of the current loop */
1854 fprintf (F, "node: { title: \"");
1856 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
1857 loop_node_started = 1;
1863 dump_node_opcode(n);
1865 dump_node_typeinfo(n);
1867 dump_node_nodeattr(n);
1868 fprintf (F, " %ld", get_irn_node_nr(n));
1872 if(loop_node_started)
1874 fprintf(F, "\" }\n");
1875 fprintf (F, "edge: {sourcename: \"");
1877 fprintf (F, "\" targetname: \"");
1879 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
1880 loop_node_started = 0;
1884 void dump_loop_tree(ir_graph *irg, char *suffix)
1886 ir_graph *rem = current_ir_graph;
1887 int el_rem = edge_label;
1890 current_ir_graph = irg;
1892 vcg_open(irg, suffix, "-looptree");
1893 dump_vcg_header(get_irg_dump_name(irg), "top_to_bottom");
1895 if (get_irg_loop(irg)) dump_loops_standalone(get_irg_loop(irg));
1899 edge_label = el_rem;
1900 current_ir_graph = rem;
1904 /*******************************************************************************/
1905 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
1906 /*******************************************************************************/
1908 void collect_nodeloop(ir_loop *loop, eset *loopnodes) {
1909 int i, son_number = 0, node_number = 0;
1911 if (dump_loop_information_flag) dump_loop_node(loop);
1913 for (i = 0; i < get_loop_n_elements(loop); i++) {
1914 loop_element le = get_loop_element(loop, i);
1915 if (*(le.kind) == k_ir_loop) {
1916 if (dump_loop_information_flag) dump_loop_son_edge(loop, son_number++);
1918 collect_nodeloop(le.son, loopnodes);
1920 if (dump_loop_information_flag) dump_loop_node_edge(loop, node_number++);
1921 eset_insert(loopnodes, le.node);
1926 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
1929 for(i = 0; i < get_loop_n_elements(loop); i++) {
1930 loop_element le = get_loop_element(loop, i);
1931 if (*(le.kind) == k_ir_loop) {
1933 collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
1935 if (is_Block(le.node)) start = 0; else start = -1;
1936 for (j = start; j < get_irn_arity(le.node); j++) {
1937 ir_node *pred = get_irn_n(le.node, j);
1938 if (!eset_contains(loopnodes, pred)) {
1939 eset_insert(extnodes, pred);
1940 if (!is_Block(pred)) {
1941 pred = get_nodes_block(pred);
1942 if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
1950 void dump_loop (ir_loop *l, char *suffix) {
1952 eset *loopnodes = eset_create();
1953 eset *extnodes = eset_create();
1956 sprintf(name, "loop_%d", get_loop_loop_nr(l));
1957 vcg_open_name (name, suffix);
1958 dump_vcg_header(name, NULL);
1960 /* collect all nodes to dump */
1961 collect_nodeloop(l, loopnodes);
1962 collect_nodeloop_external_nodes(l, loopnodes, extnodes);
1964 /* build block lists */
1965 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
1966 set_irn_link(n, NULL);
1967 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
1968 set_irn_link(n, NULL);
1969 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
1971 b = get_nodes_block(n);
1972 set_irn_link(n, get_irn_link(b));
1975 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
1977 b = get_nodes_block(n);
1978 set_irn_link(n, get_irn_link(b));
1982 for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
1984 fprintf(F, "graph: { title: \"");
1986 fprintf(F, "\" label: \"");
1987 dump_node_opcode(b);
1988 fprintf (F, " %ld", get_irn_node_nr(b));
1989 fprintf(F, "\" status:clustered color:yellow\n");
1991 /* dump the blocks edges */
1992 dump_ir_data_edges(b);
1994 /* dump the nodes that go into the block */
1995 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
1996 if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
1998 overrule_nodecolor = NULL;
1999 if (!eset_contains(extnodes, n)) dump_ir_data_edges(n);
2002 /* Close the vcg information for the block */
2004 dump_const_node_local(b);
2007 for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2009 fprintf(F, "graph: { title: \"");
2011 fprintf(F, "\" label: \"");
2012 dump_node_opcode(b);
2013 fprintf (F, " %ld", get_irn_node_nr(b));
2014 fprintf(F, "\" status:clustered color:lightblue\n");
2016 /* dump the nodes that go into the block */
2017 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2018 if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2020 overrule_nodecolor = NULL;
2021 if (eset_contains(loopnodes, n)) dump_ir_data_edges(n);
2024 /* Close the vcg information for the block */
2026 dump_const_node_local(b);
2030 eset_destroy(loopnodes);
2031 eset_destroy(extnodes);