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.
18 #include "firm_common_t.h"
21 #include "irgraph_t.h"
32 #include "type_or_entity.h"
36 #include "callgraph.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 /* basis for a color range for vcg */
54 static int n_colors = 0;
55 static int base_color = 0;
57 static const char *get_mode_name_ex(ir_mode *mode, int *bad)
60 return get_mode_name(mode);
65 static const char *get_type_name_ex(type *tp, int *bad)
68 return get_type_name(tp);
73 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
78 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
79 fprintf(F, " targetname: "); PRINT_TYPEID(T);
85 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
90 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
91 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
97 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, const char *fmt, ...)
103 fprintf(F, "backedge: { sourcename: \"");
105 fprintf(F, "edge: { sourcename: \"");
107 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
108 vfprintf(F, fmt, ap);
113 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
118 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
119 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
120 vfprintf(F, fmt, ap);
125 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
130 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
131 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
132 vfprintf(F, fmt, ap);
137 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
142 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
143 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
145 vfprintf(F, fmt, ap);
150 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
155 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
156 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
157 vfprintf(F, fmt, ap);
162 static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...)
167 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(E);
168 fprintf(F, " targetname: \""); PRINT_ITEMID(E, item); fprintf(F, "\" ");
169 vfprintf(F, fmt, ap);
174 /*******************************************************************/
175 /* global and ahead declarations */
176 /*******************************************************************/
178 static void dump_whole_node(ir_node *n, void *env);
179 static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
181 /*******************************************************************/
182 /* Helper functions. */
183 /*******************************************************************/
185 /* Use private link attr to be able to call dumper anywhere without
186 destroying link fields. */
188 static pmap *irdump_link_map = NULL;
190 static void init_irdump(void) {
191 /* We need a new, empty map. */
192 if (irdump_link_map) pmap_destroy(irdump_link_map);
193 irdump_link_map = pmap_create();
197 void *ird_get_irn_link(ir_node *n) {
199 if (!irdump_link_map) return NULL;
201 if (pmap_contains(irdump_link_map, (void *)n))
202 res = pmap_get(irdump_link_map, (void *)n);
206 void ird_set_irn_link(ir_node *n, void *x) {
207 if (!irdump_link_map) init_irdump();
208 pmap_insert(irdump_link_map, (void *)n, x);
211 void *ird_get_irg_link(ir_graph *irg) {
213 if (!irdump_link_map) return NULL;
215 if (pmap_contains(irdump_link_map, (void *)irg))
216 res = pmap_get(irdump_link_map, (void *)irg);
220 void ird_set_irg_link(ir_graph *irg, void *x) {
221 if (!irdump_link_map) init_irdump();
222 pmap_insert(irdump_link_map, (void *)irg, x);
225 static void clear_link(ir_node * node, void * env) {
226 ird_set_irn_link(node, NULL);
230 static int node_floats(ir_node *n) {
231 return ((get_irn_pinned(n) == op_pin_state_floats) &&
232 (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
235 const char *get_ent_dump_name(entity *ent) {
237 return "<NULL entity>";
238 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
239 if (ent->ld_name) return get_id_str(ent->ld_name);
240 return get_id_str(ent->name);
243 const char *get_irg_dump_name(ir_graph *irg) {
244 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
245 entity *ent = get_irg_entity(irg);
246 return get_ent_dump_name(ent);
249 static void collect_node(ir_node * node, void *env) {
252 || get_irn_op(node) == op_Bad
253 || get_irn_op(node) == op_Unknown
254 || get_irn_op(node) == op_NoMem) {
255 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
256 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
257 ARR_APP1(ir_node *, arr, node);
258 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
260 ir_node * block = get_nodes_block(node);
261 ird_set_irn_link(node, ird_get_irn_link(block));
262 ird_set_irn_link(block, node);
266 /** Construct lists to walk ir block-wise.
268 * Collects all blocks, nodes not op_pin_state_pinned,
269 * Bad, NoMem and Unknown into a flexible array in link field of
270 * irg they belong to. Sets the irg link field to NULL in all
271 * graphs not visited.
272 * Free the list with DEL_ARR_F. */
273 static ir_node ** construct_block_lists(ir_graph *irg) {
274 int i, rem_view = get_interprocedural_view();
275 ir_graph *rem = current_ir_graph;
276 current_ir_graph = irg;
278 for (i = 0; i < get_irp_n_irgs(); i++)
279 ird_set_irg_link(get_irp_irg(i), NULL);
281 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
283 /* Collect also EndReg and EndExcept. We do not want to change the walker. */
284 set_interprocedural_view(false);
285 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
286 irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
287 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
288 irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
289 set_interprocedural_view(rem_view);
291 current_ir_graph = rem;
292 return ird_get_irg_link(irg);
295 /*******************************************************************/
296 /* flags to steer output */
297 /*******************************************************************/
299 const char *dump_file_filter = "";
301 /* A compiler option to turn off edge labels */
303 /* A compiler option to turn off dumping values of constant entities */
304 int const_entities = 1;
305 /* A compiler option to dump the keep alive edges */
306 int dump_keepalive = 0;
307 /* Compiler options to dump analysis information in dump_ir_graph */
308 int dump_out_edge_flag = 0;
309 int dump_dominator_information_flag = 0;
310 int dump_loop_information_flag = 0;
311 int dump_backedge_information_flag = 1;
312 int dump_const_local = 0;
313 bool opt_dump_analysed_type_info = 1;
314 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
316 char* overrule_nodecolor = NULL;
318 INLINE bool get_opt_dump_const_local(void) {
319 if (!dump_out_edge_flag && !dump_loop_information_flag)
320 return dump_const_local;
325 void only_dump_method_with_name(ident *name) {
326 dump_file_filter = get_id_str(name);
330 /* To turn off display of edge labels. Edge labels offen cause xvcg to
331 abort with a segmentation fault. */
332 void turn_off_edge_labels(void) {
336 void dump_consts_local(bool b) {
337 dump_const_local = b;
340 void turn_off_constant_entity_values(void) {
344 void dump_keepalive_edges(bool b) {
348 bool get_opt_dump_keepalive_edges(void) {
349 return dump_keepalive;
352 void dump_out_edges(void) {
353 dump_out_edge_flag = 1;
356 void dump_dominator_information(void) {
357 dump_dominator_information_flag = 1;
360 void dump_loop_information(void) {
361 dump_loop_information_flag = 1;
364 void dont_dump_loop_information(void) {
365 dump_loop_information_flag = 0;
368 void dump_backedge_information(bool b) {
369 dump_backedge_information_flag = b;
372 /* Dump the information of type field specified in ana/irtypeinfo.h.
373 * If the flag is set, the type name is output in [] in the node label,
374 * else it is output as info.
376 void dump_analysed_type_info(bool b) {
377 opt_dump_analysed_type_info = b;
380 void dump_pointer_values_to_info(bool b) {
381 opt_dump_pointer_values_to_info = b;
384 /*-----------------------------------------------------------------*/
385 /* Routines to dump information about a single ir node. */
386 /*-----------------------------------------------------------------*/
389 dump_node_opcode(FILE *F, ir_node *n)
393 switch(get_irn_opcode(n)) {
398 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
399 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
404 if (get_SymConst_kind(n) == symconst_addr_name) {
405 /* don't use get_SymConst_ptr_info as it mangles the name. */
406 fprintf (F, "SymC %s", get_id_str(get_SymConst_name(n)));
407 } else if (get_SymConst_kind(n) == symconst_addr_ent) {
408 assert(get_SymConst_entity(n));
409 assert(is_entity(get_SymConst_entity(n)));
410 fprintf (F, "SymC &%s", get_entity_name(get_SymConst_entity(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_ex(get_SymConst_type(n), &bad));
415 if (get_SymConst_kind(n) == symconst_type_tag)
423 if (!get_interprocedural_view())
430 ir_node *pred = get_Proj_pred(n);
432 if (get_irn_opcode(pred) == iro_Cond
433 && get_Proj_proj(n) == get_Cond_defaultProj(pred)
434 && get_irn_mode(get_Cond_selector(pred)) != mode_b)
435 fprintf (F, "defProj");
437 * else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
438 * fprintf (F, "Arg");
447 if (get_interprocedural_view()) {
448 fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_entity(get_irn_irg(n))));
453 case iro_CallBegin: {
454 ir_node *addr = get_CallBegin_ptr(n);
456 if (get_irn_op(addr) == op_Sel)
457 ent = get_Sel_entity(addr);
458 else if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind(addr) == symconst_addr_ent))
459 ent = get_SymConst_entity(addr);
460 fprintf (F, "%s", get_irn_opname(n));
461 if (ent) fprintf (F, " %s", get_entity_name(ent));
465 fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
470 fprintf (F, "%s", get_irn_opname(n));
478 dump_node_mode(FILE *F, ir_node *n)
481 opcode iro = get_irn_opcode(n);
494 ir_mode *mode = get_irn_mode(n);
496 if (mode && mode != mode_BB && mode != mode_ANY && mode != mode_BAD &&
497 (mode != mode_T || iro == iro_Proj))
498 fprintf(F, "%s", get_mode_name_ex(mode, &bad));
505 static int dump_node_typeinfo(FILE *F, ir_node *n) {
508 if (opt_dump_analysed_type_info) {
509 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
510 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent) {
511 type *tp = get_irn_typeinfo_type(n);
513 fprintf(F, " [%s]", get_type_name_ex(tp, &bad));
522 dump_node_nodeattr(FILE *F, ir_node *n)
526 switch (get_irn_opcode(n)) {
528 if (false && get_interprocedural_view()) {
529 fprintf (F, "%s", get_ent_dump_name(get_irg_entity(current_ir_graph)));
533 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
534 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
536 fprintf (F, "%ld", get_Proj_proj(n));
540 fprintf (F, "%ld", get_Filter_proj(n));
543 fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
546 fprintf (F, "(%s)", get_type_name_ex(get_Cast_type(n), &bad));
549 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
559 static INLINE void dump_node_vcgattr(FILE *F, ir_node *n, int bad)
562 fprintf(F, "color: red");
565 switch (get_irn_opcode(n)) {
572 fprintf (F, "color: blue");
575 fprintf (F, "color: lightyellow");
578 fprintf (F, "color: green");
584 fprintf (F, "color: yellow");
587 PRINT_DEFAULT_NODE_ATTR;
590 if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
593 static INLINE int dump_node_info(FILE *F, ir_node *n)
599 fprintf (F, " info1: \"");
600 if (opt_dump_pointer_values_to_info)
601 fprintf (F, "addr: %p \n", (void *)n);
602 fprintf (F, "mode: %s\n", get_mode_name(get_irn_mode(n)));
603 fprintf (F, "visited: %ld \n", get_irn_visited(n));
604 irg = get_irn_irg(n);
605 if (irg != get_const_code_irg())
606 fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
608 if (get_irn_pinned(n) == op_pin_state_floats &&
609 get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
610 fprintf(F, "node was pinned in ");
611 dump_node_opcode(F, get_nodes_block(n));
612 fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
616 /* show all predecessor nodes */
617 fprintf(F, "pred nodes: \n");
620 dump_node_opcode(F, get_nodes_block(n));
621 fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
623 for ( i = 0; i < get_irn_arity(n); ++i) {
624 fprintf(F, " %d: ", i);
625 dump_node_opcode(F, get_irn_n(n, i));
626 fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
630 fprintf(F, "arity: %d", get_irn_arity(n));
631 if ((get_irn_op(n) == op_Block) ||
632 (get_irn_op(n) == op_Phi) ||
633 ((get_irn_op(n) == op_Filter) && get_interprocedural_view())) {
634 fprintf(F, " backedges:");
636 for (i = 0; i < get_irn_arity(n); i++)
637 if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
641 /* Loop node Someone else please tell me what's wrong ...
642 if (get_irn_loop(n)) {
643 ir_loop *loop = get_irn_loop(n);
645 fprintf(F, " in loop %d with depth %d\n",
646 get_loop_loop_nr(loop), get_loop_depth(loop));
651 switch (get_irn_opcode(n)) {
653 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
654 fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
655 for (i = 0; i < get_method_n_params(tp); ++i)
656 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
657 if ((get_irp_ip_view_state() == ip_view_valid) && !get_interprocedural_view()) {
658 ir_node *sbl = get_nodes_block(n);
659 int i, n_cfgpreds = get_Block_cg_n_cfgpreds(sbl);
660 fprintf(F, "graph has %d interprocedural predecessors:\n", n_cfgpreds);
661 for (i = 0; i < n_cfgpreds; ++i) {
662 ir_node *cfgpred = get_Block_cg_cfgpred(sbl, i);
663 fprintf(F, " %d: Call %ld in graph %s\n", i, get_irn_node_nr(cfgpred),
664 get_irg_dump_name(get_irn_irg(cfgpred)));
669 fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
672 fprintf(F, "freeing entity of type %s \n", get_type_name_ex(get_Free_type(n), &bad));
675 entity *ent = get_Sel_entity(n);
678 fprintf(F, "Selecting entity of type %s\n", get_type_name_ex(get_entity_type(ent), &bad));
679 fprintf(F, " from entity of type %s\n", get_type_name_ex(get_entity_owner(ent), &bad));
682 fprintf(F, "<NULL entity>\n");
687 type *tp = get_Call_type(n);
688 fprintf(F, "calling method of type %s \n", get_type_name_ex(tp, &bad));
689 if(get_unknown_type() != tp) {
690 for (i = 0; i < get_method_n_params(tp); ++i)
691 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
692 for (i = 0; i < get_method_n_ress(tp); ++i)
693 fprintf(F, " resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
695 if (Call_has_callees(n)) {
696 fprintf(F, "possible callees: \n");
697 for (i = 0; i < get_Call_n_callees(n); i++) {
698 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
702 case iro_CallBegin: {
703 ir_node *call = get_CallBegin_call(n);
704 fprintf(F, "Call: %ld\n", get_irn_node_nr(call));
705 if (Call_has_callees(call)) {
706 fprintf(F, "possible callees: \n");
707 for (i = 0; i < get_Call_n_callees(call); i++) {
708 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
713 if (!get_interprocedural_view()) {
714 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
715 fprintf(F, "return in method of type %s \n", get_type_name_ex(tp, &bad));
716 for (i = 0; i < get_method_n_ress(tp); ++i)
717 fprintf(F, " res %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
721 type *tp = get_Const_type(n);
722 assert(tp != none_type);
723 fprintf(F, "Const of type %s \n", get_type_name_ex(get_Const_type(n), &bad));
726 switch(get_SymConst_kind(n)) {
727 case symconst_addr_name:
728 fprintf(F, "kind addr_name\n");
730 case symconst_addr_ent:
731 fprintf(F, "kind addr_ent\n");
732 dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames);
734 case symconst_type_tag:
735 fprintf(F, "kind type_tag\n");
738 fprintf(F, "kind size\n");
741 fprintf(F, "SymConst of type %s \n", get_type_name_ex(get_SymConst_value_type(n), &bad));
745 if (get_interprocedural_view()) {
746 fprintf(F, "intra predecessor nodes:\n");
747 for (i = 0; i < get_irn_intra_arity(n); i++) {
748 ir_node *pred = get_irn_intra_n(n, i);
749 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
752 fprintf(F, "inter predecessor nodes:\n");
753 for (i = 0; i < get_irn_inter_arity(n); i++) {
754 ir_node *pred = get_irn_inter_n(n, i);
755 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
756 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
761 fprintf(F, "volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
764 fprintf(F, "volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
770 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
771 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
772 if (get_irn_typeinfo_type(n) != none_type)
773 fprintf (F, "\nAnalysed type: %s", get_type_name_ex(get_irn_typeinfo_type(n), &bad));
781 * checks wheater a node is "constant-like", ie can be treated "block-less"
784 bool is_constlike_node(ir_node *n) {
785 ir_op *op = get_irn_op(n);
786 return (op == op_Const || op == op_Bad || op == op_NoMem || op == op_SymConst || op == op_Unknown);
790 /* outputs the predecessors of n, that are constants, local. I.e.,
791 generates a copy of the constant predecessors for each node called with. */
792 static void dump_const_node_local(FILE *F, ir_node *n) {
794 if (!get_opt_dump_const_local()) return;
796 /* Use visited flag to avoid outputting nodes twice.
797 initialize it first. */
798 for (i = 0; i < get_irn_arity(n); i++) {
799 ir_node *con = get_irn_n(n, i);
800 if (is_constlike_node(con)) {
801 set_irn_visited(con, get_irg_visited(current_ir_graph) - 1);
805 for (i = 0; i < get_irn_arity(n); i++) {
806 ir_node *con = get_irn_n(n, i);
807 if (is_constlike_node(con) && irn_not_visited(con)) {
810 mark_irn_visited(con);
811 /* Generate a new name for the node by appending the names of
813 fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
814 fprintf(F, " label: \"");
815 bad |= dump_node_opcode(F, con);
816 bad |= dump_node_mode(F, con);
817 bad |= dump_node_typeinfo(F, con);
819 bad |= dump_node_nodeattr(F, con);
820 fprintf(F, " %ld", get_irn_node_nr(con));
822 bad |= dump_node_info(F, con);
823 dump_node_vcgattr(F, con, bad);
829 static void INLINE print_node_error(FILE *F, const char *p)
834 fprintf (F, " info2: \"%s\"", p);
837 static void dump_node(FILE *F, ir_node *n)
842 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
844 fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
846 bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
847 bad |= dump_node_opcode(F, n);
848 bad |= dump_node_mode(F, n);
849 bad |= dump_node_typeinfo(F, n);
851 bad |= dump_node_nodeattr(F, n);
852 fprintf(F, " %ld", get_irn_node_nr(n));
854 bad |= dump_node_info(F, n);
855 print_node_error(F, p);
856 dump_node_vcgattr(F, n, bad);
858 dump_const_node_local(F, n);
865 /* dump the edge to the block this node belongs to */
867 dump_ir_block_edge(FILE *F, ir_node *n) {
868 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
869 if (is_no_Block(n)) {
870 ir_node *block = get_nodes_block(n);
872 fprintf (F, "edge: { sourcename: \"");
874 fprintf (F, "\" targetname: ");
875 fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
876 fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
881 print_data_edge_vcgattr(FILE *F, ir_node *from, int to) {
882 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
883 fprintf (F, INTRA_DATA_EDGE_ATTR);
885 fprintf (F, INTER_DATA_EDGE_ATTR);
889 print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) {
890 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
891 fprintf (F, INTRA_MEM_EDGE_ATTR);
893 fprintf (F, INTER_MEM_EDGE_ATTR);
897 print_edge_vcgattr(FILE *F, ir_node *from, int to) {
900 if (dump_backedge_information_flag && is_backedge(from, to))
901 fprintf (F, BACK_EDGE_ATTR);
903 switch (get_irn_opcode(from)) {
905 fprintf (F, CF_EDGE_ATTR);
907 case iro_Start: break;
910 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
911 fprintf (F, CF_EDGE_ATTR);
912 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
913 fprintf (F, INTER_MEM_EDGE_ATTR);
921 print_data_edge_vcgattr(F, from, to);
926 print_mem_edge_vcgattr(F, from, to);
928 print_data_edge_vcgattr(F, from, to);
932 print_data_edge_vcgattr(F, from, to);
937 print_mem_edge_vcgattr(F, from, to);
939 print_data_edge_vcgattr(F, from, to);
946 print_data_edge_vcgattr(F, from, to);
953 print_mem_edge_vcgattr(F, from, to);
955 print_data_edge_vcgattr(F, from, to);
967 print_data_edge_vcgattr(F, from, to);
970 if (get_irn_modecode(from) == irm_M)
971 fprintf (F, INTER_MEM_EDGE_ATTR);
973 print_data_edge_vcgattr(F, from, to);
980 print_mem_edge_vcgattr(F, from, to);
982 print_data_edge_vcgattr(F, from, to);
985 print_mem_edge_vcgattr(F, from, to);
987 case iro_Tuple: break;
990 switch (get_irn_modecode(from)) {
992 fprintf (F, CF_EDGE_ATTR);
995 fprintf (F, INTER_MEM_EDGE_ATTR);
998 print_data_edge_vcgattr(F, from, to);
1002 case iro_Bad: break;
1003 case iro_Unknown: break;
1005 switch (get_irn_modecode(from)) {
1007 fprintf (F, INTRA_MEM_EDGE_ATTR);
1010 fprintf (F, CF_EDGE_ATTR);
1013 print_data_edge_vcgattr(F, from, to);
1021 /* dump edges to our inputs */
1023 dump_ir_data_edges(FILE *F, ir_node *n) {
1024 int i, visited = get_irn_visited(n);
1026 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
1029 for (i = 0; i < get_irn_arity(n); i++) {
1030 ir_node * pred = get_irn_n(n, i);
1033 if ((get_interprocedural_view() && get_irn_visited(pred) < visited))
1034 continue; /* pred not dumped */
1036 if (dump_backedge_information_flag && is_backedge(n, i))
1037 fprintf (F, "backedge: {sourcename: \"");
1039 fprintf (F, "edge: {sourcename: \"");
1041 fprintf (F, "\" targetname: ");
1042 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
1043 PRINT_CONSTID(n, pred);
1045 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
1047 fprintf (F, " label: \"%d\" ", i);
1048 print_edge_vcgattr(F, n, i);
1053 /** Dumps a node and its edges but not the block edge
1056 dump_node_wo_blockedge (ir_node *n, void *env) {
1059 dump_ir_data_edges(F, n);
1062 /** Dumps a node and its edges.
1065 dump_whole_node (ir_node *n, void *env) {
1067 dump_node_wo_blockedge(n, env);
1068 if (!node_floats(n)) dump_ir_block_edge(F, n);
1072 dump_const_node(ir_node *n, void *env) {
1073 if (is_Block(n)) return;
1074 dump_node_wo_blockedge(n, env);
1077 /***********************************************************************/
1078 /* the following routines dump the nodes/irgs bracketed to graphs. */
1079 /***********************************************************************/
1081 /** Dumps a constant expression as entity initializer, array bound ...
1083 static void dump_const_expression(FILE *F, ir_node *value) {
1084 ir_graph *rem = current_ir_graph;
1085 int rem_dump_const_local = dump_const_local;
1086 dump_const_local = 0;
1087 current_ir_graph = get_const_code_irg();
1088 irg_walk(value, dump_const_node, NULL, F);
1089 /* Decrease visited flag so that we walk with the same flag for the next
1090 expresssion. This guarantees that we don't dump the same node twice,
1091 as for const expressions cse is performed to save memory. */
1092 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
1093 current_ir_graph = rem;
1094 dump_const_local = rem_dump_const_local;
1097 /** Dump a block as graph containing its nodes.
1099 * Expects to find nodes belonging to the block as list in its
1101 * Dumps the edges of all nodes including itself. */
1103 dump_whole_block(FILE *F, ir_node *block) {
1105 assert(is_Block(block));
1107 fprintf(F, "graph: { title: \"");
1108 PRINT_NODEID(block);
1109 fprintf(F, "\" label: \"");
1110 dump_node_opcode(F, block);
1111 fprintf (F, " %ld", get_irn_node_nr(block));
1113 if (get_opt_dump_abstvals())
1114 fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
1116 fprintf(F, "\" status:clustered color:%s \n",
1117 get_Block_matured(block) ? "yellow" : "red");
1119 /* dump the blocks edges */
1120 dump_ir_data_edges(F, block);
1122 /* dump the nodes that go into the block */
1123 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
1125 dump_ir_data_edges(F, node);
1128 /* Close the vcg information for the block */
1130 dump_const_node_local(F, block);
1132 dump_chi_term(F, block);
1137 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
1138 * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */
1140 dump_block_graph(FILE *F, ir_graph *irg) {
1142 ir_graph *rem = current_ir_graph;
1143 ir_node **arr = ird_get_irg_link(irg);
1144 current_ir_graph = irg;
1146 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1147 ir_node * node = arr[i];
1148 if (is_Block(node)) {
1149 /* Dumps the block and all the nodes in the block, which are to
1150 be found in Block->link. */
1151 dump_whole_block(F, node);
1153 /* Nodes that are not in a Block. */
1155 dump_ir_data_edges(F, node);
1159 if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
1160 dump_loop_nodes_into_graph(F, irg);
1162 current_ir_graph = rem;
1165 /** Dumps an irg as a graph.
1166 * If interprocedural view edges can point to nodes out of this graph.
1168 static void dump_graph(FILE *F, ir_graph *irg) {
1170 fprintf(F, "graph: { title: \"");
1172 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
1173 get_ent_dump_name(get_irg_entity(irg)));
1175 dump_block_graph(F, irg);
1177 /* Close the vcg information for the irg */
1178 fprintf(F, "}\n\n");
1181 /*******************************************************************/
1182 /* Basic type and entity nodes and edges. */
1183 /*******************************************************************/
1185 /** dumps the edges between nodes and their type or entity attributes. */
1186 static void dump_node2type_edges(ir_node *n, void *env)
1191 switch (get_irn_opcode(n)) {
1193 /* @@@ some consts have an entity */
1196 if ( (get_SymConst_kind(n) ==symconst_type_tag)
1197 || (get_SymConst_kind(n) ==symconst_size))
1199 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1203 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1206 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1209 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1212 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1215 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1223 static int print_type_info(FILE *F, type *tp) {
1226 if (get_type_state(tp) == layout_undefined) {
1227 fprintf(F, "state: layout_undefined\n");
1229 fprintf(F, "state: layout_fixed,\n");
1231 if (get_type_mode(tp))
1232 fprintf(F, "mode: %s,\n", get_mode_name_ex(get_type_mode(tp), &bad));
1233 fprintf(F, "size: %db,\n", get_type_size_bits(tp));
1238 static void print_typespecific_info(FILE *F, type *tp) {
1239 switch (get_type_tpop_code(tp)) {
1242 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1249 fprintf(F, "variadicity: %s\n", get_variadicity_name(get_method_variadicity(tp)));
1250 fprintf(F, "params: %d\n", get_method_n_params(tp));
1251 fprintf(F, "results: %d\n", get_method_n_ress(tp));
1259 case tpo_enumeration:
1273 static void print_typespecific_vcgattr(FILE *F, type *tp) {
1274 switch (get_type_tpop_code(tp)) {
1277 if (peculiarity_existent == get_class_peculiarity(tp))
1278 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1280 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1284 fprintf (F, " " TYPE_METH_NODE_ATTR);
1295 case tpo_enumeration:
1308 static int print_type_node(FILE *F, type *tp)
1312 fprintf (F, "node: {title: ");
1314 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
1315 fprintf (F, " info1: \"");
1316 bad |= print_type_info(F, tp);
1317 print_typespecific_info(F, tp);
1319 print_typespecific_vcgattr(F, tp);
1325 #define X(a) case a: fprintf(F, #a); break
1326 void dump_entity_node(FILE *F, entity *ent, int color)
1328 fprintf (F, "node: {title: \"");
1329 PRINT_ENTID(ent); fprintf(F, "\"");
1330 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1331 fprintf (F, "label: ");
1332 fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
1334 fprintf(F, "color: %d", color);
1336 fprintf (F, ENTITY_NODE_ATTR);
1337 fprintf (F, "\n info1: \"");
1339 dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
1341 fprintf(F, "\"\n}\n");
1345 static void dump_enum_item(FILE *F, type *tp, int pos)
1348 ident *id = get_enumeration_nameid(tp, pos);
1349 tarval *tv = get_enumeration_enum(tp, pos);
1351 tarval_snprintf(buf, sizeof(buf), tv);
1352 fprintf (F, "node: {title: \"");
1353 PRINT_ITEMID(tp, pos); fprintf(F, "\"");
1354 fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE);
1355 fprintf (F, "label: ");
1356 fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id));
1357 fprintf (F, "\n info1: \"value: %s\"}\n", buf);
1360 /* dumps a type or entity and it's edges. */
1362 dump_type_info(type_or_ent *tore, void *env) {
1364 int i = 0; /* to shutup gcc */
1366 /* dump this type or entity */
1368 switch (get_kind(tore)) {
1371 entity *ent = (entity *)tore;
1374 dump_entity_node(F, ent, 0);
1376 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1377 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1378 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1379 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1380 if(is_class_type(get_entity_owner(ent))) {
1381 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1382 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, ENT_OVERWRITES_EDGE_ATTR);
1384 /* attached subgraphs */
1385 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1386 if (is_atomic_entity(ent)) {
1387 value = get_atomic_ent_value(ent);
1389 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1390 /* DDMN(value); $$$ */
1391 dump_const_expression(F, value);
1394 if (is_compound_entity(ent)) {
1395 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1396 value = get_compound_ent_value(ent, i);
1398 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1399 dump_const_expression(F, value);
1400 print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, ENT_CORR_EDGE_ATTR, i);
1402 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1403 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1404 get_compound_ent_value_member(ent, i), i);
1413 type *tp = (type *)tore;
1414 print_type_node(F, tp);
1415 /* and now the edges */
1416 switch (get_type_tpop_code(tp)) {
1419 for (i=0; i < get_class_n_supertypes(tp); i++)
1420 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1421 for (i=0; i < get_class_n_members(tp); i++)
1422 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1426 for (i=0; i < get_struct_n_members(tp); i++)
1427 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1431 for (i = 0; i < get_method_n_params(tp); i++)
1432 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1433 for (i = 0; i < get_method_n_ress(tp); i++)
1434 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1438 for (i = 0; i < get_union_n_members(tp); i++)
1439 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1443 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1444 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1445 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1446 ir_node *upper = get_array_upper_bound(tp, i);
1447 ir_node *lower = get_array_lower_bound(tp, i);
1448 print_node_type_edge(F, upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1449 print_node_type_edge(F, lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1450 dump_const_expression(F, upper);
1451 dump_const_expression(F, lower);
1455 case tpo_enumeration:
1457 for (i = 0; i < get_enumeration_n_enums(tp); ++i) {
1458 dump_enum_item(F, tp, i);
1459 print_enum_item_edge(F, tp, i, "label: \"item %d\"", i);
1464 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1472 break; /* case k_type */
1475 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1477 } /* switch kind_or_entity */
1480 typedef struct _h_env {
1485 /** For dumping class hierarchies.
1486 * Dumps a class type node and a superclass edge.
1487 * If env->dump_ent dumps entities of classes and overwrites edges.
1490 dump_class_hierarchy_node (type_or_ent *tore, void *ctx) {
1493 int i = 0; /* to shutup gcc */
1495 /* dump this type or entity */
1496 switch (get_kind(tore)) {
1498 entity *ent = (entity *)tore;
1499 if (get_entity_owner(ent) == get_glob_type()) break;
1500 if (!is_method_type(get_entity_type(ent))) break; /* GL */
1501 if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
1503 dump_entity_node(F, ent, 0);
1505 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1506 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1507 print_ent_ent_edge(F, get_entity_overwrites(ent, i), ent, 0, ENT_OVERWRITES_EDGE_ATTR);
1509 } break; /* case k_entity */
1512 type *tp = (type *)tore;
1513 if (tp == get_glob_type()) break;
1514 switch (get_type_tpop_code(tp)) {
1516 print_type_node(F, tp);
1517 /* and now the edges */
1518 for (i=0; i < get_class_n_supertypes(tp); i++)
1520 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1526 break; /* case k_type */
1529 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1531 } /* switch kind_or_entity */
1534 /*******************************************************************/
1535 /* dump analysis information that is expressed in graph terms. */
1536 /*******************************************************************/
1538 /* dump out edges */
1540 dump_out_edge(ir_node *n, void *env) {
1543 for (i = 0; i < get_irn_n_outs(n); i++) {
1544 assert(get_irn_out(n, i));
1545 fprintf (F, "edge: {sourcename: \"");
1547 fprintf (F, "\" targetname: \"");
1548 PRINT_NODEID(get_irn_out(n, i));
1549 fprintf (F, "\" color: red linestyle: dashed");
1555 dump_loop_label(FILE *F, ir_loop *loop) {
1556 fprintf (F, "loop %d, %d sons, %d nodes",
1557 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1560 static INLINE void dump_loop_info(FILE *F, ir_loop *loop) {
1561 fprintf (F, " info1: \"");
1562 fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1563 #if DEBUG_libfirm /* GL @@@ debug analyses */
1564 fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1570 dump_loop_node(FILE *F, ir_loop *loop) {
1571 fprintf (F, "node: {title: \"");
1573 fprintf (F, "\" label: \"");
1574 dump_loop_label(F, loop);
1576 dump_loop_info(F, loop);
1582 dump_loop_node_edge(FILE *F, ir_loop *loop, int i) {
1584 fprintf (F, "edge: {sourcename: \"");
1586 fprintf (F, "\" targetname: \"");
1587 PRINT_NODEID(get_loop_node(loop, i));
1588 fprintf (F, "\" color: green");
1593 dump_loop_son_edge(FILE *F, ir_loop *loop, int i) {
1595 fprintf (F, "edge: {sourcename: \"");
1597 fprintf (F, "\" targetname: \"");
1598 PRINT_LOOPID(get_loop_son(loop, i));
1599 fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1600 get_loop_element_pos(loop, get_loop_son(loop, i)));
1604 void dump_loops(FILE *F, ir_loop *loop) {
1606 /* dump this loop node */
1607 dump_loop_node(F, loop);
1609 /* dump edges to nodes in loop -- only if it is a real loop */
1610 if (get_loop_depth(loop) != 0) {
1611 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1612 dump_loop_node_edge(F, loop, i);
1615 for (i = 0; i < get_loop_n_sons(loop); i++) {
1616 dump_loops(F, get_loop_son(loop, i));
1617 dump_loop_son_edge(F, loop, i);
1622 void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) {
1623 ir_graph *rem = current_ir_graph;
1624 current_ir_graph = irg;
1626 if (get_irg_loop(irg)) dump_loops(F, get_irg_loop(irg));
1628 current_ir_graph = rem;
1633 * dumps the VCG header
1635 INLINE void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
1644 if (!orientation) orientation = "bottom_to_top";
1648 "graph: { title: \"ir graph of %s\"\n"
1649 "display_edge_labels: %s\n"
1650 "layoutalgorithm: mindepth\n"
1651 "manhattan_edges: yes\n"
1652 "port_sharing: no\n"
1654 "classname 1: \"intrablock Data\"\n"
1655 "classname 16: \"interblock Data\"\n"
1656 "classname 2: \"Block\"\n"
1657 "classname 13: \"Control Flow\"\n"
1658 "classname 18: \"Exception Control Flow for Interval Analysis\"\n"
1659 "classname 14: \"intrablock Memory\"\n"
1660 "classname 17: \"interblock Memory\"\n"
1661 "classname 15: \"Dominators\"\n"
1662 "classname 3: \"Entity type\"\n"
1663 "classname 4: \"Entity owner\"\n"
1664 "classname 5: \"Method Param\"\n"
1665 "classname 6: \"Method Res\"\n"
1666 "classname 7: \"Super\"\n"
1667 "classname 8: \"Union\"\n"
1668 "classname 9: \"Points-to\"\n"
1669 "classname 10: \"Array Element Type\"\n"
1670 "classname 11: \"Overwrites\"\n"
1671 "classname 12: \"Member\"\n"
1672 "infoname 1: \"Attribute\"\n"
1673 "infoname 2: \"Verification errors\"\n",
1674 name, label, orientation);
1676 /* don't use all, the range is too whith/black. */
1680 "colorentry 100: 0 0 0\n"
1681 "colorentry 101: 20 0 0\n"
1682 "colorentry 102: 40 0 0\n"
1683 "colorentry 103: 60 0 0\n"
1684 "colorentry 104: 80 0 0\n"
1685 "colorentry 105: 100 0 0\n"
1686 "colorentry 106: 120 0 0\n"
1687 "colorentry 107: 140 0 0\n"
1688 "colorentry 108: 150 0 0\n"
1689 "colorentry 109: 180 0 0\n"
1690 "colorentry 110: 200 0 0\n"
1691 "colorentry 111: 220 0 0\n"
1692 "colorentry 112: 240 0 0\n"
1693 "colorentry 113: 255 0 0\n"
1694 "colorentry 113: 255 20 20\n"
1695 "colorentry 114: 255 40 40\n"
1696 "colorentry 115: 255 60 60\n"
1697 "colorentry 116: 255 80 80\n"
1698 "colorentry 117: 255 100 100\n"
1699 "colorentry 118: 255 120 120\n"
1700 "colorentry 119: 255 140 140\n"
1701 "colorentry 120: 255 150 150\n"
1702 "colorentry 121: 255 180 180\n"
1703 "colorentry 122: 255 200 200\n"
1704 "colorentry 123: 255 220 220\n"
1705 "colorentry 124: 255 240 240\n"
1706 "colorentry 125: 255 250 250\n"
1709 fprintf (F, "\n"); /* a separator */
1715 * @param irg The graph to be dumped
1716 * @param suffix1 first filename suffix
1717 * @param suffix2 second filename suffix
1719 FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) {
1721 const char *nm = get_irg_dump_name(irg);
1722 int len = strlen(nm), i, j;
1723 char *fname; /* filename to put the vcg information in */
1725 if (!suffix1) suffix1 = "";
1726 if (!suffix2) suffix2 = "";
1728 /* open file for vcg graph */
1729 fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5);
1731 /* strncpy (fname, nm, len); */ /* copy the filename */
1733 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1735 fname[j] = '@'; j++; fname[j] = '1'; j++;
1736 } else if (nm[i] == '@') {
1737 fname[j] = '@'; j++; fname[j] = '2'; j++;
1739 fname[j] = nm[i]; j++;
1743 strcat (fname, suffix1); /* append file suffix */
1744 strcat (fname, suffix2); /* append file suffix */
1745 strcat (fname, ".vcg"); /* append the .vcg suffix */
1746 F = fopen (fname, "w"); /* open file for writing */
1748 panic("cannot open %s for writing (%m)", fname); /* not reached */
1758 * @param irg The graph to be dumped
1759 * @param suffix filename suffix
1761 static FILE *vcg_open_name (const char *name, const char *suffix) {
1763 char *fname; /* filename to put the vcg information in */
1764 int i, j, len = strlen(name);
1766 if (!suffix) suffix = "";
1768 /** open file for vcg graph */
1769 fname = malloc (len * 2 + 5 + strlen(suffix));
1770 /* strcpy (fname, name);*/ /* copy the filename */
1772 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1773 if (name[i] == '/') {
1774 fname[j] = '@'; j++; fname[j] = '1'; j++;
1775 } else if (name[i] == '@') {
1776 fname[j] = '@'; j++; fname[j] = '2'; j++;
1778 fname[j] = name[i]; j++;
1782 strcat (fname, suffix);
1783 strcat (fname, ".vcg"); /* append the .vcg suffix */
1784 F = fopen (fname, "w"); /* open file for writing */
1786 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1794 * Dumps the vcg file footer
1796 static INLINE void dump_vcg_footer (FILE *F) {
1801 * close the vcg file
1803 void vcg_close (FILE *F) {
1804 dump_vcg_footer(F); /* print footer */
1805 fclose (F); /* close vcg file */
1808 /************************************************************************/
1809 /************************************************************************/
1810 /* Routines that dump all or parts of the firm representation to a file */
1811 /************************************************************************/
1812 /************************************************************************/
1814 /************************************************************************/
1815 /* Dump ir graphs, differnt formats and additional information. */
1816 /************************************************************************/
1818 /** Routine to dump a graph, blocks as conventional nodes.
1821 dump_ir_graph (ir_graph *irg, const char *suffix )
1826 rem = current_ir_graph;
1828 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
1829 current_ir_graph = irg;
1830 if (get_interprocedural_view()) suffix1 = "-pure-ip";
1831 else suffix1 = "-pure";
1832 f = vcg_open(irg, suffix, suffix1);
1833 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1835 /* walk over the graph */
1836 /* dump_whole_node must be called in post visiting predecessors */
1837 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1839 /* dump the out edges in a separate walk */
1840 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
1841 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1846 current_ir_graph = rem;
1851 dump_ir_block_graph (ir_graph *irg, const char *suffix)
1857 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1860 if (get_interprocedural_view()) suffix1 = "-ip";
1862 f = vcg_open(irg, suffix, suffix1);
1863 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1865 construct_block_lists(irg);
1867 for (i = 0; i < get_irp_n_irgs(); i++) {
1868 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1870 dump_graph(f, get_irp_irg(i));
1878 /** dumps a graph with type information
1881 dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
1884 ir_graph *rem = current_ir_graph;
1887 /* if a filter is set, dump only the irg's that match the filter */
1888 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1891 current_ir_graph = irg;
1893 if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
1894 else suffix1 = "-pure-wtypes";
1895 f = vcg_open(irg,suffix, suffix1);
1896 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1898 /* dump common ir graph */
1899 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1900 /* dump type info */
1901 type_walk_irg(irg, dump_type_info, NULL, f);
1902 inc_irg_visited(get_const_code_irg());
1903 /* dump edges from graph to type info */
1904 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1907 current_ir_graph = rem;
1911 dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
1916 ir_graph *rem = current_ir_graph;
1918 /* if a filter is set, dump only the irg's that match the filter */
1919 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1922 if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
1923 else suffix1 = "-wtypes";
1924 f = vcg_open(irg, suffix, suffix1);
1925 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1927 /* dump common blocked ir graph */
1928 construct_block_lists(irg);
1930 for (i = 0; i < get_irp_n_irgs(); i++) {
1931 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1933 dump_graph(f, get_irp_irg(i));
1938 /* dump type info */
1939 current_ir_graph = irg;
1940 type_walk_irg(irg, dump_type_info, NULL, f);
1941 inc_irg_visited(get_const_code_irg());
1943 /* dump edges from graph to type info */
1944 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1946 current_ir_graph = rem;
1950 /*---------------------------------------------------------------------*/
1951 /* The following routines dump a control flow graph. */
1952 /*---------------------------------------------------------------------*/
1955 dump_block_to_cfg(ir_node *block, void *env) {
1960 if (is_Block(block)) {
1961 /* This is a block. Dump a node for the block. */
1962 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1963 fprintf (F, "\" label: \"");
1964 if (block == get_irg_start_block(get_irn_irg(block)))
1965 fprintf(F, "Start ");
1966 if (block == get_irg_end_block(get_irn_irg(block)))
1969 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1970 PRINT_NODEID(block);
1972 fprintf(F, "info1:\"");
1973 if (dump_dominator_information_flag)
1974 fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
1976 /* show arity and possible Bad predecessors of the block */
1977 fprintf(F, "arity: %d\n", get_Block_n_cfgpreds(block));
1978 for (fl = i = 0; i < get_Block_n_cfgpreds(block); ++i) {
1979 ir_node *pred = get_Block_cfgpred(block, i);
1982 fprintf(F, "Bad pred at pos: ");
1983 fprintf(F, "%d ", i);
1990 fprintf (F, "\""); /* closing quote of info */
1992 if ((block == get_irg_start_block(get_irn_irg(block))) ||
1993 (block == get_irg_end_block(get_irn_irg(block))) )
1994 fprintf(F, " color:blue ");
1996 fprintf(F, " color:yellow ");
1999 /* Dump the edges */
2000 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
2001 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
2002 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
2003 fprintf (F, "edge: { sourcename: \"");
2004 PRINT_NODEID(block);
2005 fprintf (F, "\" targetname: \"");
2007 fprintf (F, "\"}\n");
2010 /* Dump dominator edge */
2011 if (dump_dominator_information_flag && get_Block_idom(block)) {
2012 pred = get_Block_idom(block);
2013 fprintf (F, "edge: { sourcename: \"");
2014 PRINT_NODEID(block);
2015 fprintf (F, "\" targetname: \"");
2017 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
2023 dump_cfg (ir_graph *irg, const char *suffix)
2026 ir_graph *rem = current_ir_graph;
2027 int ddif = dump_dominator_information_flag;
2028 int ipv = get_interprocedural_view();
2030 /* if a filter is set, dump only the irg's that match the filter */
2031 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2034 current_ir_graph = irg;
2036 f = vcg_open(irg, suffix, "-cfg");
2037 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2040 printf("Warning: dumping cfg not in interprocedural view!\n");
2041 set_interprocedural_view(false);
2044 if (get_irg_dom_state(irg) != dom_consistent)
2045 dump_dominator_information_flag = 0;
2047 /* walk over the blocks in the graph */
2048 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f);
2049 dump_node(f, get_irg_bad(irg));
2051 dump_dominator_information_flag = ddif;
2052 set_interprocedural_view(ipv);
2054 current_ir_graph = rem;
2057 static int weight_overall(int rec, int loop) {
2058 return 2*rec + loop;
2061 static int compute_color (int my, int max) {
2066 /* if small, scale to the full color range. */
2068 my = my * (n_colors/max);
2070 int step = 1 + (max / n_colors);
2074 return base_color + n_colors - color;
2077 static int get_entity_color(entity *ent) {
2078 assert(get_entity_irg(ent));
2079 ir_graph *irg = get_entity_irg(ent);
2081 int rec_depth = get_irg_recursion_depth(irg);
2082 int loop_depth = get_irg_loop_depth(irg);
2083 int overall_depth = weight_overall(rec_depth, loop_depth);
2085 int max_rec_depth = irp->max_callgraph_recursion_depth;
2086 int max_loop_depth = irp->max_callgraph_loop_depth;
2087 int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
2089 /* int my_rec_color = compute_color(rec_depth, max_rec_depth); */
2090 /* int my_loop_color = compute_color(loop_depth, max_loop_depth); */
2091 int my_overall_color = compute_color(overall_depth, max_overall_depth);;
2093 return my_overall_color;
2096 void dump_callgraph(const char *suffix) {
2098 int i, n_irgs = get_irp_n_irgs();
2099 int rem = edge_label;
2101 //ident *prefix = new_id_from_str("java/");
2103 F = vcg_open_name("Callgraph", suffix);
2104 dump_vcg_header(F, "Callgraph", NULL);
2106 for (i = 0; i < n_irgs; ++i) {
2107 ir_graph *irg = get_irp_irg(i);
2108 entity *ent = get_irg_entity(irg);
2109 int j, n_callees = get_irg_n_callees(irg);
2111 /* Do not dump runtime system. */
2112 //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
2114 dump_entity_node(F, ent, get_entity_color(ent));
2115 for (j = 0; j < n_callees; ++j) {
2116 entity *c = get_irg_entity(get_irg_callee(irg, j));
2117 //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
2118 int be = is_irg_callee_backedge(irg, j);
2121 "label:\"recursion %d\" color: %d" :
2122 "label:\"calls %d\" color: %d";
2123 print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
2131 /* Dump all irgs in interprocedural view to a single file. */
2132 void dump_all_cg_block_graph(const char *suffix) {
2135 int rem_view = get_interprocedural_view();
2136 set_interprocedural_view(true);
2138 f = vcg_open_name("All_graphs", suffix);
2139 dump_vcg_header(f, "All_graphs", NULL);
2141 /* collect nodes in all irgs reachable in call graph*/
2142 for (i = 0; i < get_irp_n_irgs(); i++)
2143 ird_set_irg_link(get_irp_irg(i), NULL);
2145 cg_walk(clear_link, collect_node, NULL);
2147 /* dump all graphs */
2148 for (i = 0; i < get_irp_n_irgs(); i++) {
2149 current_ir_graph = get_irp_irg(i);
2150 assert(ird_get_irg_link(current_ir_graph));
2151 dump_graph(f, current_ir_graph);
2152 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
2156 set_interprocedural_view(rem_view);
2159 /***********************************************************************/
2160 /* the following routines dumps type information without any ir nodes. */
2161 /***********************************************************************/
2164 dump_type_graph (ir_graph *irg, const char *suffix)
2168 rem = current_ir_graph;
2170 /* if a filter is set, dump only the irg's that match the filter */
2171 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
2173 current_ir_graph = irg;
2175 f = vcg_open(irg, suffix, "-type");
2176 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2178 /* walk over the blocks in the graph */
2179 type_walk_irg(irg, dump_type_info, NULL, f);
2180 /* The walker for the const code can be called several times for the
2181 same (sub) experssion. So that no nodes are dumped several times
2182 we decrease the visited flag of the corresponding graph after each
2183 walk. So now increase it finally. */
2184 inc_irg_visited(get_const_code_irg());
2187 current_ir_graph = rem;
2191 dump_all_types (const char *suffix)
2193 FILE *f = vcg_open_name("All_types", suffix);
2194 dump_vcg_header(f, "All_types", NULL);
2195 type_walk(dump_type_info, NULL, f);
2196 inc_irg_visited(get_const_code_irg());
2201 dump_class_hierarchy (bool entities, const char *suffix)
2203 FILE *f = vcg_open_name("class_hierarchy", suffix);
2207 dump_vcg_header(f, "class_hierarchy", NULL);
2212 type_walk(dump_class_hierarchy_node, NULL, &env);
2216 /***********************************************************************/
2217 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
2219 /* dump_ir_block_graph */
2221 /* dump_type_graph */
2222 /* dump_ir_graph_w_types */
2223 /***********************************************************************/
2225 void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) {
2226 int i, n_irgs = get_irp_n_irgs();
2227 for (i = 0; i < n_irgs; ++i) {
2228 dmp_grph(get_irp_irg(i), suffix);
2233 /**********************************************************************************
2234 * Dumps a stand alone loop graph with firm nodes which belong to one loop node *
2235 * packed together in one subgraph/box *
2236 **********************************************************************************/
2238 void dump_loops_standalone(FILE *F, ir_loop *loop) {
2239 int i = 0, loop_node_started = 0, son_number = 0, first = 0;
2241 ir_loop *son = NULL;
2243 /* Dump a new loop node. */
2244 dump_loop_node(F, loop);
2246 /* Dump the loop elements. */
2248 for(i = 0; i < get_loop_n_elements(loop); i++) {
2249 le = get_loop_element(loop, i);
2251 if (get_kind(son) == k_ir_loop) {
2253 /* We are a loop son -> Recurse */
2255 if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
2256 fprintf(F, "\" }\n");
2257 fprintf (F, "edge: {sourcename: \"");
2259 fprintf (F, "\" targetname: \"");
2261 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2262 loop_node_started = 0;
2264 dump_loop_son_edge(F, loop, son_number++);
2265 dump_loops_standalone(F, son);
2266 } else if (get_kind(son) == k_ir_node) {
2267 /* We are a loop node -> Collect firm nodes */
2269 ir_node *n = le.node;
2272 if (!loop_node_started) {
2273 /* Start a new node which contains all firm nodes of the current loop */
2274 fprintf (F, "node: { title: \"");
2276 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2277 loop_node_started = 1;
2283 bad |= dump_node_opcode(F, n);
2284 bad |= dump_node_mode(F, n);
2285 bad |= dump_node_typeinfo(F, n);
2287 bad |= dump_node_nodeattr(F, n);
2288 fprintf (F, " %ld", get_irn_node_nr(n));
2289 /* Causes indeterministic output: if (is_Block(n)) fprintf (F, "\t ->%d", (int)get_irn_link(n)); */
2290 if (has_backedges(n)) fprintf(F, "\t loop head!");
2291 } else { /* for callgraph loop tree */
2292 assert(get_kind(son) == k_ir_graph);
2293 /* We are a loop node -> Collect firm graphs */
2294 ir_graph *n = (ir_graph *)le.node;
2295 if (!loop_node_started) {
2296 /* Start a new node which contains all firm nodes of the current loop */
2297 fprintf (F, "node: { title: \"");
2299 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2300 loop_node_started = 1;
2305 fprintf (F, " %s", get_irg_dump_name(n));
2306 /* fprintf (F, " %s (depth %d)", get_irg_dump_name(n), n->callgraph_weighted_loop_depth); */
2310 if (loop_node_started) {
2311 fprintf(F, "\" }\n");
2312 fprintf (F, "edge: {sourcename: \"");
2314 fprintf (F, "\" targetname: \"");
2316 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2317 loop_node_started = 0;
2321 void dump_loop_tree(ir_graph *irg, const char *suffix)
2324 ir_graph *rem = current_ir_graph;
2325 int el_rem = edge_label;
2328 /* if a filter is set, dump only the irg's that match the filter */
2329 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2332 current_ir_graph = irg;
2334 f = vcg_open(irg, suffix, "-looptree");
2335 dump_vcg_header(f, get_irg_dump_name(irg), "top_to_bottom");
2337 if (get_irg_loop(irg)) dump_loops_standalone(f, get_irg_loop(irg));
2341 edge_label = el_rem;
2342 current_ir_graph = rem;
2345 void dump_callgraph_loop_tree(const char *suffix) {
2347 F = vcg_open_name("Callgraph_looptree", suffix);
2348 dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
2349 dump_loops_standalone(F, irp->outermost_cg_loop);
2354 /*******************************************************************************/
2355 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
2356 /*******************************************************************************/
2358 void collect_nodeloop(FILE *F, ir_loop *loop, eset *loopnodes) {
2359 int i, son_number = 0, node_number = 0;
2361 if (dump_loop_information_flag) dump_loop_node(F, loop);
2363 for (i = 0; i < get_loop_n_elements(loop); i++) {
2364 loop_element le = get_loop_element(loop, i);
2365 if (*(le.kind) == k_ir_loop) {
2366 if (dump_loop_information_flag) dump_loop_son_edge(F, loop, son_number++);
2368 collect_nodeloop(F, le.son, loopnodes);
2370 if (dump_loop_information_flag) dump_loop_node_edge(F, loop, node_number++);
2371 eset_insert(loopnodes, le.node);
2376 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
2379 for(i = 0; i < get_loop_n_elements(loop); i++) {
2380 loop_element le = get_loop_element(loop, i);
2381 if (*(le.kind) == k_ir_loop) {
2383 collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
2385 if (is_Block(le.node)) start = 0; else start = -1;
2386 for (j = start; j < get_irn_arity(le.node); j++) {
2387 ir_node *pred = get_irn_n(le.node, j);
2388 if (!eset_contains(loopnodes, pred)) {
2389 eset_insert(extnodes, pred);
2390 if (!is_Block(pred)) {
2391 pred = get_nodes_block(pred);
2392 if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
2400 void dump_loop(ir_loop *l, const char *suffix) {
2403 eset *loopnodes = eset_create();
2404 eset *extnodes = eset_create();
2407 snprintf(name, sizeof(name), "loop_%d", get_loop_loop_nr(l));
2408 F = vcg_open_name (name, suffix);
2409 dump_vcg_header(F, name, NULL);
2411 /* collect all nodes to dump */
2412 collect_nodeloop(F, l, loopnodes);
2413 collect_nodeloop_external_nodes(l, loopnodes, extnodes);
2415 /* build block lists */
2416 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2417 set_irn_link(n, NULL);
2418 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2419 set_irn_link(n, NULL);
2420 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2422 b = get_nodes_block(n);
2423 set_irn_link(n, get_irn_link(b));
2426 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2428 b = get_nodes_block(n);
2429 set_irn_link(n, get_irn_link(b));
2433 for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2435 fprintf(F, "graph: { title: \"");
2437 fprintf(F, "\" label: \"");
2438 dump_node_opcode(F, b);
2439 fprintf (F, " %ld", get_irn_node_nr(b));
2440 fprintf(F, "\" status:clustered color:yellow\n");
2442 /* dump the blocks edges */
2443 dump_ir_data_edges(F, b);
2445 /* dump the nodes that go into the block */
2446 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2447 if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2449 overrule_nodecolor = NULL;
2450 if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n);
2453 /* Close the vcg information for the block */
2455 dump_const_node_local(F, b);
2458 for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2460 fprintf(F, "graph: { title: \"");
2462 fprintf(F, "\" label: \"");
2463 dump_node_opcode(F, b);
2464 fprintf (F, " %ld", get_irn_node_nr(b));
2465 fprintf(F, "\" status:clustered color:lightblue\n");
2467 /* dump the nodes that go into the block */
2468 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2469 if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2471 overrule_nodecolor = NULL;
2472 if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n);
2475 /* Close the vcg information for the block */
2477 dump_const_node_local(F, b);
2481 eset_destroy(loopnodes);
2482 eset_destroy(extnodes);