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 /* Attributes of nodes */
53 #define PRINT_DEFAULT_NODE_ATTR
54 #define DEFAULT_NODE_ATTR " "
55 #define DEFAULT_TYPE_ATTRIBUTE " "
56 #define DEFAULT_ENUM_ITEM_ATTRIBUTE " "
58 /* Attributes of edges between Firm nodes */
59 #define INTRA_DATA_EDGE_ATTR "class:1 priority:50"
60 #define INTER_DATA_EDGE_ATTR "class:16 priority:10"
61 #define BLOCK_EDGE_ATTR "class:2 priority:50 linestyle:dotted"
62 #define CF_EDGE_ATTR "class:13 priority:60 color:red"
63 #define INTRA_MEM_EDGE_ATTR "class:14 priority:50 color:blue"
64 #define INTER_MEM_EDGE_ATTR "class:17 priority:10 color:blue"
65 #define DOMINATOR_EDGE_ATTR "class:15 color:red"
67 #define BACK_EDGE_ATTR "linestyle:dashed "
69 /* Attributes of edges between Firm nodes and type/entity nodes */
70 #define NODE2TYPE_EDGE_ATTR "class:2 priority:2 linestyle:dotted"
72 /* Attributes of edges in type/entity graphs. */
73 #define TYPE_METH_NODE_ATTR "color: lightyellow"
74 #define TYPE_CLASS_NODE_ATTR "color: green"
75 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
76 #define ENTITY_NODE_ATTR "color: yellow"
77 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
78 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
79 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
80 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
81 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
82 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
83 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
84 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
85 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
86 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
87 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
88 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
89 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
90 #define ENUM_ITEM_NODE_ATTR "color: green"
91 #define CALLGRAPH_EDGE_ATTR "calls"
93 #if DEBUG_libfirm && NODEID_AS_LABEL
94 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
95 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
96 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
97 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
98 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
99 #define PRINT_LOOPID(X) fprintf(F, "l%d", get_loop_loop_nr(X))
100 #define PRINT_ITEMID(X,Y) fprintf(F, "i%ldT%d", get_type_nr(X), (Y))
103 #define PRINT_NODEID(X) fprintf(F, "n%p", (void *)(X))
104 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *)(X))
105 #define PRINT_ENTID(X) fprintf(F, "e%p", (void *)(X))
106 #define PRINT_IRGID(X) fprintf(F, "g%p",(void *)(X))
107 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*)(X), (void*)(Y))
108 #define PRINT_LOOPID(X) fprintf(F, "l%p", (void *)(X))
109 #define PRINT_ITEMID(X,Y) fprintf(F, "i%pT%d", (void *) (X), (Y))
113 /* basis for a color range for vcg */
114 static int n_colors = 0;
115 static int base_color = 0;
117 static const char *get_mode_name_ex(ir_mode *mode, int *bad)
120 return get_mode_name(mode);
125 static const char *get_type_name_ex(type *tp, int *bad)
128 return get_type_name(tp);
133 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
138 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
139 fprintf(F, " targetname: "); PRINT_TYPEID(T);
140 vfprintf(F, fmt, ap);
145 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
150 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
151 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
152 vfprintf(F, fmt, ap);
157 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, const char *fmt, ...)
163 fprintf(F, "backedge: { sourcename: \"");
165 fprintf(F, "edge: { sourcename: \"");
167 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
168 vfprintf(F, fmt, ap);
173 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
178 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
179 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
180 vfprintf(F, fmt, ap);
185 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
190 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
191 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
192 vfprintf(F, fmt, ap);
197 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
202 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
203 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
205 vfprintf(F, fmt, ap);
210 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
215 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
216 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
217 vfprintf(F, fmt, ap);
222 static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...)
227 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(E);
228 fprintf(F, " targetname: \""); PRINT_ITEMID(E, item); fprintf(F, "\" ");
229 vfprintf(F, fmt, ap);
234 /*******************************************************************/
235 /* global and ahead declarations */
236 /*******************************************************************/
238 static void dump_whole_node(ir_node *n, void *env);
239 static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
241 /*******************************************************************/
242 /* Helper functions. */
243 /*******************************************************************/
245 /* Use private link attr to be able to call dumper anywhere without
246 destroying link fields. */
248 static pmap *irdump_link_map = NULL;
250 static void init_irdump(void) {
251 /* We need a new, empty map. */
252 if (irdump_link_map) pmap_destroy(irdump_link_map);
253 irdump_link_map = pmap_create();
257 void *ird_get_irn_link(ir_node *n) {
259 if (!irdump_link_map) return NULL;
261 if (pmap_contains(irdump_link_map, (void *)n))
262 res = pmap_get(irdump_link_map, (void *)n);
266 void ird_set_irn_link(ir_node *n, void *x) {
267 if (!irdump_link_map) init_irdump();
268 pmap_insert(irdump_link_map, (void *)n, x);
271 void *ird_get_irg_link(ir_graph *irg) {
273 if (!irdump_link_map) return NULL;
275 if (pmap_contains(irdump_link_map, (void *)irg))
276 res = pmap_get(irdump_link_map, (void *)irg);
280 void ird_set_irg_link(ir_graph *irg, void *x) {
281 if (!irdump_link_map) init_irdump();
282 pmap_insert(irdump_link_map, (void *)irg, x);
285 static void clear_link(ir_node * node, void * env) {
286 ird_set_irn_link(node, NULL);
290 static int node_floats(ir_node *n) {
291 return ((get_op_pinned(get_irn_op(n)) == op_pin_state_floats) &&
292 (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
295 static const char *get_ent_dump_name(entity *ent) {
297 return "<NULL entity>";
298 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
299 if (ent->ld_name) return get_id_str(ent->ld_name);
300 return get_id_str(ent->name);
303 static const char *get_irg_dump_name(ir_graph *irg) {
304 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
305 entity *ent = get_irg_entity(irg);
306 return get_ent_dump_name(ent);
309 static void collect_node(ir_node * node, void *env) {
312 || get_irn_op(node) == op_Bad
313 || get_irn_op(node) == op_Unknown) {
314 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
315 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
316 ARR_APP1(ir_node *, arr, node);
317 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
319 ir_node * block = get_nodes_block(node);
320 ird_set_irn_link(node, ird_get_irn_link(block));
321 ird_set_irn_link(block, node);
325 /** Construct lists to walk ir block-wise.
327 * Collects all blocks, nodes not op_pin_state_pinned,
328 * Bad and Unknown into a flexible array in link field of
329 * irg they belong to. Sets the irg link field to NULL in all
330 * graphs not visited.
331 * Free the list with DEL_ARR_F. */
332 static ir_node ** construct_block_lists(ir_graph *irg) {
333 int i, rem_view = interprocedural_view;
334 ir_graph *rem = current_ir_graph;
335 current_ir_graph = irg;
337 for (i = 0; i < get_irp_n_irgs(); i++)
338 ird_set_irg_link(get_irp_irg(i), NULL);
340 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
342 /* Collect also EndReg and EndExcept. We do not want to change the walker. */
343 interprocedural_view = 0;
344 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
345 irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
346 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
347 irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
348 interprocedural_view = rem_view;
350 current_ir_graph = rem;
351 return ird_get_irg_link(irg);
354 /*******************************************************************/
355 /* flags to steer output */
356 /*******************************************************************/
358 const char *dump_file_filter = "";
360 /* A compiler option to turn off edge labels */
362 /* A compiler option to turn off dumping values of constant entities */
363 int const_entities = 1;
364 /* A compiler option to dump the keep alive edges */
365 int dump_keepalive = 0;
366 /* Compiler options to dump analysis information in dump_ir_graph */
367 int dump_out_edge_flag = 0;
368 int dump_dominator_information_flag = 0;
369 int dump_loop_information_flag = 0;
370 int dump_backedge_information_flag = 1;
371 int dump_const_local = 0;
372 bool opt_dump_analysed_type_info = 1;
373 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
375 char* overrule_nodecolor = NULL;
377 INLINE bool get_opt_dump_const_local(void) {
378 if (!dump_out_edge_flag && !dump_loop_information_flag)
379 return dump_const_local;
384 void only_dump_method_with_name(ident *name) {
385 dump_file_filter = get_id_str(name);
389 /* To turn off display of edge labels. Edge labels offen cause xvcg to
390 abort with a segmentation fault. */
391 void turn_off_edge_labels(void) {
395 void dump_consts_local(bool b) {
396 dump_const_local = b;
399 void turn_off_constant_entity_values(void) {
403 void dump_keepalive_edges(bool b) {
407 bool get_opt_dump_keepalive_edges(void) {
408 return dump_keepalive;
411 void dump_out_edges(void) {
412 dump_out_edge_flag = 1;
415 void dump_dominator_information(void) {
416 dump_dominator_information_flag = 1;
419 void dump_loop_information(void) {
420 dump_loop_information_flag = 1;
423 void dont_dump_loop_information(void) {
424 dump_loop_information_flag = 0;
427 void dump_backedge_information(bool b) {
428 dump_backedge_information_flag = b;
431 /* Dump the information of type field specified in ana/irtypeinfo.h.
432 * If the flag is set, the type name is output in [] in the node label,
433 * else it is output as info.
435 void dump_analysed_type_info(bool b) {
436 opt_dump_analysed_type_info = b;
439 void dump_pointer_values_to_info(bool b) {
440 opt_dump_pointer_values_to_info = b;
443 /*******************************************************************/
444 /* Routines to dump information about a single ir node. */
445 /*******************************************************************/
448 dump_node_opcode(FILE *F, ir_node *n)
452 switch(get_irn_opcode(n)) {
457 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
458 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
463 if (get_SymConst_kind(n) == symconst_addr_name) {
464 /* don't use get_SymConst_ptr_info as it mangles the name. */
465 fprintf (F, "SymC %s", get_id_str(get_SymConst_name(n)));
466 } else if (get_SymConst_kind(n) == symconst_addr_ent) {
467 assert(get_SymConst_entity(n));
468 assert(is_entity(get_SymConst_entity(n)));
469 fprintf (F, "SymC &%s", get_entity_name(get_SymConst_entity(n)));
471 assert(get_kind(get_SymConst_type(n)) == k_type);
472 assert(get_type_ident(get_SymConst_type(n)));
473 fprintf (F, "SymC %s ", get_type_name_ex(get_SymConst_type(n), &bad));
474 if (get_SymConst_kind(n) == symconst_type_tag)
482 if (!interprocedural_view) fprintf(F, "Proj'");
483 else goto default_case;
487 ir_node *pred = get_Proj_pred(n);
489 if (get_irn_opcode(pred) == iro_Cond
490 && get_Proj_proj(n) == get_Cond_defaultProj(pred)
491 && get_irn_mode(get_Cond_selector(pred)) != mode_b)
492 fprintf (F, "defProj");
494 * else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
495 * fprintf (F, "Arg");
504 if (interprocedural_view) {
505 fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_entity(get_irn_irg(n))));
510 case iro_CallBegin: {
511 ir_node *addr = get_CallBegin_ptr(n);
513 if (get_irn_op(addr) == op_Sel)
514 ent = get_Sel_entity(addr);
515 else if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind(addr) == symconst_addr_ent))
516 ent = get_SymConst_entity(addr);
517 fprintf (F, "%s", get_irn_opname(n));
518 if (ent) fprintf (F, " %s", get_entity_name(ent));
524 fprintf (F, "%s", get_irn_opname(n));
532 dump_node_mode(FILE *F, ir_node *n)
536 switch (get_irn_opcode(n)) {
555 fprintf(F, "%s", get_mode_name_ex(get_irn_mode(n), &bad));
563 static int dump_node_typeinfo(FILE *F, ir_node *n) {
566 if (opt_dump_analysed_type_info) {
567 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
568 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent) {
569 type *tp = get_irn_type(n);
571 fprintf(F, " [%s]", get_type_name_ex(tp, &bad));
580 dump_node_nodeattr(FILE *F, ir_node *n)
584 switch (get_irn_opcode(n)) {
586 if (false && interprocedural_view) {
587 fprintf (F, "%s", get_ent_dump_name(get_irg_entity(current_ir_graph)));
591 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
592 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
594 fprintf (F, "%ld", get_Proj_proj(n));
598 fprintf (F, "%ld", get_Filter_proj(n));
601 fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
604 fprintf (F, "(%s)", get_type_name_ex(get_Cast_type(n), &bad));
607 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
617 static INLINE void dump_node_vcgattr(FILE *F, ir_node *n, int bad)
620 fprintf(F, "color: red");
623 switch (get_irn_opcode(n)) {
630 fprintf (F, "color: blue");
633 fprintf (F, "color: lightyellow");
636 fprintf (F, "color: green");
642 fprintf (F, "color: yellow");
645 PRINT_DEFAULT_NODE_ATTR;
648 if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
651 static INLINE int dump_node_info(FILE *F, ir_node *n)
657 fprintf (F, " info1: \"");
658 if (opt_dump_pointer_values_to_info)
659 fprintf (F, "addr: %p \n", (void *)n);
660 fprintf (F, "mode: %s\n", get_mode_name(get_irn_mode(n)));
661 fprintf (F, "visited: %ld \n", get_irn_visited(n));
662 irg = get_irn_irg(n);
663 if (irg != get_const_code_irg())
664 fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
666 fprintf(F, "arity: %d", get_irn_arity(n));
667 if ((get_irn_op(n) == op_Block) ||
668 (get_irn_op(n) == op_Phi) ||
669 ((get_irn_op(n) == op_Filter) && interprocedural_view)) {
670 fprintf(F, " backedges:");
672 for (i = 0; i < get_irn_arity(n); i++)
673 if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
677 /* Loop node Someone else please tell me what's wrong ...
678 if (get_irn_loop(n)) {
679 ir_loop *loop = get_irn_loop(n);
681 fprintf(F, " in loop %d with depth %d\n",
682 get_loop_loop_nr(loop), get_loop_depth(loop));
687 switch (get_irn_opcode(n)) {
689 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
690 fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
691 for (i = 0; i < get_method_n_params(tp); ++i)
692 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
695 fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
698 fprintf(F, "freeing entity of type %s \n", get_type_name_ex(get_Free_type(n), &bad));
701 entity *ent = get_Sel_entity(n);
704 fprintf(F, "Selecting entity of type %s\n", get_type_name_ex(get_entity_type(ent), &bad));
705 fprintf(F, " from entity of type %s\n", get_type_name_ex(get_entity_owner(ent), &bad));
708 fprintf(F, "<NULL entity>\n");
713 type *tp = get_Call_type(n);
714 fprintf(F, "calling method of type %s \n", get_type_name_ex(tp, &bad));
715 for (i = 0; i < get_method_n_params(tp); ++i)
716 fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
717 for (i = 0; i < get_method_n_ress(tp); ++i)
718 fprintf(F, " resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
719 if (0 && Call_has_callees(n)) {
720 fprintf(F, "possible callees: \n");
721 for (i = 0; i < get_Call_n_callees(n); i++) {
722 if (!get_Call_callee(n, i)) {
723 fprintf(F, " %d external method\n", i);
725 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
730 case iro_CallBegin: {
731 ir_node *call = get_CallBegin_call(n);
732 if (Call_has_callees(call)) {
733 fprintf(F, "possible callees: \n");
734 for (i = 0; i < get_Call_n_callees(call); i++) {
735 if (!get_Call_callee(call, i)) {
736 fprintf(F, " %d external method\n", i);
738 fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
744 if (!interprocedural_view) {
745 type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
746 fprintf(F, "return in method of type %s \n", get_type_name_ex(tp, &bad));
747 for (i = 0; i < get_method_n_ress(tp); ++i)
748 fprintf(F, " res %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
752 type *tp = get_Const_type(n);
753 assert(tp != none_type);
754 fprintf(F, "Const of type %s \n", get_type_name_ex(get_Const_type(n), &bad));
757 switch(get_SymConst_kind(n)) {
758 case symconst_addr_name:
759 fprintf(F, "kind addr_name\n");
761 case symconst_addr_ent:
762 fprintf(F, "kind addr_ent\n");
764 case symconst_type_tag:
765 fprintf(F, "kind type_tag\n");
768 fprintf(F, "kind size\n");
774 if (interprocedural_view) {
775 fprintf(F, "intra predecessor nodes:\n");
776 for (i = 0; i < get_irn_intra_arity(n); i++) {
777 ir_node *pred = get_irn_intra_n(n, i);
778 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
781 fprintf(F, "inter predecessor nodes:\n");
782 for (i = 0; i < get_irn_inter_arity(n); i++) {
783 ir_node *pred = get_irn_inter_n(n, i);
784 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
785 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
792 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
793 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
794 if (get_irn_type(n) != none_type)
795 fprintf (F, "\nAnalysed type: %s", get_type_name_ex(get_irn_type(n), &bad));
804 bool is_constlike_node(ir_node *n) {
805 ir_op *op = get_irn_op(n);
806 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
810 /* outputs the predecessors of n, that are constants, local. I.e.,
811 generates a copy of the constant predecessors for each node called with. */
812 static void dump_const_node_local(FILE *F, ir_node *n) {
814 if (!get_opt_dump_const_local()) return;
816 /* Use visited flag to avoid outputting nodes twice.
817 initialize it first. */
818 for (i = 0; i < get_irn_arity(n); i++) {
819 ir_node *con = get_irn_n(n, i);
820 if (is_constlike_node(con)) {
821 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
825 for (i = 0; i < get_irn_arity(n); i++) {
826 ir_node *con = get_irn_n(n, i);
827 if (is_constlike_node(con) && irn_not_visited(con)) {
830 mark_irn_visited(con);
831 /* Generate a new name for the node by appending the names of
833 fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
834 fprintf(F, " label: \"");
835 bad |= dump_node_opcode(F, con);
836 bad |= dump_node_mode(F, con);
837 bad |= dump_node_typeinfo(F, con);
839 bad |= dump_node_nodeattr(F, con);
840 fprintf(F, " %ld", get_irn_node_nr(con));
842 bad |= dump_node_info(F, con);
843 dump_node_vcgattr(F, con, bad);
849 static void INLINE print_node_error(FILE *F, const char *p)
854 fprintf (F, " info2: \"%s\"", p);
857 static void dump_node(FILE *F, ir_node *n)
862 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
864 fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
866 bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
867 bad |= dump_node_opcode(F, n);
868 bad |= dump_node_mode(F, n);
869 bad |= dump_node_typeinfo(F, n);
871 bad |= dump_node_nodeattr(F, n);
872 fprintf(F, " %ld", get_irn_node_nr(n));
874 bad |= dump_node_info(F, n);
875 print_node_error(F, p);
876 dump_node_vcgattr(F, n, bad);
878 dump_const_node_local(F, n);
885 /* dump the edge to the block this node belongs to */
887 dump_ir_block_edge(FILE *F, ir_node *n) {
888 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
889 if (is_no_Block(n)) {
890 fprintf (F, "edge: { sourcename: \"");
892 fprintf (F, "\" targetname: \"");
893 PRINT_NODEID(get_nodes_block(n));
894 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
899 print_data_edge_vcgattr(FILE *F, ir_node *from, int to) {
900 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
901 fprintf (F, INTRA_DATA_EDGE_ATTR);
903 fprintf (F, INTER_DATA_EDGE_ATTR);
907 print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) {
908 if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
909 fprintf (F, INTRA_MEM_EDGE_ATTR);
911 fprintf (F, INTER_MEM_EDGE_ATTR);
915 print_edge_vcgattr(FILE *F, ir_node *from, int to) {
918 if (dump_backedge_information_flag && is_backedge(from, to))
919 fprintf (F, BACK_EDGE_ATTR);
921 switch (get_irn_opcode(from)) {
923 fprintf (F, CF_EDGE_ATTR);
925 case iro_Start: break;
928 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
929 fprintf (F, CF_EDGE_ATTR);
930 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
931 fprintf (F, INTER_MEM_EDGE_ATTR);
939 print_data_edge_vcgattr(F, from, to);
944 print_mem_edge_vcgattr(F, from, to);
946 print_data_edge_vcgattr(F, from, to);
950 print_data_edge_vcgattr(F, from, to);
955 print_mem_edge_vcgattr(F, from, to);
957 print_data_edge_vcgattr(F, from, to);
964 print_data_edge_vcgattr(F, from, to);
971 print_mem_edge_vcgattr(F, from, to);
973 print_data_edge_vcgattr(F, from, to);
985 print_data_edge_vcgattr(F, from, to);
988 if (get_irn_modecode(from) == irm_M)
989 fprintf (F, INTER_MEM_EDGE_ATTR);
991 print_data_edge_vcgattr(F, from, to);
998 print_mem_edge_vcgattr(F, from, to);
1000 print_data_edge_vcgattr(F, from, to);
1003 print_mem_edge_vcgattr(F, from, to);
1005 case iro_Tuple: break;
1008 switch (get_irn_modecode(from)) {
1010 fprintf (F, CF_EDGE_ATTR);
1013 fprintf (F, INTER_MEM_EDGE_ATTR);
1016 print_data_edge_vcgattr(F, from, to);
1020 case iro_Bad: break;
1021 case iro_Unknown: break;
1023 switch (get_irn_modecode(from)) {
1025 fprintf (F, INTRA_MEM_EDGE_ATTR);
1028 fprintf (F, CF_EDGE_ATTR);
1031 print_data_edge_vcgattr(F, from, to);
1039 /* dump edges to our inputs */
1041 dump_ir_data_edges(FILE *F, ir_node *n) {
1042 int i, visited = get_irn_visited(n);
1044 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
1047 for (i = 0; i < get_irn_arity(n); i++) {
1048 ir_node * pred = get_irn_n(n, i);
1051 if ((interprocedural_view && get_irn_visited(pred) < visited))
1052 continue; /* pred not dumped */
1054 if (dump_backedge_information_flag && is_backedge(n, i))
1055 fprintf (F, "backedge: {sourcename: \"");
1057 fprintf (F, "edge: {sourcename: \"");
1059 fprintf (F, "\" targetname: ");
1060 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
1061 PRINT_CONSTID(n, pred);
1063 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
1065 fprintf (F, " label: \"%d\" ", i);
1066 print_edge_vcgattr(F, n, i);
1071 /** Dumps a node and its edges but not the block edge
1074 dump_node_wo_blockedge (ir_node *n, void *env) {
1077 dump_ir_data_edges(F, n);
1080 /** Dumps a node and its edges.
1083 dump_whole_node (ir_node *n, void *env) {
1085 dump_node_wo_blockedge(n, env);
1086 if (!node_floats(n)) dump_ir_block_edge(F, n);
1090 dump_const_node(ir_node *n, void *env) {
1091 if (is_Block(n)) return;
1092 dump_node_wo_blockedge(n, env);
1095 /***********************************************************************/
1096 /* the following routines dump the nodes/irgs bracketed to graphs. */
1097 /***********************************************************************/
1099 /** Dumps a constant expression as entity initializer, array bound ...
1101 static void dump_const_expression(FILE *F, ir_node *value) {
1102 ir_graph *rem = current_ir_graph;
1103 int rem_dump_const_local = dump_const_local;
1104 dump_const_local = 0;
1105 current_ir_graph = get_const_code_irg();
1106 irg_walk(value, dump_const_node, NULL, F);
1107 /* Decrease visited flag so that we walk with the same flag for the next
1108 expresssion. This guarantees that we don't dump the same node twice,
1109 as for const expressions cse is performed to save memory. */
1110 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
1111 current_ir_graph = rem;
1112 dump_const_local = rem_dump_const_local;
1115 /** Dump a block as graph containing its nodes.
1117 * Expects to find nodes belonging to the block as list in its
1119 * Dumps the edges of all nodes including itself. */
1121 dump_whole_block(FILE *F, ir_node *block) {
1123 assert(is_Block(block));
1125 fprintf(F, "graph: { title: \"");
1126 PRINT_NODEID(block);
1127 fprintf(F, "\" label: \"");
1128 dump_node_opcode(F, block);
1129 fprintf (F, " %ld", get_irn_node_nr(block));
1131 if (get_opt_dump_abstvals())
1132 fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
1134 fprintf(F, "\" status:clustered color:%s \n",
1135 get_Block_matured(block) ? "yellow" : "red");
1137 /* dump the blocks edges */
1138 dump_ir_data_edges(F, block);
1140 /* dump the nodes that go into the block */
1141 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
1143 dump_ir_data_edges(F, node);
1146 /* Close the vcg information for the block */
1148 dump_const_node_local(F, block);
1150 dump_chi_term(F, block);
1155 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
1156 * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */
1158 dump_block_graph(FILE *F, ir_graph *irg) {
1160 ir_graph *rem = current_ir_graph;
1161 ir_node **arr = ird_get_irg_link(irg);
1162 current_ir_graph = irg;
1164 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1165 ir_node * node = arr[i];
1166 if (is_Block(node)) {
1167 /* Dumps the block and all the nodes in the block, which are to
1168 be found in Block->link. */
1169 dump_whole_block(F, node);
1171 /* Nodes that are not in a Block. */
1173 dump_ir_data_edges(F, node);
1177 if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
1178 dump_loop_nodes_into_graph(F, irg);
1180 current_ir_graph = rem;
1183 /** Dumps an irg as a graph.
1184 * If interprocedural view edges can point to nodes out of this graph.
1186 static void dump_graph(FILE *F, ir_graph *irg) {
1188 fprintf(F, "graph: { title: \"");
1190 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
1191 get_ent_dump_name(get_irg_entity(irg)));
1193 dump_block_graph(F, irg);
1195 /* Close the vcg information for the irg */
1196 fprintf(F, "}\n\n");
1199 /*******************************************************************/
1200 /* Basic type and entity nodes and edges. */
1201 /*******************************************************************/
1203 /* dumps the edges between nodes and their type or entity attributes. */
1204 static void dump_node2type_edges(ir_node *n, void *env)
1209 switch (get_irn_opcode(n)) {
1211 /* @@@ some consts have an entity */
1214 if ( (get_SymConst_kind(n) ==symconst_type_tag)
1215 || (get_SymConst_kind(n) ==symconst_size))
1217 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1221 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1224 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1227 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1230 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1233 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1241 static int print_type_info(FILE *F, type *tp) {
1244 if (get_type_state(tp) == layout_undefined) {
1245 fprintf(F, "state: layout_undefined\n");
1247 fprintf(F, "state: layout_fixed,\n");
1249 if (get_type_mode(tp))
1250 fprintf(F, "mode: %s,\n", get_mode_name_ex(get_type_mode(tp), &bad));
1251 fprintf(F, "size: %db,\n", get_type_size_bits(tp));
1256 static void print_typespecific_info(FILE *F, type *tp) {
1257 switch (get_type_tpop_code(tp)) {
1260 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1267 fprintf(F, "variadicity: %s\n", get_variadicity_name(get_method_variadicity(tp)));
1268 fprintf(F, "params: %d\n", get_method_n_params(tp));
1269 fprintf(F, "results: %d\n", get_method_n_ress(tp));
1277 case tpo_enumeration:
1291 static void print_typespecific_vcgattr(FILE *F, type *tp) {
1292 switch (get_type_tpop_code(tp)) {
1295 if (peculiarity_existent == get_class_peculiarity(tp))
1296 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1298 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1302 fprintf (F, " " TYPE_METH_NODE_ATTR);
1313 case tpo_enumeration:
1326 static int print_type_node(FILE *F, type *tp)
1330 fprintf (F, "node: {title: ");
1332 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
1333 fprintf (F, " info1: \"");
1334 bad |= print_type_info(F, tp);
1335 print_typespecific_info(F, tp);
1337 print_typespecific_vcgattr(F, tp);
1343 #define X(a) case a: fprintf(F, #a); break
1344 void dump_entity_node(FILE *F, entity *ent, int color)
1346 fprintf (F, "node: {title: \"");
1347 PRINT_ENTID(ent); fprintf(F, "\"");
1348 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1349 fprintf (F, "label: ");
1350 fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
1352 fprintf(F, "color: %d", color);
1354 fprintf (F, ENTITY_NODE_ATTR);
1355 fprintf (F, "\n info1: \"");
1357 dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
1359 fprintf(F, "\"\n}\n");
1363 static void dump_enum_item(FILE *F, type *tp, int pos)
1366 ident *id = get_enumeration_nameid(tp, pos);
1367 tarval *tv = get_enumeration_enum(tp, pos);
1369 tarval_snprintf(buf, sizeof(buf), tv);
1370 fprintf (F, "node: {title: \"");
1371 PRINT_ITEMID(tp, pos); fprintf(F, "\"");
1372 fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE);
1373 fprintf (F, "label: ");
1374 fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id));
1375 fprintf (F, "\n info1: \"value: %s\"}\n", buf);
1378 /* dumps a type or entity and it's edges. */
1380 dump_type_info(type_or_ent *tore, void *env) {
1382 int i = 0; /* to shutup gcc */
1384 /* dump this type or entity */
1386 switch (get_kind(tore)) {
1389 entity *ent = (entity *)tore;
1392 dump_entity_node(F, ent, 0);
1394 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1395 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1396 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1397 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1398 if(is_class_type(get_entity_owner(ent))) {
1399 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1400 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, ENT_OVERWRITES_EDGE_ATTR);
1402 /* attached subgraphs */
1403 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1404 if (is_atomic_entity(ent)) {
1405 value = get_atomic_ent_value(ent);
1407 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1408 /* DDMN(value); $$$ */
1409 dump_const_expression(F, value);
1412 if (is_compound_entity(ent)) {
1413 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1414 value = get_compound_ent_value(ent, i);
1416 print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1417 dump_const_expression(F, value);
1418 print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, ENT_CORR_EDGE_ATTR, i);
1420 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1421 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1422 get_compound_ent_value_member(ent, i), i);
1431 type *tp = (type *)tore;
1432 print_type_node(F, tp);
1433 /* and now the edges */
1434 switch (get_type_tpop_code(tp)) {
1437 for (i=0; i < get_class_n_supertypes(tp); i++)
1438 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1439 for (i=0; i < get_class_n_members(tp); i++)
1440 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1444 for (i=0; i < get_struct_n_members(tp); i++)
1445 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1449 for (i = 0; i < get_method_n_params(tp); i++)
1450 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1451 for (i = 0; i < get_method_n_ress(tp); i++)
1452 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1456 for (i = 0; i < get_union_n_members(tp); i++)
1457 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1461 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1462 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1463 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1464 ir_node *upper = get_array_upper_bound(tp, i);
1465 ir_node *lower = get_array_lower_bound(tp, i);
1466 print_node_type_edge(F, upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1467 print_node_type_edge(F, lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1468 dump_const_expression(F, upper);
1469 dump_const_expression(F, lower);
1473 case tpo_enumeration:
1475 for (i = 0; i < get_enumeration_n_enums(tp); ++i) {
1476 dump_enum_item(F, tp, i);
1477 print_enum_item_edge(F, tp, i, "label: \"item %d\"", i);
1482 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1490 break; /* case k_type */
1493 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1495 } /* switch kind_or_entity */
1498 typedef struct _h_env {
1503 /** For dumping class hierarchies.
1504 * Dumps a class type node and a superclass edge.
1505 * If env->dump_ent dumps entities of classes and overwrites edges.
1508 dump_class_hierarchy_node (type_or_ent *tore, void *ctx) {
1511 int i = 0; /* to shutup gcc */
1513 /* dump this type or entity */
1514 switch (get_kind(tore)) {
1516 entity *ent = (entity *)tore;
1517 if (get_entity_owner(ent) == get_glob_type()) break;
1518 if (!is_method_type(get_entity_type(ent))) break; /* GL */
1519 if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
1521 dump_entity_node(F, ent, 0);
1523 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1524 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1525 print_ent_ent_edge(F, get_entity_overwrites(ent, i), ent, 0, ENT_OVERWRITES_EDGE_ATTR);
1527 } break; /* case k_entity */
1530 type *tp = (type *)tore;
1531 if (tp == get_glob_type()) break;
1532 switch (get_type_tpop_code(tp)) {
1534 print_type_node(F, tp);
1535 /* and now the edges */
1536 for (i=0; i < get_class_n_supertypes(tp); i++)
1538 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1544 break; /* case k_type */
1547 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1549 } /* switch kind_or_entity */
1552 /*******************************************************************/
1553 /* dump analysis information that is expressed in graph terms. */
1554 /*******************************************************************/
1556 /* dump out edges */
1558 dump_out_edge(ir_node *n, void *env) {
1561 for (i = 0; i < get_irn_n_outs(n); i++) {
1562 assert(get_irn_out(n, i));
1563 fprintf (F, "edge: {sourcename: \"");
1565 fprintf (F, "\" targetname: \"");
1566 PRINT_NODEID(get_irn_out(n, i));
1567 fprintf (F, "\" color: red linestyle: dashed");
1573 dump_loop_label(FILE *F, ir_loop *loop) {
1574 fprintf (F, "loop %d, %d sons, %d nodes",
1575 get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1578 static INLINE void dump_loop_info(FILE *F, ir_loop *loop) {
1579 fprintf (F, " info1: \"");
1580 fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1581 #if DEBUG_libfirm /* GL @@@ debug analyses */
1582 fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1588 dump_loop_node(FILE *F, ir_loop *loop) {
1589 fprintf (F, "node: {title: \"");
1591 fprintf (F, "\" label: \"");
1592 dump_loop_label(F, loop);
1594 dump_loop_info(F, loop);
1600 dump_loop_node_edge(FILE *F, ir_loop *loop, int i) {
1602 fprintf (F, "edge: {sourcename: \"");
1604 fprintf (F, "\" targetname: \"");
1605 PRINT_NODEID(get_loop_node(loop, i));
1606 fprintf (F, "\" color: green");
1611 dump_loop_son_edge(FILE *F, ir_loop *loop, int i) {
1613 fprintf (F, "edge: {sourcename: \"");
1615 fprintf (F, "\" targetname: \"");
1616 PRINT_LOOPID(get_loop_son(loop, i));
1617 fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1618 get_loop_element_pos(loop, get_loop_son(loop, i)));
1622 void dump_loops(FILE *F, ir_loop *loop) {
1624 /* dump this loop node */
1625 dump_loop_node(F, loop);
1627 /* dump edges to nodes in loop -- only if it is a real loop */
1628 if (get_loop_depth(loop) != 0) {
1629 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1630 dump_loop_node_edge(F, loop, i);
1633 for (i = 0; i < get_loop_n_sons(loop); i++) {
1634 dump_loops(F, get_loop_son(loop, i));
1635 dump_loop_son_edge(F, loop, i);
1640 void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) {
1641 ir_graph *rem = current_ir_graph;
1642 current_ir_graph = irg;
1644 if (get_irg_loop(irg)) dump_loops(F, get_irg_loop(irg));
1646 current_ir_graph = rem;
1651 * dumps the VCG header
1654 dump_vcg_header(FILE *F, const char *name, const char *orientation) {
1663 if (!orientation) orientation = "bottom_to_top";
1667 "graph: { title: \"ir graph of %s\"\n"
1668 "display_edge_labels: %s\n"
1669 "layoutalgorithm: mindepth\n"
1670 "manhattan_edges: yes\n"
1671 "port_sharing: no\n"
1673 "classname 1: \"intrablock Data\"\n"
1674 "classname 16: \"interblock Data\"\n"
1675 "classname 2: \"Block\"\n"
1676 "classname 13: \"Control Flow\"\n"
1677 "classname 14: \"intrablock Memory\"\n"
1678 "classname 17: \"interblock Memory\"\n"
1679 "classname 15: \"Dominators\"\n"
1680 "classname 3: \"Entity type\"\n"
1681 "classname 4: \"Entity owner\"\n"
1682 "classname 5: \"Method Param\"\n"
1683 "classname 6: \"Method Res\"\n"
1684 "classname 7: \"Super\"\n"
1685 "classname 8: \"Union\"\n"
1686 "classname 9: \"Points-to\"\n"
1687 "classname 10: \"Array Element Type\"\n"
1688 "classname 11: \"Overwrites\"\n"
1689 "classname 12: \"Member\"\n"
1690 "infoname 1: \"Attribute\"\n"
1691 "infoname 2: \"Verification errors\"\n",
1692 name, label, orientation);
1694 /* don't use all, the range is too whith/black. */
1698 "colorentry 100: 0 0 0\n"
1699 "colorentry 101: 20 0 0\n"
1700 "colorentry 102: 40 0 0\n"
1701 "colorentry 103: 60 0 0\n"
1702 "colorentry 104: 80 0 0\n"
1703 "colorentry 105: 100 0 0\n"
1704 "colorentry 106: 120 0 0\n"
1705 "colorentry 107: 140 0 0\n"
1706 "colorentry 108: 150 0 0\n"
1707 "colorentry 109: 180 0 0\n"
1708 "colorentry 110: 200 0 0\n"
1709 "colorentry 111: 220 0 0\n"
1710 "colorentry 112: 240 0 0\n"
1711 "colorentry 113: 255 0 0\n"
1712 "colorentry 113: 255 20 20\n"
1713 "colorentry 114: 255 40 40\n"
1714 "colorentry 115: 255 60 60\n"
1715 "colorentry 116: 255 80 80\n"
1716 "colorentry 117: 255 100 100\n"
1717 "colorentry 118: 255 120 120\n"
1718 "colorentry 119: 255 140 140\n"
1719 "colorentry 120: 255 150 150\n"
1720 "colorentry 121: 255 180 180\n"
1721 "colorentry 122: 255 200 200\n"
1722 "colorentry 123: 255 220 220\n"
1723 "colorentry 124: 255 240 240\n"
1724 "colorentry 125: 255 250 250\n"
1727 fprintf (F, "\n"); /* a separator */
1733 * @param irg The graph to be dumped
1734 * @param suffix1 first filename suffix
1735 * @param suffix2 second filename suffix
1737 static FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) {
1739 const char *nm = get_irg_dump_name(irg);
1740 int len = strlen(nm), i, j;
1741 char *fname; /* filename to put the vcg information in */
1743 if (!suffix1) suffix1 = "";
1744 if (!suffix2) suffix2 = "";
1746 /* open file for vcg graph */
1747 fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5);
1749 /* strncpy (fname, nm, len); */ /* copy the filename */
1751 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1753 fname[j] = '@'; j++; fname[j] = '1'; j++;
1754 } else if (nm[i] == '@') {
1755 fname[j] = '@'; j++; fname[j] = '2'; j++;
1757 fname[j] = nm[i]; j++;
1761 strcat (fname, suffix1); /* append file suffix */
1762 strcat (fname, suffix2); /* append file suffix */
1763 strcat (fname, ".vcg"); /* append the .vcg suffix */
1764 F = fopen (fname, "w"); /* open file for writing */
1766 panic("cannot open %s for writing (%m)", fname); /* not reached */
1776 * @param irg The graph to be dumped
1777 * @param suffix filename suffix
1779 static FILE *vcg_open_name (const char *name, const char *suffix) {
1781 char *fname; /* filename to put the vcg information in */
1782 int i, j, len = strlen(name);
1784 if (!suffix) suffix = "";
1786 /** open file for vcg graph */
1787 fname = malloc (len * 2 + 5 + strlen(suffix));
1788 /* strcpy (fname, name);*/ /* copy the filename */
1790 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
1791 if (name[i] == '/') {
1792 fname[j] = '@'; j++; fname[j] = '1'; j++;
1793 } else if (name[i] == '@') {
1794 fname[j] = '@'; j++; fname[j] = '2'; j++;
1796 fname[j] = name[i]; j++;
1800 strcat (fname, suffix);
1801 strcat (fname, ".vcg"); /* append the .vcg suffix */
1802 F = fopen (fname, "w"); /* open file for writing */
1804 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1812 * Dumps the vcg file footer
1814 static INLINE void dump_vcg_footer (FILE *F) {
1819 * close the vcg file
1822 vcg_close (FILE *F) {
1823 dump_vcg_footer(F); /* print footer */
1824 fclose (F); /* close vcg file */
1827 /************************************************************************/
1828 /************************************************************************/
1829 /* Routines that dump all or parts of the firm representation to a file */
1830 /************************************************************************/
1831 /************************************************************************/
1833 /************************************************************************/
1834 /* Dump ir graphs, differnt formats and additional information. */
1835 /************************************************************************/
1837 /** Routine to dump a graph, blocks as conventional nodes.
1840 dump_ir_graph (ir_graph *irg, const char *suffix )
1845 rem = current_ir_graph;
1847 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
1848 current_ir_graph = irg;
1849 if (interprocedural_view) suffix1 = "-pure-ip";
1850 else suffix1 = "-pure";
1851 f = vcg_open(irg, suffix, suffix1);
1852 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1854 /* walk over the graph */
1855 /* dump_whole_node must be called in post visiting predecessors */
1856 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1858 /* dump the out edges in a separate walk */
1859 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
1860 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1865 current_ir_graph = rem;
1870 dump_ir_block_graph (ir_graph *irg, const char *suffix)
1876 if(strncmp(get_entity_name(get_irg_entity(irg)),dump_file_filter,strlen(dump_file_filter))!=0) return;
1877 if (interprocedural_view) suffix1 = "-ip";
1879 f = vcg_open(irg, suffix, suffix1);
1880 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1882 construct_block_lists(irg);
1884 for (i = 0; i < get_irp_n_irgs(); i++) {
1885 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1887 dump_graph(f, get_irp_irg(i));
1895 /** dumps a graph with type information
1898 dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
1901 ir_graph *rem = current_ir_graph;
1904 /* if a filter is set, dump only the irg's that match the filter */
1905 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1908 current_ir_graph = irg;
1910 if (interprocedural_view) suffix1 = "-pure-wtypes-ip";
1911 else suffix1 = "-pure-wtypes";
1912 f = vcg_open(irg,suffix, suffix1);
1913 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1915 /* dump common ir graph */
1916 irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1917 /* dump type info */
1918 type_walk_irg(irg, dump_type_info, NULL, f);
1919 inc_irg_visited(get_const_code_irg());
1920 /* dump edges from graph to type info */
1921 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1924 current_ir_graph = rem;
1928 dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
1933 ir_graph *rem = current_ir_graph;
1935 /* if a filter is set, dump only the irg's that match the filter */
1936 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1939 if (interprocedural_view) suffix1 = "-wtypes-ip";
1940 else suffix1 = "-wtypes";
1941 f = vcg_open(irg, suffix, suffix1);
1942 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1944 /* dump common blocked ir graph */
1945 construct_block_lists(irg);
1947 for (i = 0; i < get_irp_n_irgs(); i++) {
1948 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1950 dump_graph(f, get_irp_irg(i));
1955 /* dump type info */
1956 current_ir_graph = irg;
1957 type_walk_irg(irg, dump_type_info, NULL, f);
1958 inc_irg_visited(get_const_code_irg());
1960 /* dump edges from graph to type info */
1961 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1963 current_ir_graph = rem;
1967 /*---------------------------------------------------------------------*/
1968 /* The following routines dump a control flow graph. */
1969 /*---------------------------------------------------------------------*/
1972 dump_block_to_cfg(ir_node *block, void *env) {
1977 if (is_Block(block)) {
1978 /* This is a block. Dump a node for the block. */
1979 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1980 fprintf (F, "\" label: \"");
1981 if (block == get_irg_start_block(get_irn_irg(block)))
1982 fprintf(F, "Start ");
1983 if (block == get_irg_end_block(get_irn_irg(block)))
1986 fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1987 PRINT_NODEID(block);
1989 fprintf(F, "info1:\"");
1990 if (dump_dominator_information_flag)
1991 fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
1993 /* show arity and possible Bad predecessors of the block */
1994 fprintf(F, "arity: %d\n", get_Block_n_cfgpreds(block));
1995 for (fl = i = 0; i < get_Block_n_cfgpreds(block); ++i) {
1996 ir_node *pred = get_Block_cfgpred(block, i);
1999 fprintf(F, "Bad pred at pos: ");
2000 fprintf(F, "%d ", i);
2007 fprintf (F, "\""); /* closing quote of info */
2009 if ((block == get_irg_start_block(get_irn_irg(block))) ||
2010 (block == get_irg_end_block(get_irn_irg(block))) )
2011 fprintf(F, " color:blue ");
2013 fprintf(F, " color:yellow ");
2016 /* Dump the edges */
2017 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
2018 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
2019 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
2020 fprintf (F, "edge: { sourcename: \"");
2021 PRINT_NODEID(block);
2022 fprintf (F, "\" targetname: \"");
2024 fprintf (F, "\"}\n");
2027 /* Dump dominator edge */
2028 if (dump_dominator_information_flag && get_Block_idom(block)) {
2029 pred = get_Block_idom(block);
2030 fprintf (F, "edge: { sourcename: \"");
2031 PRINT_NODEID(block);
2032 fprintf (F, "\" targetname: \"");
2034 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
2040 dump_cfg (ir_graph *irg, const char *suffix)
2043 ir_graph *rem = current_ir_graph;
2044 int ddif = dump_dominator_information_flag;
2045 int ipv = interprocedural_view;
2047 /* if a filter is set, dump only the irg's that match the filter */
2048 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2051 current_ir_graph = irg;
2053 f = vcg_open(irg, suffix, "-cfg");
2054 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2056 if (interprocedural_view) {
2057 printf("Warning: dumping cfg not in interprocedural view!\n");
2058 interprocedural_view = 0;
2061 if (get_irg_dom_state(irg) != dom_consistent)
2062 dump_dominator_information_flag = 0;
2064 /* walk over the blocks in the graph */
2065 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f);
2066 dump_node(f, get_irg_bad(irg));
2068 dump_dominator_information_flag = ddif;
2069 interprocedural_view = ipv;
2071 current_ir_graph = rem;
2074 static int weight_overall(int rec, int loop) {
2075 return 2*rec + loop;
2078 static int compute_color (int my, int max) {
2083 /* if small, scale to the full color range. */
2085 my = my * (n_colors/max);
2087 int step = 1 + (max / n_colors);
2091 return base_color + n_colors - color;
2094 static int get_entity_color(entity *ent) {
2095 assert(get_entity_irg(ent));
2096 ir_graph *irg = get_entity_irg(ent);
2098 int rec_depth = get_irg_recursion_depth(irg);
2099 int loop_depth = get_irg_loop_depth(irg);
2100 int overall_depth = weight_overall(rec_depth, loop_depth);
2102 int max_rec_depth = irp->max_callgraph_recursion_depth;
2103 int max_loop_depth = irp->max_callgraph_loop_depth;
2104 int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
2106 int my_rec_color = compute_color(rec_depth, max_rec_depth);
2107 int my_loop_color = compute_color(loop_depth, max_loop_depth);
2108 int my_overall_color = compute_color(overall_depth, max_overall_depth);;
2110 return my_overall_color;
2113 void dump_callgraph(const char *suffix) {
2115 int i, n_irgs = get_irp_n_irgs();
2116 int rem = edge_label;
2118 //ident *prefix = new_id_from_str("java/");
2120 F = vcg_open_name("Callgraph", suffix);
2121 dump_vcg_header(F, "Callgraph", NULL);
2123 for (i = 0; i < n_irgs; ++i) {
2124 ir_graph *irg = get_irp_irg(i);
2125 entity *ent = get_irg_entity(irg);
2126 int j, n_callees = get_irg_n_callees(irg);
2128 /* Do not dump runtime system. */
2129 //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
2131 dump_entity_node(F, ent, get_entity_color(ent));
2132 for (j = 0; j < n_callees; ++j) {
2133 entity *c = get_irg_entity(get_irg_callee(irg, j));
2134 //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
2135 int be = is_irg_callee_backedge(irg, j);
2138 "label:\"recursion %d\" color: %d" :
2139 "label:\"calls %d\" color: %d";
2140 print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
2148 /* Dump all irgs in interprocedural view to a single file. */
2149 void dump_all_cg_block_graph(const char *suffix) {
2152 int rem_view = interprocedural_view;
2153 interprocedural_view = 1;
2155 f = vcg_open_name("All_graphs", suffix);
2156 dump_vcg_header(f, "All_graphs", NULL);
2158 /* collect nodes in all irgs reachable in call graph*/
2159 for (i = 0; i < get_irp_n_irgs(); i++)
2160 ird_set_irg_link(get_irp_irg(i), NULL);
2162 cg_walk(clear_link, collect_node, NULL);
2164 /* dump all graphs */
2165 for (i = 0; i < get_irp_n_irgs(); i++) {
2166 current_ir_graph = get_irp_irg(i);
2167 assert(ird_get_irg_link(current_ir_graph));
2168 dump_graph(f, current_ir_graph);
2169 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
2173 interprocedural_view = rem_view;
2176 /***********************************************************************/
2177 /* the following routines dumps type information without any ir nodes. */
2178 /***********************************************************************/
2181 dump_type_graph (ir_graph *irg, const char *suffix)
2185 rem = current_ir_graph;
2187 /* if a filter is set, dump only the irg's that match the filter */
2188 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
2190 current_ir_graph = irg;
2192 f = vcg_open(irg, suffix, "-type");
2193 dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2195 /* walk over the blocks in the graph */
2196 type_walk_irg(irg, dump_type_info, NULL, f);
2197 /* The walker for the const code can be called several times for the
2198 same (sub) experssion. So that no nodes are dumped several times
2199 we decrease the visited flag of the corresponding graph after each
2200 walk. So now increase it finally. */
2201 inc_irg_visited(get_const_code_irg());
2204 current_ir_graph = rem;
2208 dump_all_types (const char *suffix)
2210 FILE *f = vcg_open_name("All_types", suffix);
2211 dump_vcg_header(f, "All_types", NULL);
2212 type_walk(dump_type_info, NULL, f);
2213 inc_irg_visited(get_const_code_irg());
2218 dump_class_hierarchy (bool entities, const char *suffix)
2220 FILE *f = vcg_open_name("class_hierarchy", suffix);
2224 dump_vcg_header(f, "class_hierarchy", NULL);
2229 type_walk(dump_class_hierarchy_node, NULL, &env);
2233 /***********************************************************************/
2234 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
2236 /* dump_ir_block_graph */
2238 /* dump_type_graph */
2239 /* dump_ir_graph_w_types */
2240 /***********************************************************************/
2242 void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) {
2244 for (i=0; i < get_irp_n_irgs(); i++) {
2245 dmp_grph(get_irp_irg(i), suffix);
2250 /**********************************************************************************
2251 * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes *
2252 * packed together in one subgraph/box *
2253 **********************************************************************************/
2255 void dump_loops_standalone(FILE *F, ir_loop *loop) {
2256 int i = 0, loop_node_started = 0, son_number = 0, first = 0;
2258 ir_loop *son = NULL;
2260 /* Dump a new loop node. */
2261 dump_loop_node(F, loop);
2263 /* Dump the loop elements. */
2265 for(i = 0; i < get_loop_n_elements(loop); i++) {
2266 le = get_loop_element(loop, i);
2268 if (get_kind(son) == k_ir_loop) {
2270 /* We are a loop son -> Recurse */
2272 if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
2273 fprintf(F, "\" }\n");
2274 fprintf (F, "edge: {sourcename: \"");
2276 fprintf (F, "\" targetname: \"");
2278 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2279 loop_node_started = 0;
2281 dump_loop_son_edge(F, loop, son_number++);
2282 dump_loops_standalone(F, son);
2283 } else if (get_kind(son) == k_ir_node) {
2284 /* We are a loop node -> Collect firm nodes */
2286 ir_node *n = le.node;
2289 if (!loop_node_started) {
2290 /* Start a new node which contains all firm nodes of the current loop */
2291 fprintf (F, "node: { title: \"");
2293 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2294 loop_node_started = 1;
2300 bad |= dump_node_opcode(F, n);
2301 bad |= dump_node_mode(F, n);
2302 bad |= dump_node_typeinfo(F, n);
2304 bad |= dump_node_nodeattr(F, n);
2305 fprintf (F, " %ld", get_irn_node_nr(n));
2306 if (is_Block(n)) fprintf (F, "\t ->%d", (int)get_irn_link(n));
2307 } else { /* for callgraph loop tree */
2308 assert(get_kind(son) == k_ir_graph);
2309 /* We are a loop node -> Collect firm graphs */
2310 ir_graph *n = (ir_graph *)le.node;
2311 if (!loop_node_started) {
2312 /* Start a new node which contains all firm nodes of the current loop */
2313 fprintf (F, "node: { title: \"");
2315 fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2316 loop_node_started = 1;
2321 fprintf (F, " %s", get_irg_dump_name(n));
2322 /* fprintf (F, " %s (depth %d)", get_irg_dump_name(n), n->callgraph_weighted_loop_depth); */
2326 if (loop_node_started) {
2327 fprintf(F, "\" }\n");
2328 fprintf (F, "edge: {sourcename: \"");
2330 fprintf (F, "\" targetname: \"");
2332 fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2333 loop_node_started = 0;
2337 void dump_loop_tree(ir_graph *irg, const char *suffix)
2340 ir_graph *rem = current_ir_graph;
2341 int el_rem = edge_label;
2344 /* if a filter is set, dump only the irg's that match the filter */
2345 if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2348 current_ir_graph = irg;
2350 f = vcg_open(irg, suffix, "-looptree");
2351 dump_vcg_header(f, get_irg_dump_name(irg), "top_to_bottom");
2353 if (get_irg_loop(irg)) dump_loops_standalone(f, get_irg_loop(irg));
2357 edge_label = el_rem;
2358 current_ir_graph = rem;
2361 void dump_callgraph_loop_tree(const char *suffix) {
2363 F = vcg_open_name("Callgraph_looptree", suffix);
2364 dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
2365 dump_loops_standalone(F, irp->outermost_cg_loop);
2370 /*******************************************************************************/
2371 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
2372 /*******************************************************************************/
2374 void collect_nodeloop(FILE *F, ir_loop *loop, eset *loopnodes) {
2375 int i, son_number = 0, node_number = 0;
2377 if (dump_loop_information_flag) dump_loop_node(F, loop);
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) {
2382 if (dump_loop_information_flag) dump_loop_son_edge(F, loop, son_number++);
2384 collect_nodeloop(F, le.son, loopnodes);
2386 if (dump_loop_information_flag) dump_loop_node_edge(F, loop, node_number++);
2387 eset_insert(loopnodes, le.node);
2392 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
2395 for(i = 0; i < get_loop_n_elements(loop); i++) {
2396 loop_element le = get_loop_element(loop, i);
2397 if (*(le.kind) == k_ir_loop) {
2399 collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
2401 if (is_Block(le.node)) start = 0; else start = -1;
2402 for (j = start; j < get_irn_arity(le.node); j++) {
2403 ir_node *pred = get_irn_n(le.node, j);
2404 if (!eset_contains(loopnodes, pred)) {
2405 eset_insert(extnodes, pred);
2406 if (!is_Block(pred)) {
2407 pred = get_nodes_block(pred);
2408 if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
2416 void dump_loop(ir_loop *l, const char *suffix) {
2419 eset *loopnodes = eset_create();
2420 eset *extnodes = eset_create();
2423 snprintf(name, sizeof(name), "loop_%d", get_loop_loop_nr(l));
2424 F = vcg_open_name (name, suffix);
2425 dump_vcg_header(F, name, NULL);
2427 /* collect all nodes to dump */
2428 collect_nodeloop(F, l, loopnodes);
2429 collect_nodeloop_external_nodes(l, loopnodes, extnodes);
2431 /* build block lists */
2432 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2433 set_irn_link(n, NULL);
2434 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2435 set_irn_link(n, NULL);
2436 for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2438 b = get_nodes_block(n);
2439 set_irn_link(n, get_irn_link(b));
2442 for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2444 b = get_nodes_block(n);
2445 set_irn_link(n, get_irn_link(b));
2449 for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2451 fprintf(F, "graph: { title: \"");
2453 fprintf(F, "\" label: \"");
2454 dump_node_opcode(F, b);
2455 fprintf (F, " %ld", get_irn_node_nr(b));
2456 fprintf(F, "\" status:clustered color:yellow\n");
2458 /* dump the blocks edges */
2459 dump_ir_data_edges(F, b);
2461 /* dump the nodes that go into the block */
2462 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2463 if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2465 overrule_nodecolor = NULL;
2466 if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n);
2469 /* Close the vcg information for the block */
2471 dump_const_node_local(F, b);
2474 for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2476 fprintf(F, "graph: { title: \"");
2478 fprintf(F, "\" label: \"");
2479 dump_node_opcode(F, b);
2480 fprintf (F, " %ld", get_irn_node_nr(b));
2481 fprintf(F, "\" status:clustered color:lightblue\n");
2483 /* dump the nodes that go into the block */
2484 for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2485 if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2487 overrule_nodecolor = NULL;
2488 if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n);
2491 /* Close the vcg information for the block */
2493 dump_const_node_local(F, b);
2497 eset_destroy(loopnodes);
2498 eset_destroy(extnodes);