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"
31 #include "type_or_entity.h"
35 #include "callgraph.h"
45 void dump_chi_term(FILE *FL, ir_node *n);
46 void dump_state(FILE *FL, ir_node *n);
47 int get_opt_dump_abstvals(void);
48 typedef unsigned long SeqNo;
49 SeqNo get_Block_seqno(ir_node *n);
52 /* basis for a color range for vcg */
53 static int n_colors = 0;
54 static int base_color = 0;
56 #define ERROR_TXT "<ERROR>"
59 * returns the name of a mode or <ERROR> if mode is NOT a mode object.
60 * in the later case, sets bad
62 static const char *get_mode_name_ex(ir_mode *mode, int *bad)
65 return get_mode_name(mode);
71 * returns the name of a type or <ERROR> if mode is NOT a mode object.
72 * in the later case, sets bad
74 static const char *get_type_name_ex(type *tp, int *bad)
77 return get_type_name(tp);
83 * prints the edge from a type S to a type T with additional info fmt, ...
86 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
91 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
92 fprintf(F, " targetname: "); PRINT_TYPEID(T);
99 * prints the edge from a type T to an entity E with additional info fmt, ...
102 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
107 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
108 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
109 vfprintf(F, fmt, ap);
115 * prints the edge from an entity E to an entity T with additional info fmt, ...
118 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, const char *fmt, ...)
124 fprintf(F, "backedge: { sourcename: \"");
126 fprintf(F, "edge: { sourcename: \"");
128 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
129 vfprintf(F, fmt, ap);
135 * prints the edge from an entity E to a type T with additional info fmt, ...
138 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
143 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
144 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
145 vfprintf(F, fmt, ap);
151 * prints the edge from a node N to a type T with additional info fmt, ...
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);
167 * prints the edge from a node N to an entity E with additional info fmt, ...
170 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
175 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
176 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
178 vfprintf(F, fmt, ap);
184 * prints the edge from an entity E to a node N with additional info fmt, ...
187 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
192 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
193 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
194 vfprintf(F, fmt, ap);
200 * prints the edge from a type E to an enumeration item item with additional info fmt, ...
203 static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...)
208 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(E);
209 fprintf(F, " targetname: \""); PRINT_ITEMID(E, item); fprintf(F, "\" ");
210 vfprintf(F, fmt, ap);
215 /*-----------------------------------------------------------------*/
216 /* global and ahead declarations */
217 /*-----------------------------------------------------------------*/
219 static void dump_whole_node(ir_node *n, void *env);
220 static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
222 /*-----------------------------------------------------------------*/
223 /* Helper functions. */
224 /*-----------------------------------------------------------------*/
227 * This map is used as a private link attr to be able to call dumper
228 * anywhere without destroying link fields.
230 static pmap *irdump_link_map = NULL;
232 /** Creates the link attribut map. */
233 static void init_irdump(void) {
234 /* We need a new, empty map. */
235 if (irdump_link_map) pmap_destroy(irdump_link_map);
236 irdump_link_map = pmap_create();
240 * Returns the private link field.
242 static void *ird_get_irn_link(ir_node *n) {
244 if (!irdump_link_map) return NULL;
246 if (pmap_contains(irdump_link_map, (void *)n))
247 res = pmap_get(irdump_link_map, (void *)n);
252 * Sets the private link field.
254 static void ird_set_irn_link(ir_node *n, void *x) {
255 if (!irdump_link_map) init_irdump();
256 pmap_insert(irdump_link_map, (void *)n, x);
260 * Gets the private link field of an irg.
262 static void *ird_get_irg_link(ir_graph *irg) {
264 if (!irdump_link_map) return NULL;
266 if (pmap_contains(irdump_link_map, (void *)irg))
267 res = pmap_get(irdump_link_map, (void *)irg);
272 * Sets the private link field of an irg.
274 static void ird_set_irg_link(ir_graph *irg, void *x) {
275 if (!irdump_link_map) init_irdump();
276 pmap_insert(irdump_link_map, (void *)irg, x);
280 * Walker, clears tzhe private link field
282 static void clear_link(ir_node * node, void * env) {
283 ird_set_irn_link(node, NULL);
287 * Returns non-zero if a node is in floating state.
289 static int node_floats(ir_node *n) {
290 return ((get_irn_pinned(n) == op_pin_state_floats) &&
291 (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
295 * If the entity has a ld_name, returns it, else returns the name of the entity.
297 static const char *get_ent_dump_name(entity *ent) {
299 return "<NULL entity>";
300 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
301 if (ent->ld_name) return get_id_str(ent->ld_name);
302 return get_id_str(ent->name);
305 /* Returns the name of an IRG. */
306 const char *get_irg_dump_name(ir_graph *irg) {
307 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
308 entity *ent = get_irg_entity(irg);
309 return get_ent_dump_name(ent);
313 * Walker, allocates an array for all blocks and puts it's nodes non-floating nodes into this array.
315 static void collect_node(ir_node * node, void *env) {
318 || get_irn_op(node) == op_Bad
319 || get_irn_op(node) == op_Unknown
320 || get_irn_op(node) == op_NoMem) {
321 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
322 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
323 ARR_APP1(ir_node *, arr, node);
324 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
326 ir_node * block = get_nodes_block(node);
327 ird_set_irn_link(node, ird_get_irn_link(block));
328 ird_set_irn_link(block, node);
332 /** Construct lists to walk ir block-wise.
334 * Collects all blocks, nodes not op_pin_state_pinned,
335 * Bad, NoMem and Unknown into a flexible array in link field of
336 * irg they belong to. Sets the irg link field to NULL in all
337 * graphs not visited.
338 * Free the list with DEL_ARR_F().
340 static ir_node ** construct_block_lists(ir_graph *irg) {
341 int i, rem_view = get_interprocedural_view();
342 ir_graph *rem = current_ir_graph;
343 current_ir_graph = irg;
345 for (i = 0; i < get_irp_n_irgs(); i++)
346 ird_set_irg_link(get_irp_irg(i), NULL);
348 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
350 /* Collect also EndReg and EndExcept. We do not want to change the walker. */
351 set_interprocedural_view(false);
352 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
353 irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
354 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
355 irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
356 set_interprocedural_view(rem_view);
358 current_ir_graph = rem;
359 return ird_get_irg_link(irg);
362 /*******************************************************************/
363 /* flags to steer output */
364 /*******************************************************************/
366 /** Dump only irgs with names start with this string */
367 const char *dump_file_filter = "";
369 /** A compiler option to turn off edge labels */
370 static int edge_label = 1;
371 /** A compiler option to turn off dumping values of constant entities */
372 static int const_entities = 1;
373 /** A compiler option to dump the keep alive edges */
374 static int dump_keepalive = 0;
375 /** Compiler options to dump analysis information in dump_ir_graph */
376 int dump_out_edge_flag = 0;
377 int dump_dominator_information_flag = 0;
378 int dump_loop_information_flag = 0;
379 int dump_backedge_information_flag = 1;
380 int dump_const_local = 0;
381 bool opt_dump_analysed_type_info = 1;
382 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
384 static const char *overrule_nodecolor = NULL;
386 /** The vcg attribute hook. */
387 static DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL;
390 void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook)
392 dump_node_vcgattr_hook = hook;
395 INLINE bool get_opt_dump_const_local(void) {
396 if (!dump_out_edge_flag && !dump_loop_information_flag)
397 return dump_const_local;
402 void only_dump_method_with_name(ident *name) {
403 dump_file_filter = get_id_str(name);
407 /* To turn off display of edge labels. Edge labels offen cause xvcg to
408 abort with a segmentation fault. */
409 void turn_off_edge_labels(void) {
413 void dump_consts_local(bool b) {
414 dump_const_local = b;
417 void turn_off_constant_entity_values(void) {
421 void dump_keepalive_edges(bool b) {
425 bool get_opt_dump_keepalive_edges(void) {
426 return dump_keepalive;
429 void dump_out_edges(void) {
430 dump_out_edge_flag = 1;
433 void dump_dominator_information(void) {
434 dump_dominator_information_flag = 1;
437 void dump_loop_information(void) {
438 dump_loop_information_flag = 1;
441 void dont_dump_loop_information(void) {
442 dump_loop_information_flag = 0;
445 void dump_backedge_information(bool b) {
446 dump_backedge_information_flag = b;
449 /* Dump the information of type field specified in ana/irtypeinfo.h.
450 * If the flag is set, the type name is output in [] in the node label,
451 * else it is output as info.
453 void dump_analysed_type_info(bool b) {
454 opt_dump_analysed_type_info = b;
457 void dump_pointer_values_to_info(bool b) {
458 opt_dump_pointer_values_to_info = b;
461 /*-----------------------------------------------------------------*/
462 /* Routines to dump information about a single ir node. */
463 /*-----------------------------------------------------------------*/
466 * dump the name of a node n to the File F.
469 dump_node_opcode(FILE *F, ir_node *n)
473 switch(get_irn_opcode(n)) {
478 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
479 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
484 if (get_SymConst_kind(n) == symconst_addr_name) {
485 /* don't use get_SymConst_ptr_info as it mangles the name. */
486 fprintf (F, "SymC %s", get_id_str(get_SymConst_name(n)));
487 } else if (get_SymConst_kind(n) == symconst_addr_ent) {
488 assert(get_SymConst_entity(n));
489 assert(is_entity(get_SymConst_entity(n)));
490 fprintf (F, "SymC &%s", get_entity_name(get_SymConst_entity(n)));
492 assert(get_kind(get_SymConst_type(n)) == k_type);
493 assert(get_type_ident(get_SymConst_type(n)));
494 fprintf (F, "SymC %s ", get_type_name_ex(get_SymConst_type(n), &bad));
495 if (get_SymConst_kind(n) == symconst_type_tag)
503 if (!get_interprocedural_view())
510 ir_node *pred = get_Proj_pred(n);
512 if (get_irn_opcode(pred) == iro_Cond
513 && get_Proj_proj(n) == get_Cond_defaultProj(pred)
514 && get_irn_mode(get_Cond_selector(pred)) != mode_b)
515 fprintf (F, "defProj");
517 * else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
518 * fprintf (F, "Arg");
527 if (get_interprocedural_view()) {
528 fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_entity(get_irn_irg(n))));
533 case iro_CallBegin: {
534 ir_node *addr = get_CallBegin_ptr(n);
536 if (get_irn_op(addr) == op_Sel)
537 ent = get_Sel_entity(addr);
538 else if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind(addr) == symconst_addr_ent))
539 ent = get_SymConst_entity(addr);
540 fprintf (F, "%s", get_irn_opname(n));
541 if (ent) fprintf (F, " %s", get_entity_name(ent));
545 fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
550 fprintf (F, "%s", get_irn_opname(n));
558 * Dump the mode of a node n to a file F.
559 * Ignore modes that are "always known".
562 dump_node_mode(FILE *F, ir_node *n)
565 opcode iro = get_irn_opcode(n);
578 ir_mode *mode = get_irn_mode(n);
580 if (mode && mode != mode_BB && mode != mode_ANY && mode != mode_BAD &&
581 (mode != mode_T || iro == iro_Proj))
582 fprintf(F, "%s", get_mode_name_ex(mode, &bad));
590 * Dump the tpe of a node n to a file F if it's known.
592 static int dump_node_typeinfo(FILE *F, ir_node *n) {
595 if (opt_dump_analysed_type_info) {
596 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
597 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent) {
598 type *tp = get_irn_typeinfo_type(n);
600 fprintf(F, " [%s]", get_type_name_ex(tp, &bad));
609 * Dump addinional node attributes of some nodes to a file F.
612 dump_node_nodeattr(FILE *F, ir_node *n)
616 switch (get_irn_opcode(n)) {
618 if (false && get_interprocedural_view()) {
619 fprintf (F, "%s", get_ent_dump_name(get_irg_entity(current_ir_graph)));
623 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
624 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
626 fprintf (F, "%ld", get_Proj_proj(n));
630 fprintf (F, "%ld", get_Filter_proj(n));
633 fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
636 fprintf (F, "(%s)", get_type_name_ex(get_Cast_type(n), &bad));
639 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
650 * dumps the attributes of a node n into the file F.
651 * Currently this is only the color of a node.
653 static void dump_node_vcgattr(FILE *F, ir_node *n, int bad)
656 fprintf(F, "color: red");
660 if (dump_node_vcgattr_hook)
661 if (dump_node_vcgattr_hook(F, n));
664 switch (get_irn_opcode(n)) {
671 fprintf (F, "color: blue");
674 fprintf (F, "color: lightyellow");
677 fprintf (F, "color: green");
683 fprintf (F, "color: yellow");
686 PRINT_DEFAULT_NODE_ATTR;
689 if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
693 * Dump the node information of a node n to a file F.
695 static INLINE int dump_node_info(FILE *F, ir_node *n)
701 fprintf (F, " info1: \"");
702 if (opt_dump_pointer_values_to_info)
703 fprintf (F, "addr: %p \n", (void *)n);
704 fprintf (F, "mode: %s\n", get_mode_name(get_irn_mode(n)));
705 fprintf (F, "visited: %ld \n", get_irn_visited(n));
706 irg = get_irn_irg(n);
707 if (irg != get_const_code_irg())
708 fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
710 if (get_irn_pinned(n) == op_pin_state_floats &&
711 get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
712 fprintf(F, "node was pinned in ");
713 dump_node_opcode(F, get_nodes_block(n));
714 fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
718 /* show all predecessor nodes */
719 fprintf(F, "pred nodes: \n");
722 dump_node_opcode(F, get_nodes_block(n));
723 fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
725 for ( i = 0; i < get_irn_arity(n); ++i) {
726 fprintf(F, " %d: ", i);
727 dump_node_opcode(F, get_irn_n(n, i));
728 fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
732 fprintf(F, "arity: %d", get_irn_arity(n));
733 if ((get_irn_op(n) == op_Block) ||
734 (get_irn_op(n) == op_Phi) ||
735 ((get_irn_op(n) == op_Filter) && get_interprocedural_view())) {
736 fprintf(F, " backedges:");
738 for (i = 0; i < get_irn_arity(n); i++)
739 if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
743 /* Loop node Someone else please tell me what's wrong ...
744 if (get_irn_loop(n)) {
745 ir_loop *loop = get_irn_loop(n);
747 fprintf(F, " in loop %d with depth %d\n",
748 get_loop_loop_nr(loop), get_loop_depth(loop));
753 switch (get_irn_opcode(n)) {
755 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
756 fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
757 for (i = 0; i < get_method_n_params(tp); ++i)
758 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
759 if ((get_irp_ip_view_state() == ip_view_valid) && !get_interprocedural_view()) {
760 ir_node *sbl = get_nodes_block(n);
761 int i, n_cfgpreds = get_Block_cg_n_cfgpreds(sbl);
762 fprintf(F, "graph has %d interprocedural predecessors:\n", n_cfgpreds);
763 for (i = 0; i < n_cfgpreds; ++i) {
764 ir_node *cfgpred = get_Block_cg_cfgpred(sbl, i);
765 fprintf(F, " %d: Call %ld in graph %s\n", i, get_irn_node_nr(cfgpred),
766 get_irg_dump_name(get_irn_irg(cfgpred)));
771 fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
774 fprintf(F, "freeing entity of type %s \n", get_type_name_ex(get_Free_type(n), &bad));
777 entity *ent = get_Sel_entity(n);
780 fprintf(F, "Selecting entity of type %s\n", get_type_name_ex(get_entity_type(ent), &bad));
781 fprintf(F, " from entity of type %s\n", get_type_name_ex(get_entity_owner(ent), &bad));
784 fprintf(F, "<NULL entity>\n");
789 type *tp = get_Call_type(n);
790 fprintf(F, "calling method of type %s \n", get_type_name_ex(tp, &bad));
791 if(get_unknown_type() != tp) {
792 for (i = 0; i < get_method_n_params(tp); ++i)
793 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
794 for (i = 0; i < get_method_n_ress(tp); ++i)
795 fprintf(F, " resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
797 if (Call_has_callees(n)) {
798 fprintf(F, "possible callees: \n");
799 for (i = 0; i < get_Call_n_callees(n); i++) {
800 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
804 case iro_CallBegin: {
805 ir_node *call = get_CallBegin_call(n);
806 fprintf(F, "Call: %ld\n", get_irn_node_nr(call));
807 if (Call_has_callees(call)) {
808 fprintf(F, "possible callees: \n");
809 for (i = 0; i < get_Call_n_callees(call); i++) {
810 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
815 if (!get_interprocedural_view()) {
816 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
817 fprintf(F, "return in method of type %s \n", get_type_name_ex(tp, &bad));
818 for (i = 0; i < get_method_n_ress(tp); ++i)
819 fprintf(F, " res %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
823 type *tp = get_Const_type(n);
824 assert(tp != none_type);
825 fprintf(F, "Const of type %s \n", get_type_name_ex(get_Const_type(n), &bad));
828 switch(get_SymConst_kind(n)) {
829 case symconst_addr_name:
830 fprintf(F, "kind addr_name\n");
832 case symconst_addr_ent:
833 fprintf(F, "kind addr_ent\n");
834 dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames);
836 case symconst_type_tag:
837 fprintf(F, "kind type_tag\n");
840 fprintf(F, "kind size\n");
843 fprintf(F, "SymConst of type %s \n", get_type_name_ex(get_SymConst_value_type(n), &bad));
847 if (get_interprocedural_view()) {
848 fprintf(F, "intra predecessor nodes:\n");
849 for (i = 0; i < get_irn_intra_arity(n); i++) {
850 ir_node *pred = get_irn_intra_n(n, i);
851 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
854 fprintf(F, "inter predecessor nodes:\n");
855 for (i = 0; i < get_irn_inter_arity(n); i++) {
856 ir_node *pred = get_irn_inter_n(n, i);
857 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
858 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
863 fprintf(F, "volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
866 fprintf(F, "volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
872 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
873 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
874 if (get_irn_typeinfo_type(n) != none_type)
875 fprintf (F, "\nAnalysed type: %s", get_type_name_ex(get_irn_typeinfo_type(n), &bad));
883 * checks wheater a node is "constant-like", ie can be treated "block-less"
886 bool is_constlike_node(ir_node *n) {
887 ir_op *op = get_irn_op(n);
888 return (op == op_Const || op == op_Bad || op == op_NoMem || op == op_SymConst || op == op_Unknown);
892 /** outputs the predecessors of n, that are constants, local. I.e.,
893 generates a copy of the constant predecessors for each node called with. */
894 static void dump_const_node_local(FILE *F, ir_node *n) {
896 if (!get_opt_dump_const_local()) return;
898 /* Use visited flag to avoid outputting nodes twice.
899 initialize it first. */
900 for (i = 0; i < get_irn_arity(n); i++) {
901 ir_node *con = get_irn_n(n, i);
902 if (is_constlike_node(con)) {
903 set_irn_visited(con, get_irg_visited(current_ir_graph) - 1);
907 for (i = 0; i < get_irn_arity(n); i++) {
908 ir_node *con = get_irn_n(n, i);
909 if (is_constlike_node(con) && irn_not_visited(con)) {
912 mark_irn_visited(con);
913 /* Generate a new name for the node by appending the names of
915 fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
916 fprintf(F, " label: \"");
917 bad |= dump_node_opcode(F, con);
918 bad |= dump_node_mode(F, con);
919 bad |= dump_node_typeinfo(F, con);
921 bad |= dump_node_nodeattr(F, con);
922 fprintf(F, " %ld", get_irn_node_nr(con));
924 bad |= dump_node_info(F, con);
925 dump_node_vcgattr(F, con, bad);
932 * prints the error message of a node to a file F as info2.
934 static void INLINE print_node_error(FILE *F, const char *err_msg)
939 fprintf (F, " info2: \"%s\"", err_msg);
945 static void dump_node(FILE *F, ir_node *n)
950 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
952 fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
954 bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
955 bad |= dump_node_opcode(F, n);
956 bad |= dump_node_mode(F, n);
957 bad |= dump_node_typeinfo(F, n);
959 bad |= dump_node_nodeattr(F, n);
960 fprintf(F, " %ld", get_irn_node_nr(n));
962 bad |= dump_node_info(F, n);
963 print_node_error(F, p);
964 dump_node_vcgattr(F, n, bad);
966 dump_const_node_local(F, n);
973 /** dump the edge to the block this node belongs to */
975 dump_ir_block_edge(FILE *F, ir_node *n) {
976 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
977 if (is_no_Block(n)) {
978 ir_node *block = get_nodes_block(n);
980 fprintf (F, "edge: { sourcename: \"");
982 fprintf (F, "\" targetname: ");
983 fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
984 fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
989 print_data_edge_vcgattr(FILE *F, ir_node *from, int to) {
990 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
991 fprintf (F, INTRA_DATA_EDGE_ATTR);
993 fprintf (F, INTER_DATA_EDGE_ATTR);
997 print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) {
998 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
999 fprintf (F, INTRA_MEM_EDGE_ATTR);
1001 fprintf (F, INTER_MEM_EDGE_ATTR);
1005 print_edge_vcgattr(FILE *F, ir_node *from, int to) {
1008 if (dump_backedge_information_flag && is_backedge(from, to))
1009 fprintf (F, BACK_EDGE_ATTR);
1011 switch (get_irn_opcode(from)) {
1013 fprintf (F, CF_EDGE_ATTR);
1015 case iro_Start: break;
1018 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
1019 fprintf (F, CF_EDGE_ATTR);
1020 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
1021 fprintf (F, INTER_MEM_EDGE_ATTR);
1029 print_data_edge_vcgattr(F, from, to);
1034 print_mem_edge_vcgattr(F, from, to);
1036 print_data_edge_vcgattr(F, from, to);
1040 print_data_edge_vcgattr(F, from, to);
1045 print_mem_edge_vcgattr(F, from, to);
1047 print_data_edge_vcgattr(F, from, to);
1054 print_data_edge_vcgattr(F, from, to);
1061 print_mem_edge_vcgattr(F, from, to);
1063 print_data_edge_vcgattr(F, from, to);
1075 print_data_edge_vcgattr(F, from, to);
1078 if (get_irn_modecode(from) == irm_M)
1079 fprintf (F, INTER_MEM_EDGE_ATTR);
1081 print_data_edge_vcgattr(F, from, to);
1088 print_mem_edge_vcgattr(F, from, to);
1090 print_data_edge_vcgattr(F, from, to);
1093 print_mem_edge_vcgattr(F, from, to);
1095 case iro_Tuple: break;
1098 switch (get_irn_modecode(from)) {
1100 fprintf (F, CF_EDGE_ATTR);
1103 fprintf (F, INTER_MEM_EDGE_ATTR);
1106 print_data_edge_vcgattr(F, from, to);
1110 case iro_Bad: break;
1111 case iro_Unknown: break;
1113 switch (get_irn_modecode(from)) {
1115 fprintf (F, INTRA_MEM_EDGE_ATTR);
1118 fprintf (F, CF_EDGE_ATTR);
1121 print_data_edge_vcgattr(F, from, to);
1129 /* dump edges to our inputs */
1131 dump_ir_data_edges(FILE *F, ir_node *n) {
1132 int i, visited = get_irn_visited(n);
1134 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
1137 for (i = 0; i < get_irn_arity(n); i++) {
1138 ir_node * pred = get_irn_n(n, i);
1141 if ((get_interprocedural_view() && get_irn_visited(pred) < visited))
1142 continue; /* pred not dumped */
1144 if (dump_backedge_information_flag && is_backedge(n, i))
1145 fprintf (F, "backedge: {sourcename: \"");
1147 fprintf (F, "edge: {sourcename: \"");
1149 fprintf (F, "\" targetname: ");
1150 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
1151 PRINT_CONSTID(n, pred);
1153 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
1155 fprintf (F, " label: \"%d\" ", i);
1156 print_edge_vcgattr(F, n, i);
1161 /** Dumps a node and its edges but not the block edge
1164 dump_node_wo_blockedge (ir_node *n, void *env) {
1167 dump_ir_data_edges(F, n);
1170 /** Dumps a node and its edges.
1173 dump_whole_node (ir_node *n, void *env) {
1175 dump_node_wo_blockedge(n, env);
1176 if (!node_floats(n)) dump_ir_block_edge(F, n);
1180 dump_const_node(ir_node *n, void *env) {
1181 if (is_Block(n)) return;
1182 dump_node_wo_blockedge(n, env);
1185 /***********************************************************************/
1186 /* the following routines dump the nodes/irgs bracketed to graphs. */
1187 /***********************************************************************/
1189 /** Dumps a constant expression as entity initializer, array bound ...
1191 static void dump_const_expression(FILE *F, ir_node *value) {
1192 ir_graph *rem = current_ir_graph;
1193 int rem_dump_const_local = dump_const_local;
1194 dump_const_local = 0;
1195 current_ir_graph = get_const_code_irg();
1196 irg_walk(value, dump_const_node, NULL, F);
1197 /* Decrease visited flag so that we walk with the same flag for the next
1198 expresssion. This guarantees that we don't dump the same node twice,
1199 as for const expressions cse is performed to save memory. */
1200 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
1201 current_ir_graph = rem;
1202 dump_const_local = rem_dump_const_local;
1205 /** Dump a block as graph containing its nodes.
1207 * Expects to find nodes belonging to the block as list in its
1209 * Dumps the edges of all nodes including itself. */
1211 dump_whole_block(FILE *F, ir_node *block) {
1213 assert(is_Block(block));
1215 fprintf(F, "graph: { title: \"");
1216 PRINT_NODEID(block);
1217 fprintf(F, "\" label: \"");
1218 dump_node_opcode(F, block);
1219 fprintf (F, " %ld", get_irn_node_nr(block));
1221 if (get_opt_dump_abstvals())
1222 fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
1224 fprintf(F, "\" status:clustered color:%s \n",
1225 get_Block_matured(block) ? "yellow" : "red");
1227 /* dump the blocks edges */
1228 dump_ir_data_edges(F, block);
1230 /* dump the nodes that go into the block */
1231 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
1233 dump_ir_data_edges(F, node);
1236 /* Close the vcg information for the block */
1238 dump_const_node_local(F, block);
1240 dump_chi_term(F, block);
1245 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
1246 * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */
1248 dump_block_graph(FILE *F, ir_graph *irg) {
1250 ir_graph *rem = current_ir_graph;
1251 ir_node **arr = ird_get_irg_link(irg);
1252 current_ir_graph = irg;
1254 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1255 ir_node * node = arr[i];
1256 if (is_Block(node)) {
1257 /* Dumps the block and all the nodes in the block, which are to
1258 be found in Block->link. */
1259 dump_whole_block(F, node);
1261 /* Nodes that are not in a Block. */
1263 dump_ir_data_edges(F, node);
1267 if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
1268 dump_loop_nodes_into_graph(F, irg);
1270 current_ir_graph = rem;
1273 /** Dumps an irg as a graph.
1274 * If interprocedural view edges can point to nodes out of this graph.
1276 static void dump_graph(FILE *F, ir_graph *irg) {
1278 fprintf(F, "graph: { title: \"");
1280 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
1281 get_ent_dump_name(get_irg_entity(irg)));
1283 dump_block_graph(F, irg);
1285 /* Close the vcg information for the irg */
1286 fprintf(F, "}\n\n");
1289 /*******************************************************************/
1290 /* Basic type and entity nodes and edges. */
1291 /*******************************************************************/
1293 /** dumps the edges between nodes and their type or entity attributes. */
1294 static void dump_node2type_edges(ir_node *n, void *env)
1299 switch (get_irn_opcode(n)) {
1301 /* @@@ some consts have an entity */
1304 if ( (get_SymConst_kind(n) ==symconst_type_tag)
1305 || (get_SymConst_kind(n) ==symconst_size))
1307 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1311 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1314 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1317 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1320 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1323 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1331 static int print_type_info(FILE *F, type *tp) {
1334 if (get_type_state(tp) == layout_undefined) {
1335 fprintf(F, "state: layout_undefined\n");
1337 fprintf(F, "state: layout_fixed,\n");
1339 if (get_type_mode(tp))
1340 fprintf(F, "mode: %s,\n", get_mode_name_ex(get_type_mode(tp), &bad));
1341 fprintf(F, "size: %db,\n", get_type_size_bits(tp));
1346 static void print_typespecific_info(FILE *F, type *tp) {
1347 switch (get_type_tpop_code(tp)) {
1350 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1357 fprintf(F, "variadicity: %s\n", get_variadicity_name(get_method_variadicity(tp)));
1358 fprintf(F, "params: %d\n", get_method_n_params(tp));
1359 fprintf(F, "results: %d\n", get_method_n_ress(tp));
1367 case tpo_enumeration:
1381 static void print_typespecific_vcgattr(FILE *F, type *tp) {
1382 switch (get_type_tpop_code(tp)) {
1385 if (peculiarity_existent == get_class_peculiarity(tp))
1386 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1388 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1392 fprintf (F, " " TYPE_METH_NODE_ATTR);
1403 case tpo_enumeration:
1416 static int print_type_node(FILE *F, type *tp)
1420 fprintf (F, "node: {title: ");
1422 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
1423 fprintf (F, " info1: \"");
1424 bad |= print_type_info(F, tp);
1425 print_typespecific_info(F, tp);
1427 print_typespecific_vcgattr(F, tp);
1433 #define X(a) case a: fprintf(F, #a); break
1434 void dump_entity_node(FILE *F, entity *ent, int color)
1436 fprintf (F, "node: {title: \"");
1437 PRINT_ENTID(ent); fprintf(F, "\"");
1438 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1439 fprintf (F, "label: ");
1440 fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
1442 fprintf(F, "color: %d", color);
1444 fprintf (F, ENTITY_NODE_ATTR);
1445 fprintf (F, "\n info1: \"");
1447 dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
1449 fprintf(F, "\"\n}\n");
1453 static void dump_enum_item(FILE *F, type *tp, int pos)
1456 ident *id = get_enumeration_nameid(tp, pos);
1457 tarval *tv = get_enumeration_enum(tp, pos);
1459 tarval_snprintf(buf, sizeof(buf), tv);
1460 fprintf (F, "node: {title: \"");
1461 PRINT_ITEMID(tp, pos); fprintf(F, "\"");
1462 fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE);
1463 fprintf (F, "label: ");
1464 fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id));
1465 fprintf (F, "\n info1: \"value: %s\"}\n", buf);
1468 /* dumps a type or entity and it's edges. */
1470 dump_type_info(type_or_ent *tore, void *env) {
1472 int i = 0; /* to shutup gcc */
1474 /* dump this type or entity */
1476 switch (get_kind(tore)) {
1479 entity *ent = (entity *)tore;
1482 dump_entity_node(F, ent, 0);
1484 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1485 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1486 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1487 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1488 if(is_class_type(get_entity_owner(ent))) {
1489 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1490 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, ENT_OVERWRITES_EDGE_ATTR);
1492 /* attached subgraphs */
1493 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1494 if (is_atomic_entity(ent)) {
1495 value = get_atomic_ent_value(ent);
1497 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1498 /* DDMN(value); $$$ */
1499 dump_const_expression(F, value);
1502 if (is_compound_entity(ent)) {
1503 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1504 value = get_compound_ent_value(ent, i);
1506 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1507 dump_const_expression(F, value);
1508 print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, ENT_CORR_EDGE_ATTR, i);
1510 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1511 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1512 get_compound_ent_value_member(ent, i), i);
1521 type *tp = (type *)tore;
1522 print_type_node(F, tp);
1523 /* and now the edges */
1524 switch (get_type_tpop_code(tp)) {
1527 for (i=0; i < get_class_n_supertypes(tp); i++)
1528 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1529 for (i=0; i < get_class_n_members(tp); i++)
1530 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1534 for (i=0; i < get_struct_n_members(tp); i++)
1535 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1539 for (i = 0; i < get_method_n_params(tp); i++)
1540 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1541 for (i = 0; i < get_method_n_ress(tp); i++)
1542 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1546 for (i = 0; i < get_union_n_members(tp); i++)
1547 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1551 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1552 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1553 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1554 ir_node *upper = get_array_upper_bound(tp, i);
1555 ir_node *lower = get_array_lower_bound(tp, i);
1556 print_node_type_edge(F, upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1557 print_node_type_edge(F, lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1558 dump_const_expression(F, upper);
1559 dump_const_expression(F, lower);
1563 case tpo_enumeration:
1565 for (i = 0; i < get_enumeration_n_enums(tp); ++i) {
1566 dump_enum_item(F, tp, i);
1567 print_enum_item_edge(F, tp, i, "label: \"item %d\"", i);
1572 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1580 break; /* case k_type */
1583 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1585 } /* switch kind_or_entity */
1588 typedef struct _h_env {
1593 /** For dumping class hierarchies.
1594 * Dumps a class type node and a superclass edge.
1595 * If env->dump_ent dumps entities of classes and overwrites edges.
1598 dump_class_hierarchy_node (type_or_ent *tore, void *ctx) {
1601 int i = 0; /* to shutup gcc */
1603 /* dump this type or entity */
1604 switch (get_kind(tore)) {
1606 entity *ent = (entity *)tore;
1607 if (get_entity_owner(ent) == get_glob_type()) break;
1608 if (!is_method_type(get_entity_type(ent))) break; /* GL */
1609 if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
1611 dump_entity_node(F, ent, 0);
1613 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1614 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1615 print_ent_ent_edge(F, get_entity_overwrites(ent, i), ent, 0, ENT_OVERWRITES_EDGE_ATTR);
1617 } break; /* case k_entity */
1620 type *tp = (type *)tore;
1621 if (tp == get_glob_type()) break;
1622 switch (get_type_tpop_code(tp)) {
1624 print_type_node(F, tp);
1625 /* and now the edges */
1626 for (i=0; i < get_class_n_supertypes(tp); i++)
1628 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1634 break; /* case k_type */
1637 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1639 } /* switch kind_or_entity */
1642 /*******************************************************************/
1643 /* dump analysis information that is expressed in graph terms. */
1644 /*******************************************************************/
1646 /* dump out edges */
1648 dump_out_edge(ir_node *n, void *env) {
1651 for (i = 0; i < get_irn_n_outs(n); i++) {
1652 assert(get_irn_out(n, i));
1653 fprintf (F, "edge: {sourcename: \"");
1655 fprintf (F, "\" targetname: \"");
1656 PRINT_NODEID(get_irn_out(n, i));
1657 fprintf (F, "\" color: red linestyle: dashed");
1663 dump_loop_label(FILE *F, ir_loop *loop) {
1664 fprintf (F, "loop %d, %d sons, %d nodes",
1665 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1668 static INLINE void dump_loop_info(FILE *F, ir_loop *loop) {
1669 fprintf (F, " info1: \"");
1670 fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1671 #if DEBUG_libfirm /* GL @@@ debug analyses */
1672 fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1678 dump_loop_node(FILE *F, ir_loop *loop) {
1679 fprintf (F, "node: {title: \"");
1681 fprintf (F, "\" label: \"");
1682 dump_loop_label(F, loop);
1684 dump_loop_info(F, loop);
1690 dump_loop_node_edge(FILE *F, ir_loop *loop, int i) {
1692 fprintf (F, "edge: {sourcename: \"");
1694 fprintf (F, "\" targetname: \"");
1695 PRINT_NODEID(get_loop_node(loop, i));
1696 fprintf (F, "\" color: green");
1701 dump_loop_son_edge(FILE *F, ir_loop *loop, int i) {
1703 fprintf (F, "edge: {sourcename: \"");
1705 fprintf (F, "\" targetname: \"");
1706 PRINT_LOOPID(get_loop_son(loop, i));
1707 fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1708 get_loop_element_pos(loop, get_loop_son(loop, i)));
1712 void dump_loops(FILE *F, ir_loop *loop) {
1714 /* dump this loop node */
1715 dump_loop_node(F, loop);
1717 /* dump edges to nodes in loop -- only if it is a real loop */
1718 if (get_loop_depth(loop) != 0) {
1719 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1720 dump_loop_node_edge(F, loop, i);
1723 for (i = 0; i < get_loop_n_sons(loop); i++) {
1724 dump_loops(F, get_loop_son(loop, i));
1725 dump_loop_son_edge(F, loop, i);
1730 void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) {
1731 ir_graph *rem = current_ir_graph;
1732 current_ir_graph = irg;
1734 if (get_irg_loop(irg)) dump_loops(F, get_irg_loop(irg));
1736 current_ir_graph = rem;
1741 * dumps the VCG header
1743 INLINE void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
1752 if (!orientation) orientation = "bottom_to_top";
1756 "graph: { title: \"ir graph of %s\"\n"
1757 "display_edge_labels: %s\n"
1758 "layoutalgorithm: mindepth\n"
1759 "manhattan_edges: yes\n"
1760 "port_sharing: no\n"
1762 "classname 1: \"intrablock Data\"\n"
1763 "classname 16: \"interblock Data\"\n"
1764 "classname 2: \"Block\"\n"
1765 "classname 13: \"Control Flow\"\n"
1766 "classname 18: \"Exception Control Flow for Interval Analysis\"\n"
1767 "classname 14: \"intrablock Memory\"\n"
1768 "classname 17: \"interblock Memory\"\n"
1769 "classname 15: \"Dominators\"\n"
1770 "classname 3: \"Entity type\"\n"
1771 "classname 4: \"Entity owner\"\n"
1772 "classname 5: \"Method Param\"\n"
1773 "classname 6: \"Method Res\"\n"
1774 "classname 7: \"Super\"\n"
1775 "classname 8: \"Union\"\n"
1776 "classname 9: \"Points-to\"\n"
1777 "classname 10: \"Array Element Type\"\n"
1778 "classname 11: \"Overwrites\"\n"
1779 "classname 12: \"Member\"\n"
1780 "infoname 1: \"Attribute\"\n"
1781 "infoname 2: \"Verification errors\"\n",
1782 name, label, orientation);
1784 /* don't use all, the range is too whith/black. */
1788 "colorentry 100: 0 0 0\n"
1789 "colorentry 101: 20 0 0\n"
1790 "colorentry 102: 40 0 0\n"
1791 "colorentry 103: 60 0 0\n"
1792 "colorentry 104: 80 0 0\n"
1793 "colorentry 105: 100 0 0\n"
1794 "colorentry 106: 120 0 0\n"
1795 "colorentry 107: 140 0 0\n"
1796 "colorentry 108: 150 0 0\n"
1797 "colorentry 109: 180 0 0\n"
1798 "colorentry 110: 200 0 0\n"
1799 "colorentry 111: 220 0 0\n"
1800 "colorentry 112: 240 0 0\n"
1801 "colorentry 113: 255 0 0\n"
1802 "colorentry 113: 255 20 20\n"
1803 "colorentry 114: 255 40 40\n"
1804 "colorentry 115: 255 60 60\n"
1805 "colorentry 116: 255 80 80\n"
1806 "colorentry 117: 255 100 100\n"
1807 "colorentry 118: 255 120 120\n"
1808 "colorentry 119: 255 140 140\n"
1809 "colorentry 120: 255 150 150\n"
1810 "colorentry 121: 255 180 180\n"
1811 "colorentry 122: 255 200 200\n"
1812 "colorentry 123: 255 220 220\n"
1813 "colorentry 124: 255 240 240\n"
1814 "colorentry 125: 255 250 250\n"
1817 fprintf (F, "\n"); /* a separator */
1823 * @param irg The graph to be dumped
1824 * @param suffix1 first filename suffix
1825 * @param suffix2 second filename suffix
1827 FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) {
1829 const char *nm = get_irg_dump_name(irg);
1830 int len = strlen(nm), i, j;
1831 char *fname; /* filename to put the vcg information in */
1833 if (!suffix1) suffix1 = "";
1834 if (!suffix2) suffix2 = "";
1836 /* open file for vcg graph */
1837 fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5);
1839 /* strncpy (fname, nm, len); */ /* copy the filename */
1841 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1843 fname[j] = '@'; j++; fname[j] = '1'; j++;
1844 } else if (nm[i] == '@') {
1845 fname[j] = '@'; j++; fname[j] = '2'; j++;
1847 fname[j] = nm[i]; j++;
1851 strcat (fname, suffix1); /* append file suffix */
1852 strcat (fname, suffix2); /* append file suffix */
1853 strcat (fname, ".vcg"); /* append the .vcg suffix */
1854 F = fopen (fname, "w"); /* open file for writing */
1856 panic("cannot open %s for writing (%m)", fname); /* not reached */
1866 * @param irg The graph to be dumped
1867 * @param suffix filename suffix
1869 static FILE *vcg_open_name (const char *name, const char *suffix) {
1871 char *fname; /* filename to put the vcg information in */
1872 int i, j, len = strlen(name);
1874 if (!suffix) suffix = "";
1876 /** open file for vcg graph */
1877 fname = malloc (len * 2 + 5 + strlen(suffix));
1878 /* strcpy (fname, name);*/ /* copy the filename */
1880 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1881 if (name[i] == '/') {
1882 fname[j] = '@'; j++; fname[j] = '1'; j++;
1883 } else if (name[i] == '@') {
1884 fname[j] = '@'; j++; fname[j] = '2'; j++;
1886 fname[j] = name[i]; j++;
1890 strcat (fname, suffix);
1891 strcat (fname, ".vcg"); /* append the .vcg suffix */
1892 F = fopen (fname, "w"); /* open file for writing */
1894 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1902 * Dumps the vcg file footer
1904 static INLINE void dump_vcg_footer (FILE *F) {
1909 * close the vcg file
1911 void vcg_close (FILE *F) {
1912 dump_vcg_footer(F); /* print footer */
1913 fclose (F); /* close vcg file */
1916 /************************************************************************/
1917 /************************************************************************/
1918 /* Routines that dump all or parts of the firm representation to a file */
1919 /************************************************************************/
1920 /************************************************************************/
1922 /************************************************************************/
1923 /* Dump ir graphs, differnt formats and additional information. */
1924 /************************************************************************/
1926 /** Routine to dump a graph, blocks as conventional nodes.
1929 dump_ir_graph (ir_graph *irg, const char *suffix )
1934 rem = current_ir_graph;
1936 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
1937 current_ir_graph = irg;
1938 if (get_interprocedural_view()) suffix1 = "-pure-ip";
1939 else suffix1 = "-pure";
1940 f = vcg_open(irg, suffix, suffix1);
1941 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1943 /* walk over the graph */
1944 /* dump_whole_node must be called in post visiting predecessors */
1945 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1947 /* dump the out edges in a separate walk */
1948 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
1949 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1954 current_ir_graph = rem;
1959 dump_ir_block_graph (ir_graph *irg, const char *suffix)
1965 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1968 if (get_interprocedural_view()) suffix1 = "-ip";
1970 f = vcg_open(irg, suffix, suffix1);
1971 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1973 construct_block_lists(irg);
1975 for (i = 0; i < get_irp_n_irgs(); i++) {
1976 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1978 dump_graph(f, get_irp_irg(i));
1986 /** dumps a graph with type information
1989 dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
1992 ir_graph *rem = current_ir_graph;
1995 /* if a filter is set, dump only the irg's that match the filter */
1996 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1999 current_ir_graph = irg;
2001 if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
2002 else suffix1 = "-pure-wtypes";
2003 f = vcg_open(irg,suffix, suffix1);
2004 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2006 /* dump common ir graph */
2007 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
2008 /* dump type info */
2009 type_walk_irg(irg, dump_type_info, NULL, f);
2010 inc_irg_visited(get_const_code_irg());
2011 /* dump edges from graph to type info */
2012 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
2015 current_ir_graph = rem;
2019 dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
2024 ir_graph *rem = current_ir_graph;
2026 /* if a filter is set, dump only the irg's that match the filter */
2027 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2030 if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
2031 else suffix1 = "-wtypes";
2032 f = vcg_open(irg, suffix, suffix1);
2033 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2035 /* dump common blocked ir graph */
2036 construct_block_lists(irg);
2038 for (i = 0; i < get_irp_n_irgs(); i++) {
2039 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
2041 dump_graph(f, get_irp_irg(i));
2046 /* dump type info */
2047 current_ir_graph = irg;
2048 type_walk_irg(irg, dump_type_info, NULL, f);
2049 inc_irg_visited(get_const_code_irg());
2051 /* dump edges from graph to type info */
2052 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
2054 current_ir_graph = rem;
2058 /*---------------------------------------------------------------------*/
2059 /* The following routines dump a control flow graph. */
2060 /*---------------------------------------------------------------------*/
2063 dump_block_to_cfg(ir_node *block, void *env) {
2068 if (is_Block(block)) {
2069 /* This is a block. Dump a node for the block. */
2070 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
2071 fprintf (F, "\" label: \"");
2072 if (block == get_irg_start_block(get_irn_irg(block)))
2073 fprintf(F, "Start ");
2074 if (block == get_irg_end_block(get_irn_irg(block)))
2077 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
2078 PRINT_NODEID(block);
2080 fprintf(F, "info1:\"");
2081 if (dump_dominator_information_flag)
2082 fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
2084 /* show arity and possible Bad predecessors of the block */
2085 fprintf(F, "arity: %d\n", get_Block_n_cfgpreds(block));
2086 for (fl = i = 0; i < get_Block_n_cfgpreds(block); ++i) {
2087 ir_node *pred = get_Block_cfgpred(block, i);
2090 fprintf(F, "Bad pred at pos: ");
2091 fprintf(F, "%d ", i);
2098 fprintf (F, "\""); /* closing quote of info */
2100 if ((block == get_irg_start_block(get_irn_irg(block))) ||
2101 (block == get_irg_end_block(get_irn_irg(block))) )
2102 fprintf(F, " color:blue ");
2104 fprintf(F, " color:yellow ");
2107 /* Dump the edges */
2108 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
2109 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
2110 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
2111 fprintf (F, "edge: { sourcename: \"");
2112 PRINT_NODEID(block);
2113 fprintf (F, "\" targetname: \"");
2115 fprintf (F, "\"}\n");
2118 /* Dump dominator edge */
2119 if (dump_dominator_information_flag && get_Block_idom(block)) {
2120 pred = get_Block_idom(block);
2121 fprintf (F, "edge: { sourcename: \"");
2122 PRINT_NODEID(block);
2123 fprintf (F, "\" targetname: \"");
2125 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
2131 dump_cfg (ir_graph *irg, const char *suffix)
2134 ir_graph *rem = current_ir_graph;
2135 int ddif = dump_dominator_information_flag;
2136 int ipv = get_interprocedural_view();
2138 /* if a filter is set, dump only the irg's that match the filter */
2139 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2142 current_ir_graph = irg;
2144 f = vcg_open(irg, suffix, "-cfg");
2145 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2148 printf("Warning: dumping cfg not in interprocedural view!\n");
2149 set_interprocedural_view(false);
2152 if (get_irg_dom_state(irg) != dom_consistent)
2153 dump_dominator_information_flag = 0;
2155 /* walk over the blocks in the graph */
2156 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f);
2157 dump_node(f, get_irg_bad(irg));
2159 dump_dominator_information_flag = ddif;
2160 set_interprocedural_view(ipv);
2162 current_ir_graph = rem;
2165 static int weight_overall(int rec, int loop) {
2166 return 2*rec + loop;
2169 static int compute_color (int my, int max) {
2174 /* if small, scale to the full color range. */
2176 my = my * (n_colors/max);
2178 int step = 1 + (max / n_colors);
2182 return base_color + n_colors - color;
2185 static int get_entity_color(entity *ent) {
2186 assert(get_entity_irg(ent));
2187 ir_graph *irg = get_entity_irg(ent);
2189 int rec_depth = get_irg_recursion_depth(irg);
2190 int loop_depth = get_irg_loop_depth(irg);
2191 int overall_depth = weight_overall(rec_depth, loop_depth);
2193 int max_rec_depth = irp->max_callgraph_recursion_depth;
2194 int max_loop_depth = irp->max_callgraph_loop_depth;
2195 int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
2197 /* int my_rec_color = compute_color(rec_depth, max_rec_depth); */
2198 /* int my_loop_color = compute_color(loop_depth, max_loop_depth); */
2199 int my_overall_color = compute_color(overall_depth, max_overall_depth);;
2201 return my_overall_color;
2204 void dump_callgraph(const char *suffix) {
2206 int i, n_irgs = get_irp_n_irgs();
2207 int rem = edge_label;
2209 //ident *prefix = new_id_from_str("java/");
2211 F = vcg_open_name("Callgraph", suffix);
2212 dump_vcg_header(F, "Callgraph", NULL);
2214 for (i = 0; i < n_irgs; ++i) {
2215 ir_graph *irg = get_irp_irg(i);
2216 entity *ent = get_irg_entity(irg);
2217 int j, n_callees = get_irg_n_callees(irg);
2219 /* Do not dump runtime system. */
2220 //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
2222 dump_entity_node(F, ent, get_entity_color(ent));
2223 for (j = 0; j < n_callees; ++j) {
2224 entity *c = get_irg_entity(get_irg_callee(irg, j));
2225 //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
2226 int be = is_irg_callee_backedge(irg, j);
2229 "label:\"recursion %d\" color: %d" :
2230 "label:\"calls %d\" color: %d";
2231 print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
2239 /* Dump all irgs in interprocedural view to a single file. */
2240 void dump_all_cg_block_graph(const char *suffix) {
2243 int rem_view = get_interprocedural_view();
2244 set_interprocedural_view(true);
2246 f = vcg_open_name("All_graphs", suffix);
2247 dump_vcg_header(f, "All_graphs", NULL);
2249 /* collect nodes in all irgs reachable in call graph*/
2250 for (i = 0; i < get_irp_n_irgs(); i++)
2251 ird_set_irg_link(get_irp_irg(i), NULL);
2253 cg_walk(clear_link, collect_node, NULL);
2255 /* dump all graphs */
2256 for (i = 0; i < get_irp_n_irgs(); i++) {
2257 current_ir_graph = get_irp_irg(i);
2258 assert(ird_get_irg_link(current_ir_graph));
2259 dump_graph(f, current_ir_graph);
2260 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
2264 set_interprocedural_view(rem_view);
2267 /*---------------------------------------------------------------------*/
2268 /* the following routines dumps type information without any ir nodes. */
2269 /*---------------------------------------------------------------------*/
2272 dump_type_graph (ir_graph *irg, const char *suffix)
2276 rem = current_ir_graph;
2278 /* if a filter is set, dump only the irg's that match the filter */
2279 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
2281 current_ir_graph = irg;
2283 f = vcg_open(irg, suffix, "-type");
2284 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2286 /* walk over the blocks in the graph */
2287 type_walk_irg(irg, dump_type_info, NULL, f);
2288 /* The walker for the const code can be called several times for the
2289 same (sub) experssion. So that no nodes are dumped several times
2290 we decrease the visited flag of the corresponding graph after each
2291 walk. So now increase it finally. */
2292 inc_irg_visited(get_const_code_irg());
2295 current_ir_graph = rem;
2299 dump_all_types (const char *suffix)
2301 FILE *f = vcg_open_name("All_types", suffix);
2302 dump_vcg_header(f, "All_types", NULL);
2303 type_walk(dump_type_info, NULL, f);
2304 inc_irg_visited(get_const_code_irg());
2309 dump_class_hierarchy (bool entities, const char *suffix)
2311 FILE *f = vcg_open_name("class_hierarchy", suffix);
2315 dump_vcg_header(f, "class_hierarchy", NULL);
2320 type_walk(dump_class_hierarchy_node, NULL, &env);
2324 /*---------------------------------------------------------------------*/
2325 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
2327 /* dump_ir_block_graph */
2329 /* dump_type_graph */
2330 /* dump_ir_graph_w_types */
2331 /*---------------------------------------------------------------------*/
2333 void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) {
2334 int i, n_irgs = get_irp_n_irgs();
2335 for (i = 0; i < n_irgs; ++i) {
2336 dmp_grph(get_irp_irg(i), suffix);
2341 /*--------------------------------------------------------------------------------*
2342 * Dumps a stand alone loop graph with firm nodes which belong to one loop node *
2343 * packed together in one subgraph/box *
2344 *--------------------------------------------------------------------------------*/
2346 void dump_loops_standalone(FILE *F, ir_loop *loop) {
2347 int i = 0, loop_node_started = 0, son_number = 0, first = 0;
2349 ir_loop *son = NULL;
2351 /* Dump a new loop node. */
2352 dump_loop_node(F, loop);
2354 /* Dump the loop elements. */
2356 for(i = 0; i < get_loop_n_elements(loop); i++) {
2357 le = get_loop_element(loop, i);
2359 if (get_kind(son) == k_ir_loop) {
2361 /* We are a loop son -> Recurse */
2363 if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
2364 fprintf(F, "\" }\n");
2365 fprintf (F, "edge: {sourcename: \"");
2367 fprintf (F, "\" targetname: \"");
2369 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2370 loop_node_started = 0;
2372 dump_loop_son_edge(F, loop, son_number++);
2373 dump_loops_standalone(F, son);
2374 } else if (get_kind(son) == k_ir_node) {
2375 /* We are a loop node -> Collect firm nodes */
2377 ir_node *n = le.node;
2380 if (!loop_node_started) {
2381 /* Start a new node which contains all firm nodes of the current loop */
2382 fprintf (F, "node: { title: \"");
2384 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2385 loop_node_started = 1;
2391 bad |= dump_node_opcode(F, n);
2392 bad |= dump_node_mode(F, n);
2393 bad |= dump_node_typeinfo(F, n);
2395 bad |= dump_node_nodeattr(F, n);
2396 fprintf (F, " %ld", get_irn_node_nr(n));
2397 /* Causes indeterministic output: if (is_Block(n)) fprintf (F, "\t ->%d", (int)get_irn_link(n)); */
2398 if (has_backedges(n)) fprintf(F, "\t loop head!");
2399 } else { /* for callgraph loop tree */
2400 assert(get_kind(son) == k_ir_graph);
2401 /* We are a loop node -> Collect firm graphs */
2402 ir_graph *n = (ir_graph *)le.node;
2403 if (!loop_node_started) {
2404 /* Start a new node which contains all firm nodes of the current loop */
2405 fprintf (F, "node: { title: \"");
2407 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2408 loop_node_started = 1;
2413 fprintf (F, " %s", get_irg_dump_name(n));
2414 /* fprintf (F, " %s (depth %d)", get_irg_dump_name(n), n->callgraph_weighted_loop_depth); */
2418 if (loop_node_started) {
2419 fprintf(F, "\" }\n");
2420 fprintf (F, "edge: {sourcename: \"");
2422 fprintf (F, "\" targetname: \"");
2424 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2425 loop_node_started = 0;
2429 void dump_loop_tree(ir_graph *irg, const char *suffix)
2432 ir_graph *rem = current_ir_graph;
2433 int el_rem = edge_label;
2436 /* if a filter is set, dump only the irg's that match the filter */
2437 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2440 current_ir_graph = irg;
2442 f = vcg_open(irg, suffix, "-looptree");
2443 dump_vcg_header(f, get_irg_dump_name(irg), "top_to_bottom");
2445 if (get_irg_loop(irg)) dump_loops_standalone(f, get_irg_loop(irg));
2449 edge_label = el_rem;
2450 current_ir_graph = rem;
2453 void dump_callgraph_loop_tree(const char *suffix) {
2455 F = vcg_open_name("Callgraph_looptree", suffix);
2456 dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
2457 dump_loops_standalone(F, irp->outermost_cg_loop);
2462 /*-----------------------------------------------------------------------------*/
2463 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
2464 /*-----------------------------------------------------------------------------*/
2466 void collect_nodeloop(FILE *F, ir_loop *loop, eset *loopnodes) {
2467 int i, son_number = 0, node_number = 0;
2469 if (dump_loop_information_flag) dump_loop_node(F, loop);
2471 for (i = 0; i < get_loop_n_elements(loop); i++) {
2472 loop_element le = get_loop_element(loop, i);
2473 if (*(le.kind) == k_ir_loop) {
2474 if (dump_loop_information_flag) dump_loop_son_edge(F, loop, son_number++);
2476 collect_nodeloop(F, le.son, loopnodes);
2478 if (dump_loop_information_flag) dump_loop_node_edge(F, loop, node_number++);
2479 eset_insert(loopnodes, le.node);
2484 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
2487 for(i = 0; i < get_loop_n_elements(loop); i++) {
2488 loop_element le = get_loop_element(loop, i);
2489 if (*(le.kind) == k_ir_loop) {
2491 collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
2493 if (is_Block(le.node)) start = 0; else start = -1;
2494 for (j = start; j < get_irn_arity(le.node); j++) {
2495 ir_node *pred = get_irn_n(le.node, j);
2496 if (!eset_contains(loopnodes, pred)) {
2497 eset_insert(extnodes, pred);
2498 if (!is_Block(pred)) {
2499 pred = get_nodes_block(pred);
2500 if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
2508 void dump_loop(ir_loop *l, const char *suffix) {
2511 eset *loopnodes = eset_create();
2512 eset *extnodes = eset_create();
2515 snprintf(name, sizeof(name), "loop_%d", get_loop_loop_nr(l));
2516 F = vcg_open_name (name, suffix);
2517 dump_vcg_header(F, name, NULL);
2519 /* collect all nodes to dump */
2520 collect_nodeloop(F, l, loopnodes);
2521 collect_nodeloop_external_nodes(l, loopnodes, extnodes);
2523 /* build block lists */
2524 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2525 set_irn_link(n, NULL);
2526 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2527 set_irn_link(n, NULL);
2528 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2530 b = get_nodes_block(n);
2531 set_irn_link(n, get_irn_link(b));
2534 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2536 b = get_nodes_block(n);
2537 set_irn_link(n, get_irn_link(b));
2541 for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2543 fprintf(F, "graph: { title: \"");
2545 fprintf(F, "\" label: \"");
2546 dump_node_opcode(F, b);
2547 fprintf (F, " %ld", get_irn_node_nr(b));
2548 fprintf(F, "\" status:clustered color:yellow\n");
2550 /* dump the blocks edges */
2551 dump_ir_data_edges(F, b);
2553 /* dump the nodes that go into the block */
2554 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2555 if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2557 overrule_nodecolor = NULL;
2558 if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n);
2561 /* Close the vcg information for the block */
2563 dump_const_node_local(F, b);
2566 for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2568 fprintf(F, "graph: { title: \"");
2570 fprintf(F, "\" label: \"");
2571 dump_node_opcode(F, b);
2572 fprintf (F, " %ld", get_irn_node_nr(b));
2573 fprintf(F, "\" status:clustered color:lightblue\n");
2575 /* dump the nodes that go into the block */
2576 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2577 if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2579 overrule_nodecolor = NULL;
2580 if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n);
2583 /* Close the vcg information for the block */
2585 dump_const_node_local(F, b);
2589 eset_destroy(loopnodes);
2590 eset_destroy(extnodes);