Call_calleesl now with unknown entity instead of NULL.
[libfirm] / ir / ir / irdump.c
1 /*
2  * Project:     libFIRM
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
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stdarg.h>
17
18 #include "firm_common_t.h"
19
20 #include "irnode_t.h"
21 #include "irgraph_t.h"
22 #include "irprog_t.h"
23 #include "entity_t.h"
24 #include "irop_t.h"
25
26 #include "irdump.h"
27 #include "irdump_t.h"
28
29 #include "irgwalk.h"
30 #include "typewalk.h"
31 #include "tv_t.h"
32 #include "type_or_entity.h"
33 #include "irouts.h"
34 #include "irdom.h"
35 #include "irloop.h"
36 #include "callgraph.h"
37
38 #include "irvrfy.h"
39
40 #include "panic.h"
41 #include "array.h"
42 #include "pmap.h"
43 #include "eset.h"
44
45 #if DO_HEAPANALYSIS
46 void dump_chi_term(FILE *FL, ir_node *n);
47 void dump_state(FILE *FL, ir_node *n);
48 int  get_opt_dump_abstvals(void);
49 typedef unsigned long SeqNo;
50 SeqNo get_Block_seqno(ir_node *n);
51 #endif
52
53 /* basis for a color range for vcg */
54 static int n_colors   = 0;
55 static int base_color = 0;
56
57 static const char *get_mode_name_ex(ir_mode *mode, int *bad)
58 {
59   if (is_mode(mode))
60     return get_mode_name(mode);
61   *bad |= 1;
62   return "<ERROR>";
63 }
64
65 static const char *get_type_name_ex(type *tp, int *bad)
66 {
67   if (is_type(tp))
68     return get_type_name(tp);
69   *bad |= 1;
70   return "<ERROR>";
71 }
72
73 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
74 {
75   va_list ap;
76
77   va_start(ap, fmt);
78   fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
79   fprintf(F, " targetname: "); PRINT_TYPEID(T);
80   vfprintf(F, fmt, ap);
81   fprintf(F,"}\n");
82   va_end(ap);
83 }
84
85 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
86 {
87   va_list ap;
88
89   va_start(ap, fmt);
90   fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
91   fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
92   vfprintf(F, fmt, ap);
93   fprintf(F, "}\n");
94   va_end(ap);
95 }
96
97 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, const char *fmt, ...)
98 {
99   va_list ap;
100
101   va_start(ap, fmt);
102   if (backedge)
103     fprintf(F, "backedge: { sourcename: \"");
104    else
105     fprintf(F, "edge: { sourcename: \"");
106   PRINT_ENTID(E);
107   fprintf(F, "\" targetname: \""); PRINT_ENTID(T);  fprintf(F, "\"");
108   vfprintf(F, fmt, ap);
109   fprintf(F, "}\n");
110   va_end(ap);
111 }
112
113 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
114 {
115   va_list ap;
116
117   va_start(ap, fmt);
118   fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
119   fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
120   vfprintf(F, fmt, ap);
121   fprintf(F,"}\n");
122   va_end(ap);
123 }
124
125 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
126 {
127   va_list ap;
128
129   va_start(ap, fmt);
130   fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
131   fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
132   vfprintf(F, fmt, ap);
133   fprintf(F,"}\n");
134   va_end(ap);
135 }
136
137 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
138 {
139   va_list ap;
140
141   va_start(ap, fmt);
142   fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
143   fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
144   fprintf(F, "\"");
145   vfprintf(F, fmt, ap);
146   fprintf(F,"}\n");
147   va_end(ap);
148 }
149
150 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
151 {
152   va_list ap;
153
154   va_start(ap, fmt);
155   fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
156   fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
157   vfprintf(F, fmt, ap);
158   fprintf(F,"}\n");
159   va_end(ap);
160 }
161
162 static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...)
163 {
164   va_list ap;
165
166   va_start(ap, fmt);
167   fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(E);
168   fprintf(F, " targetname: \""); PRINT_ITEMID(E, item); fprintf(F, "\" ");
169   vfprintf(F, fmt, ap);
170   fprintf(F,"}\n");
171   va_end(ap);
172 }
173
174 /*******************************************************************/
175 /* global and ahead declarations                                   */
176 /*******************************************************************/
177
178 static void dump_whole_node(ir_node *n, void *env);
179 static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
180
181 /*******************************************************************/
182 /* Helper functions.                                                */
183 /*******************************************************************/
184
185 /* Use private link attr to be able to call dumper anywhere without
186    destroying link fields. */
187
188 static pmap *irdump_link_map = NULL;
189
190 static void init_irdump(void) {
191   /* We need a new, empty map. */
192   if (irdump_link_map) pmap_destroy(irdump_link_map);
193   irdump_link_map = pmap_create();
194 }
195
196
197 void *ird_get_irn_link(ir_node *n) {
198   void *res = NULL;
199   if (!irdump_link_map) return NULL;
200
201   if (pmap_contains(irdump_link_map, (void *)n))
202     res = pmap_get(irdump_link_map, (void *)n);
203   return res;
204 }
205
206 void ird_set_irn_link(ir_node *n, void *x) {
207   if (!irdump_link_map) init_irdump();
208   pmap_insert(irdump_link_map, (void *)n, x);
209 }
210
211 void *ird_get_irg_link(ir_graph *irg) {
212   void *res = NULL;
213   if (!irdump_link_map) return NULL;
214
215   if (pmap_contains(irdump_link_map, (void *)irg))
216     res = pmap_get(irdump_link_map, (void *)irg);
217   return res;
218 }
219
220 void ird_set_irg_link(ir_graph *irg, void *x) {
221   if (!irdump_link_map) init_irdump();
222   pmap_insert(irdump_link_map, (void *)irg, x);
223 }
224
225 static void clear_link(ir_node * node, void * env) {
226   ird_set_irn_link(node, NULL);
227 }
228
229
230 static int node_floats(ir_node *n) {
231   return ((get_irn_pinned(n) == op_pin_state_floats) &&
232       (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
233 }
234
235 const char *get_ent_dump_name(entity *ent) {
236   if (!ent)
237     return "<NULL entity>";
238   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
239   if (ent->ld_name) return get_id_str(ent->ld_name);
240   return get_id_str(ent->name);
241 }
242
243 const char *get_irg_dump_name(ir_graph *irg) {
244   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
245   entity *ent = get_irg_entity(irg);
246   return get_ent_dump_name(ent);
247 }
248
249 static void collect_node(ir_node * node, void *env) {
250   if (is_Block(node)
251       || node_floats(node)
252       || get_irn_op(node) == op_Bad
253       || get_irn_op(node) == op_Unknown) {
254     ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
255     if (!arr) arr = NEW_ARR_F(ir_node *, 0);
256     ARR_APP1(ir_node *, arr, node);
257     ird_set_irg_link(get_irn_irg(node), arr);    /* arr is an l-value, APP_ARR might change it! */
258   } else {
259     ir_node * block = get_nodes_block(node);
260     ird_set_irn_link(node, ird_get_irn_link(block));
261     ird_set_irn_link(block, node);
262   }
263 }
264
265 /** Construct lists to walk ir block-wise.
266  *
267  * Collects all blocks, nodes not op_pin_state_pinned,
268  * Bad and Unknown into a flexible array in link field of
269  * irg they belong to.  Sets the irg link field to NULL in all
270  * graphs not visited.
271  * Free the list with DEL_ARR_F.  */
272 static ir_node ** construct_block_lists(ir_graph *irg) {
273   int i, rem_view = get_interprocedural_view();
274   ir_graph *rem = current_ir_graph;
275   current_ir_graph = irg;
276
277   for (i = 0; i < get_irp_n_irgs(); i++)
278     ird_set_irg_link(get_irp_irg(i), NULL);
279
280   irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
281
282   /* Collect also EndReg and EndExcept. We do not want to change the walker. */
283   set_interprocedural_view(false);
284   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
285   irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
286   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
287   irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
288   set_interprocedural_view(rem_view);
289
290   current_ir_graph = rem;
291   return ird_get_irg_link(irg);
292 }
293
294 /*******************************************************************/
295 /* flags to steer output                                           */
296 /*******************************************************************/
297
298 const char *dump_file_filter = "";
299
300 /* A compiler option to turn off edge labels */
301 int edge_label = 1;
302 /* A compiler option to turn off dumping values of constant entities */
303 int const_entities = 1;
304 /* A compiler option to dump the keep alive edges */
305 int dump_keepalive = 0;
306 /* Compiler options to dump analysis information in dump_ir_graph */
307 int dump_out_edge_flag = 0;
308 int dump_dominator_information_flag = 0;
309 int dump_loop_information_flag = 0;
310 int dump_backedge_information_flag = 1;
311 int dump_const_local = 0;
312 bool opt_dump_analysed_type_info = 1;
313 bool opt_dump_pointer_values_to_info = 0;  /* default off: for test compares!! */
314
315 char* overrule_nodecolor = NULL;
316
317 INLINE bool get_opt_dump_const_local(void) {
318   if (!dump_out_edge_flag && !dump_loop_information_flag)
319     return dump_const_local;
320   else
321     return false;
322 }
323
324 void only_dump_method_with_name(ident *name) {
325   dump_file_filter = get_id_str(name);
326 }
327
328
329 /* To turn off display of edge labels.  Edge labels offen cause xvcg to
330    abort with a segmentation fault. */
331 void turn_off_edge_labels(void) {
332   edge_label = 0;
333 }
334
335 void dump_consts_local(bool b) {
336   dump_const_local = b;
337 }
338
339 void turn_off_constant_entity_values(void) {
340   const_entities = 0;
341 }
342
343 void dump_keepalive_edges(bool b) {
344   dump_keepalive = b;
345 }
346
347 bool get_opt_dump_keepalive_edges(void) {
348   return dump_keepalive;
349 }
350
351 void dump_out_edges(void) {
352   dump_out_edge_flag = 1;
353 }
354
355 void dump_dominator_information(void) {
356   dump_dominator_information_flag = 1;
357 }
358
359 void dump_loop_information(void) {
360   dump_loop_information_flag = 1;
361 }
362
363 void dont_dump_loop_information(void) {
364   dump_loop_information_flag = 0;
365 }
366
367 void dump_backedge_information(bool b) {
368   dump_backedge_information_flag = b;
369 }
370
371 /* Dump the information of type field specified in ana/irtypeinfo.h.
372  * If the flag is set, the type name is output in [] in the node label,
373  * else it is output as info.
374  */
375 void dump_analysed_type_info(bool b) {
376   opt_dump_analysed_type_info = b;
377 }
378
379 void dump_pointer_values_to_info(bool b) {
380   opt_dump_pointer_values_to_info = b;
381 }
382
383 /*-----------------------------------------------------------------*/
384 /* Routines to dump information about a single ir node.            */
385 /*-----------------------------------------------------------------*/
386
387 INLINE int
388 dump_node_opcode(FILE *F, ir_node *n)
389 {
390   int bad = 0;
391
392   switch(get_irn_opcode(n)) {
393
394   case iro_Const: {
395     int res;
396     char buf[1024];
397     res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
398     assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
399     fprintf(F, buf);
400   } break;
401
402   case iro_SymConst: {
403     if (get_SymConst_kind(n) == symconst_addr_name) {
404       /* don't use get_SymConst_ptr_info as it mangles the name. */
405       fprintf (F, "SymC %s", get_id_str(get_SymConst_name(n)));
406     } else if (get_SymConst_kind(n) == symconst_addr_ent) {
407       assert(get_SymConst_entity(n));
408       assert(is_entity(get_SymConst_entity(n)));
409       fprintf (F, "SymC &%s", get_entity_name(get_SymConst_entity(n)));
410     } else {
411       assert(get_kind(get_SymConst_type(n)) == k_type);
412       assert(get_type_ident(get_SymConst_type(n)));
413       fprintf (F, "SymC %s ", get_type_name_ex(get_SymConst_type(n), &bad));
414       if (get_SymConst_kind(n) == symconst_type_tag)
415         fprintf (F, "tag");
416       else
417         fprintf (F, "size");
418     }
419   } break;
420
421   case iro_Filter: {
422     if (!get_interprocedural_view())
423       fprintf(F, "Proj'");
424     else
425       goto default_case;
426   } break;
427
428   case iro_Proj: {
429     ir_node *pred = get_Proj_pred(n);
430
431     if (get_irn_opcode(pred) == iro_Cond
432         && get_Proj_proj(n) == get_Cond_defaultProj(pred)
433         && get_irn_mode(get_Cond_selector(pred)) != mode_b)
434       fprintf (F, "defProj");
435 /*
436  *   else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
437  *     fprintf (F, "Arg");
438  */
439     else
440       goto default_case;
441   } break;
442   case iro_Start:
443   case iro_End:
444   case iro_EndExcept:
445   case iro_EndReg: {
446     if (get_interprocedural_view()) {
447       fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_entity(get_irn_irg(n))));
448       break;
449     } else
450       goto default_case;
451   }
452   case iro_CallBegin: {
453     ir_node *addr = get_CallBegin_ptr(n);
454     entity *ent = NULL;
455     if (get_irn_op(addr) == op_Sel)
456       ent = get_Sel_entity(addr);
457     else if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind(addr) == symconst_addr_ent))
458       ent = get_SymConst_entity(addr);
459     fprintf (F, "%s", get_irn_opname(n));
460     if (ent) fprintf (F, " %s", get_entity_name(ent));
461     break;
462   }
463   case iro_Load:
464     fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
465     break;
466
467 default_case:
468   default: {
469     fprintf (F, "%s", get_irn_opname(n));
470   }
471
472   }  /* end switch */
473   return bad;
474 }
475
476 static INLINE int
477 dump_node_mode(FILE *F, ir_node *n)
478 {
479   int bad = 0;
480   opcode iro = get_irn_opcode(n);
481
482   switch (iro) {
483     case iro_SymConst:
484     case iro_Sel:
485     case iro_End:
486     case iro_Return:
487     case iro_Free:
488     case iro_Sync:
489     case iro_Jmp:
490       break;
491     default: {
492       ir_mode *mode = get_irn_mode(n);
493
494       if (mode && mode != mode_BB && mode != mode_ANY && mode != mode_BAD &&
495           (mode != mode_T || iro == iro_Proj))
496         fprintf(F, "%s", get_mode_name_ex(mode, &bad));
497     }
498   }
499
500   return bad;
501 }
502
503 static int dump_node_typeinfo(FILE *F, ir_node *n) {
504   int bad = 0;
505
506   if (opt_dump_analysed_type_info) {
507     if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent  ||
508         get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent) {
509       type *tp = get_irn_typeinfo_type(n);
510       if (tp != none_type)
511         fprintf(F, " [%s]", get_type_name_ex(tp, &bad));
512       else
513         fprintf(F, " []");
514     }
515   }
516   return bad;
517 }
518
519 static INLINE int
520 dump_node_nodeattr(FILE *F, ir_node *n)
521 {
522   int bad = 0;
523
524   switch (get_irn_opcode(n)) {
525   case iro_Start:
526     if (false && get_interprocedural_view()) {
527       fprintf (F, "%s", get_ent_dump_name(get_irg_entity(current_ir_graph)));
528     }
529     break;
530   case iro_Proj:
531     if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
532       fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
533     } else {
534       fprintf (F, "%ld", get_Proj_proj(n));
535     }
536     break;
537   case iro_Filter:
538     fprintf (F, "%ld", get_Filter_proj(n));
539     break;
540   case iro_Sel: {
541     fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
542     } break;
543   case iro_Cast: {
544     fprintf (F, "(%s)", get_type_name_ex(get_Cast_type(n), &bad));
545     } break;
546   case iro_Confirm: {
547     fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
548     } break;
549
550   default:
551     ;
552   } /* end switch */
553
554   return bad;
555 }
556
557 static INLINE void dump_node_vcgattr(FILE *F, ir_node *n, int bad)
558 {
559   if (bad) {
560     fprintf(F, "color: red");
561     return;
562   }
563   switch (get_irn_opcode(n)) {
564   case iro_Start:
565   case iro_EndReg:
566     /* fall through */
567   case iro_EndExcept:
568     /* fall through */
569   case iro_End:
570     fprintf (F, "color: blue");
571     break;
572   case iro_Block:
573     fprintf (F, "color: lightyellow");
574     break;
575   case iro_Phi:
576     fprintf (F, "color: green");
577     break;
578   case iro_Const:
579   case iro_Proj:
580   case iro_Filter:
581   case iro_Tuple:
582     fprintf (F, "color: yellow");
583     break;
584   default:
585     PRINT_DEFAULT_NODE_ATTR;
586   }
587
588   if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
589 }
590
591 static INLINE int dump_node_info(FILE *F, ir_node *n)
592 {
593   int i, bad = 0;
594   char comma;
595   ir_graph *irg;
596
597   fprintf (F, " info1: \"");
598   if (opt_dump_pointer_values_to_info)
599     fprintf (F, "addr:    %p \n", (void *)n);
600   fprintf (F, "mode:    %s\n", get_mode_name(get_irn_mode(n)));
601   fprintf (F, "visited: %ld \n", get_irn_visited(n));
602   irg = get_irn_irg(n);
603   if (irg != get_const_code_irg())
604     fprintf (F, "irg:     %s\n", get_ent_dump_name(get_irg_entity(irg)));
605
606   if (get_irn_pinned(n) == op_pin_state_floats &&
607       get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
608     fprintf(F, "node was pinned in ");
609     dump_node_opcode(F, get_nodes_block(n));
610     fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
611   }
612
613 #if 0
614   /* show all predecessor nodes */
615   fprintf(F, "pred nodes: \n");
616   if (!is_Block(n)) {
617     fprintf(F, "  -1: ");
618     dump_node_opcode(F, get_nodes_block(n));
619     fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
620   }
621   for ( i = 0; i < get_irn_arity(n); ++i) {
622     fprintf(F, "   %d: ", i);
623     dump_node_opcode(F, get_irn_n(n, i));
624     fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
625   }
626 #endif
627
628   fprintf(F, "arity: %d", get_irn_arity(n));
629   if ((get_irn_op(n) == op_Block) ||
630       (get_irn_op(n) == op_Phi) ||
631       ((get_irn_op(n) == op_Filter) && get_interprocedural_view())) {
632     fprintf(F, " backedges:");
633     comma = ' ';
634     for (i = 0; i < get_irn_arity(n); i++)
635       if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
636   }
637   fprintf(F, "\n");
638
639   /* Loop node   Someone else please tell me what's wrong ...
640   if (get_irn_loop(n)) {
641     ir_loop *loop = get_irn_loop(n);
642     assert(loop);
643     fprintf(F, " in loop %d with depth %d\n",
644         get_loop_loop_nr(loop), get_loop_depth(loop));
645   }
646   */
647
648   /* Source types */
649   switch (get_irn_opcode(n)) {
650   case iro_Start: {
651     type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
652     fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
653     for (i = 0; i < get_method_n_params(tp); ++i)
654       fprintf(F, "  param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
655     if ((get_irp_ip_view_state() == ip_view_valid) && !get_interprocedural_view()) {
656       ir_node *sbl = get_nodes_block(n);
657       int i, n_cfgpreds = get_Block_cg_n_cfgpreds(sbl);
658       fprintf(F, "graph has %d interprocedural predecessors:\n", n_cfgpreds);
659       for (i = 0; i < n_cfgpreds; ++i) {
660     ir_node *cfgpred = get_Block_cg_cfgpred(sbl, i);
661     fprintf(F, "  %d: Call %ld in graph %s\n", i, get_irn_node_nr(cfgpred),
662         get_irg_dump_name(get_irn_irg(cfgpred)));
663       }
664     }
665   } break;
666   case iro_Alloc: {
667     fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
668   } break;
669   case iro_Free: {
670     fprintf(F, "freeing entity of type %s \n", get_type_name_ex(get_Free_type(n), &bad));
671   } break;
672   case iro_Sel: {
673     entity *ent = get_Sel_entity(n);
674
675     if (ent) {
676       fprintf(F, "Selecting entity of type %s\n", get_type_name_ex(get_entity_type(ent), &bad));
677       fprintf(F, "  from entity of type %s\n", get_type_name_ex(get_entity_owner(ent), &bad));
678     }
679     else {
680       fprintf(F, "<NULL entity>\n");
681       bad = 1;
682     }
683   } break;
684   case iro_Call: {
685     type *tp = get_Call_type(n);
686     fprintf(F, "calling method of type %s \n", get_type_name_ex(tp, &bad));
687     if(get_unknown_type() != tp) {
688       for (i = 0; i < get_method_n_params(tp); ++i)
689         fprintf(F, "  param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
690       for (i = 0; i < get_method_n_ress(tp); ++i)
691         fprintf(F, "  resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
692     }
693     if (Call_has_callees(n)) {
694       fprintf(F, "possible callees: \n");
695       for (i = 0; i < get_Call_n_callees(n); i++) {
696         fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
697       }
698     }
699   } break;
700   case iro_CallBegin: {
701     ir_node *call = get_CallBegin_call(n);
702     if (Call_has_callees(call)) {
703       fprintf(F, "possible callees: \n");
704       for (i = 0; i < get_Call_n_callees(call); i++) {
705         fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
706       }
707     }
708   } break;
709   case iro_Return: {
710     if (!get_interprocedural_view()) {
711       type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
712       fprintf(F, "return in method of type %s \n", get_type_name_ex(tp, &bad));
713       for (i = 0; i < get_method_n_ress(tp); ++i)
714         fprintf(F, "  res %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
715     }
716   } break;
717   case iro_Const: {
718     type *tp = get_Const_type(n);
719     assert(tp != none_type);
720     fprintf(F, "Const of type %s \n", get_type_name_ex(get_Const_type(n), &bad));
721   } break;
722   case iro_SymConst: {
723     switch(get_SymConst_kind(n)) {
724     case symconst_addr_name:
725       fprintf(F, "kind addr_name\n");
726       break;
727     case symconst_addr_ent:
728       fprintf(F, "kind addr_ent\n");
729       dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames);
730       break;
731     case symconst_type_tag:
732       fprintf(F, "kind type_tag\n");
733       break;
734     case symconst_size:
735       fprintf(F, "kind size\n");
736       break;
737     }
738     fprintf(F, "SymConst of type %s \n", get_type_name_ex(get_SymConst_value_type(n), &bad));
739   } break;
740   case iro_Filter: {
741     int i;
742     if (get_interprocedural_view()) {
743       fprintf(F, "intra predecessor nodes:\n");
744       for (i = 0; i < get_irn_intra_arity(n); i++) {
745         ir_node *pred = get_irn_intra_n(n, i);
746         fprintf(F, "  %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
747       }
748     } else {
749       fprintf(F, "inter predecessor nodes:\n");
750       for (i = 0; i < get_irn_inter_arity(n); i++) {
751         ir_node *pred = get_irn_inter_n(n, i);
752         fprintf(F, "  %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
753         get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
754       }
755     }
756   } break;
757   case iro_Load:
758     fprintf(F, "volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
759     break;
760   case iro_Store:
761     fprintf(F, "volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
762     break;
763
764   default: ;
765   }
766
767   if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent  ||
768       get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent  )
769     if (get_irn_typeinfo_type(n) != none_type)
770       fprintf (F, "\nAnalysed type: %s", get_type_name_ex(get_irn_typeinfo_type(n), &bad));
771
772   fprintf (F, "\"");
773
774   return bad;
775 }
776
777
778 static INLINE
779 bool is_constlike_node(ir_node *n) {
780   ir_op *op = get_irn_op(n);
781   return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
782 }
783
784
785 /* outputs the predecessors of n, that are constants, local.  I.e.,
786    generates a copy of the constant predecessors for each node called with. */
787 static void dump_const_node_local(FILE *F, ir_node *n) {
788   int i;
789   if (!get_opt_dump_const_local()) return;
790
791   /* Use visited flag to avoid outputting nodes twice.
792      initialize it first. */
793   for (i = 0; i < get_irn_arity(n); i++) {
794     ir_node *con = get_irn_n(n, i);
795     if (is_constlike_node(con)) {
796       set_irn_visited(con, get_irg_visited(current_ir_graph) - 1);
797     }
798   }
799
800   for (i = 0; i < get_irn_arity(n); i++) {
801     ir_node *con = get_irn_n(n, i);
802     if (is_constlike_node(con) && irn_not_visited(con)) {
803       int bad = 0;
804
805       mark_irn_visited(con);
806       /* Generate a new name for the node by appending the names of
807          n and const. */
808       fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
809       fprintf(F, " label: \"");
810       bad |= dump_node_opcode(F, con);
811       bad |= dump_node_mode(F, con);
812       bad |= dump_node_typeinfo(F, con);
813       fprintf (F, " ");
814       bad |= dump_node_nodeattr(F, con);
815       fprintf(F, " %ld", get_irn_node_nr(con));
816       fprintf(F, "\" ");
817       bad |= dump_node_info(F, con);
818       dump_node_vcgattr(F, con, bad);
819       fprintf(F, "}\n");
820     }
821   }
822 }
823
824 static void INLINE print_node_error(FILE *F, const char *p)
825 {
826   if (! p)
827     return;
828
829   fprintf (F, " info2: \"%s\"", p);
830 }
831
832 static void dump_node(FILE *F, ir_node *n)
833 {
834   int bad = 0;
835   const char *p;
836
837   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
838   /* dump this node */
839   fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
840
841   bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
842   bad |= dump_node_opcode(F, n);
843   bad |= dump_node_mode(F, n);
844   bad |= dump_node_typeinfo(F, n);
845   fprintf(F, " ");
846   bad |= dump_node_nodeattr(F, n);
847   fprintf(F, " %ld", get_irn_node_nr(n));
848   fprintf(F, "\" ");
849   bad |= dump_node_info(F, n);
850   print_node_error(F, p);
851   dump_node_vcgattr(F, n, bad);
852   fprintf(F, "}\n");
853   dump_const_node_local(F, n);
854 #if DO_HEAPANALYSIS
855   dump_chi_term(F, n);
856   dump_state(F, n);
857 #endif
858 }
859
860 /* dump the edge to the block this node belongs to */
861 static void
862 dump_ir_block_edge(FILE *F, ir_node *n)  {
863   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
864   if (is_no_Block(n)) {
865     ir_node *block = get_nodes_block(n);
866
867     fprintf (F, "edge: { sourcename: \"");
868     PRINT_NODEID(n);
869     fprintf (F, "\" targetname: ");
870     fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
871     fprintf (F, " "   BLOCK_EDGE_ATTR "}\n");
872   }
873 }
874
875 static void
876 print_data_edge_vcgattr(FILE *F, ir_node *from, int to) {
877   if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
878     fprintf (F, INTRA_DATA_EDGE_ATTR);
879   else
880     fprintf (F, INTER_DATA_EDGE_ATTR);
881 }
882
883 static void
884 print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) {
885   if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to)))
886     fprintf (F, INTRA_MEM_EDGE_ATTR);
887   else
888     fprintf (F, INTER_MEM_EDGE_ATTR);
889 }
890
891 static void
892 print_edge_vcgattr(FILE *F, ir_node *from, int to) {
893   assert(from);
894
895   if (dump_backedge_information_flag && is_backedge(from, to))
896     fprintf (F, BACK_EDGE_ATTR);
897
898   switch (get_irn_opcode(from)) {
899   case iro_Block:
900     fprintf (F, CF_EDGE_ATTR);
901     break;
902   case iro_Start:   break;
903   case iro_End:
904     if (to >= 0) {
905       if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
906     fprintf (F, CF_EDGE_ATTR);
907       if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
908     fprintf (F, INTER_MEM_EDGE_ATTR);
909     }
910     break;
911   case iro_EndReg:
912   case iro_EndExcept:
913   case iro_Jmp:
914   case iro_Break:
915   case iro_Cond:
916     print_data_edge_vcgattr(F, from, to);
917     break;
918   case iro_Return:
919   case iro_Raise:
920     if (to == 0)
921       print_mem_edge_vcgattr(F, from, to);
922     else
923       print_data_edge_vcgattr(F, from, to);
924     break;
925   case iro_Const:
926   case iro_SymConst:
927     print_data_edge_vcgattr(F, from, to);
928     break;
929   case iro_Sel:
930   case iro_Call:
931     if (to == 0)
932       print_mem_edge_vcgattr(F, from, to);
933     else
934       print_data_edge_vcgattr(F, from, to);
935     break;
936   case iro_CallBegin:
937   case iro_Add:
938   case iro_Sub:
939   case iro_Minus:
940   case iro_Mul:
941     print_data_edge_vcgattr(F, from, to);
942     break;
943   case iro_Quot:
944   case iro_DivMod:
945   case iro_Div:
946   case iro_Mod:
947     if (to == 0)
948       print_mem_edge_vcgattr(F, from, to);
949     else
950       print_data_edge_vcgattr(F, from, to);
951     break;
952   case iro_Abs:
953   case iro_And:
954   case iro_Or:
955   case iro_Eor:
956   case iro_Shl:
957   case iro_Shr:
958   case iro_Shrs:
959   case iro_Rot:
960   case iro_Cmp:
961   case iro_Conv:
962       print_data_edge_vcgattr(F, from, to);
963     break;
964   case iro_Phi:
965     if (get_irn_modecode(from) == irm_M)
966       fprintf (F, INTER_MEM_EDGE_ATTR);
967     else
968       print_data_edge_vcgattr(F, from, to);
969     break;
970   case iro_Load:
971   case iro_Store:
972   case iro_Alloc:
973   case iro_Free:
974     if (to == 0)
975       print_mem_edge_vcgattr(F, from, to);
976     else
977       print_data_edge_vcgattr(F, from, to);
978     break;
979   case iro_Sync:
980     print_mem_edge_vcgattr(F, from, to);
981     break;
982   case iro_Tuple:  break;
983   case iro_Proj:
984   case iro_Filter:
985     switch (get_irn_modecode(from)) {
986     case irm_X:
987       fprintf (F, CF_EDGE_ATTR);
988       break;
989     case irm_M:
990       fprintf (F, INTER_MEM_EDGE_ATTR);
991       break;
992     default:
993       print_data_edge_vcgattr(F, from, to);
994       break;
995     }
996     break;
997   case iro_Bad:     break;
998   case iro_Unknown: break;
999   case iro_Id:
1000     switch (get_irn_modecode(from)) {
1001     case irm_M:
1002       fprintf (F, INTRA_MEM_EDGE_ATTR);
1003       break;
1004     case irm_X:
1005       fprintf (F, CF_EDGE_ATTR);
1006       break;
1007     default:
1008       print_data_edge_vcgattr(F, from, to);
1009       break;
1010     } break;
1011   default:
1012     ;
1013   }
1014 }
1015
1016 /* dump edges to our inputs */
1017 static void
1018 dump_ir_data_edges(FILE *F, ir_node *n)  {
1019   int i, visited = get_irn_visited(n);
1020
1021   if ((get_irn_op(n) == op_End) && (!dump_keepalive))
1022     return;
1023
1024   for (i = 0; i < get_irn_arity(n); i++) {
1025     ir_node * pred = get_irn_n(n, i);
1026     assert(pred);
1027
1028     if ((get_interprocedural_view() && get_irn_visited(pred) < visited))
1029       continue; /* pred not dumped */
1030
1031     if (dump_backedge_information_flag && is_backedge(n, i))
1032       fprintf (F, "backedge: {sourcename: \"");
1033     else
1034       fprintf (F, "edge: {sourcename: \"");
1035     PRINT_NODEID(n);
1036     fprintf (F, "\" targetname: ");
1037     if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
1038       PRINT_CONSTID(n, pred);
1039     } else {
1040       fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
1041     }
1042     fprintf (F, " label: \"%d\" ", i);
1043     print_edge_vcgattr(F, n, i);
1044     fprintf (F, "}\n");
1045   }
1046 }
1047
1048 /** Dumps a node and its edges but not the block edge
1049  */
1050 static INLINE void
1051 dump_node_wo_blockedge (ir_node *n, void *env) {
1052   FILE *F = env;
1053   dump_node(F, n);
1054   dump_ir_data_edges(F, n);
1055 }
1056
1057 /** Dumps a node and its edges.
1058  */
1059 static void
1060 dump_whole_node (ir_node *n, void *env) {
1061   FILE *F = env;
1062   dump_node_wo_blockedge(n, env);
1063   if (!node_floats(n)) dump_ir_block_edge(F, n);
1064 }
1065
1066 static void
1067 dump_const_node(ir_node *n, void *env) {
1068   if (is_Block(n)) return;
1069   dump_node_wo_blockedge(n, env);
1070 }
1071
1072 /***********************************************************************/
1073 /* the following routines dump the nodes/irgs bracketed to graphs.     */
1074 /***********************************************************************/
1075
1076 /** Dumps a constant expression as entity initializer, array bound ...
1077  */
1078 static void dump_const_expression(FILE *F, ir_node *value) {
1079   ir_graph *rem = current_ir_graph;
1080   int rem_dump_const_local = dump_const_local;
1081   dump_const_local = 0;
1082   current_ir_graph = get_const_code_irg();
1083   irg_walk(value, dump_const_node, NULL, F);
1084   /* Decrease visited flag so that we walk with the same flag for the next
1085      expresssion.  This guarantees that we don't dump the same node twice,
1086      as for const expressions cse is performed to save memory. */
1087   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
1088   current_ir_graph = rem;
1089   dump_const_local = rem_dump_const_local;
1090 }
1091
1092 /** Dump a block as graph containing its nodes.
1093  *
1094  *  Expects to find nodes belonging to the block as list in its
1095  *  link field.
1096  *  Dumps the edges of all nodes including itself. */
1097 static void
1098 dump_whole_block(FILE *F, ir_node *block) {
1099   ir_node *node;
1100   assert(is_Block(block));
1101
1102   fprintf(F, "graph: { title: \"");
1103   PRINT_NODEID(block);
1104   fprintf(F, "\"  label: \"");
1105   dump_node_opcode(F, block);
1106   fprintf (F, " %ld", get_irn_node_nr(block));
1107 #if DO_HEAPANALYSIS
1108   if (get_opt_dump_abstvals())
1109     fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
1110 #endif
1111   fprintf(F, "\" status:clustered color:%s \n",
1112        get_Block_matured(block) ? "yellow" : "red");
1113
1114   /* dump the blocks edges */
1115   dump_ir_data_edges(F, block);
1116
1117   /* dump the nodes that go into the block */
1118   for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
1119     dump_node(F, node);
1120     dump_ir_data_edges(F, node);
1121   }
1122
1123   /* Close the vcg information for the block */
1124   fprintf(F, "}\n");
1125   dump_const_node_local(F, block);
1126 #if DO_HEAPANALYSIS
1127   dump_chi_term(F, block);
1128 #endif
1129   fprintf(F, "\n");
1130 }
1131
1132 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
1133  *  The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */
1134 static void
1135 dump_block_graph(FILE *F, ir_graph *irg) {
1136   int i;
1137   ir_graph *rem = current_ir_graph;
1138   ir_node **arr = ird_get_irg_link(irg);
1139   current_ir_graph = irg;
1140
1141   for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1142     ir_node * node = arr[i];
1143     if (is_Block(node)) {
1144       /* Dumps the block and all the nodes in the block, which are to
1145          be found in Block->link. */
1146       dump_whole_block(F, node);
1147     } else {
1148       /* Nodes that are not in a Block. */
1149       dump_node(F, node);
1150       dump_ir_data_edges(F, node);
1151     }
1152   }
1153
1154   if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
1155     dump_loop_nodes_into_graph(F, irg);
1156
1157   current_ir_graph = rem;
1158 }
1159
1160 /** Dumps an irg as a graph.
1161  *  If interprocedural view edges can point to nodes out of this graph.
1162  */
1163 static void dump_graph(FILE *F, ir_graph *irg) {
1164
1165   fprintf(F, "graph: { title: \"");
1166   PRINT_IRGID(irg);
1167   fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
1168       get_ent_dump_name(get_irg_entity(irg)));
1169
1170   dump_block_graph(F, irg);
1171
1172   /* Close the vcg information for the irg */
1173   fprintf(F, "}\n\n");
1174 }
1175
1176 /*******************************************************************/
1177 /* Basic type and entity nodes and edges.                          */
1178 /*******************************************************************/
1179
1180 /* dumps the edges between nodes and their type or entity attributes. */
1181 static void dump_node2type_edges(ir_node *n, void *env)
1182 {
1183   FILE *F = env;
1184   assert(n);
1185
1186   switch (get_irn_opcode(n)) {
1187   case iro_Const :
1188     /* @@@ some consts have an entity */
1189     break;
1190   case iro_SymConst:
1191     if (   (get_SymConst_kind(n) ==symconst_type_tag)
1192        || (get_SymConst_kind(n) ==symconst_size))
1193       {
1194         print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1195       }
1196     break;
1197   case iro_Sel: {
1198       print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1199     } break;
1200   case iro_Call: {
1201       print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1202     } break;
1203   case iro_Alloc: {
1204       print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1205     } break;
1206   case iro_Free: {
1207       print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1208     } break;
1209   case iro_Cast: {
1210       print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1211     } break;
1212   default:
1213     break;
1214   }
1215 }
1216
1217
1218 static int print_type_info(FILE *F, type *tp) {
1219   int bad = 0;
1220
1221   if (get_type_state(tp) == layout_undefined) {
1222     fprintf(F, "state: layout_undefined\n");
1223   } else {
1224     fprintf(F, "state: layout_fixed,\n");
1225   }
1226   if (get_type_mode(tp))
1227     fprintf(F, "mode: %s,\n", get_mode_name_ex(get_type_mode(tp), &bad));
1228   fprintf(F, "size: %db,\n", get_type_size_bits(tp));
1229
1230   return bad;
1231 }
1232
1233 static void print_typespecific_info(FILE *F, type *tp) {
1234   switch (get_type_tpop_code(tp)) {
1235   case tpo_class:
1236     {
1237       fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1238     } break;
1239   case tpo_struct:
1240     {
1241     } break;
1242   case tpo_method:
1243     {
1244       fprintf(F, "variadicity: %s\n", get_variadicity_name(get_method_variadicity(tp)));
1245       fprintf(F, "params: %d\n", get_method_n_params(tp));
1246       fprintf(F, "results: %d\n", get_method_n_ress(tp));
1247     } break;
1248   case tpo_union:
1249     {
1250     } break;
1251   case tpo_array:
1252     {
1253     } break;
1254   case tpo_enumeration:
1255     {
1256     } break;
1257   case tpo_pointer:
1258     {
1259     } break;
1260   case tpo_primitive:
1261     {
1262     } break;
1263   default: break;
1264   } /* switch type */
1265 }
1266
1267
1268 static void print_typespecific_vcgattr(FILE *F, type *tp) {
1269   switch (get_type_tpop_code(tp)) {
1270   case tpo_class:
1271     {
1272       if (peculiarity_existent == get_class_peculiarity(tp))
1273     fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1274       else
1275     fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1276     } break;
1277   case tpo_struct:
1278     {
1279       fprintf (F, " " TYPE_METH_NODE_ATTR);
1280     } break;
1281   case tpo_method:
1282     {
1283     } break;
1284   case tpo_union:
1285     {
1286     } break;
1287   case tpo_array:
1288     {
1289     } break;
1290   case tpo_enumeration:
1291     {
1292     } break;
1293   case tpo_pointer:
1294     {
1295     } break;
1296   case tpo_primitive:
1297     {
1298     } break;
1299   default: break;
1300   } /* switch type */
1301 }
1302
1303 static int print_type_node(FILE *F, type *tp)
1304 {
1305   int bad = 0;
1306
1307   fprintf (F, "node: {title: ");
1308   PRINT_TYPEID(tp);
1309   fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
1310   fprintf (F, " info1: \"");
1311   bad |= print_type_info(F, tp);
1312   print_typespecific_info(F, tp);
1313   fprintf (F, "\"");
1314   print_typespecific_vcgattr(F, tp);
1315   fprintf (F, "}\n");
1316
1317   return bad;
1318 }
1319
1320 #define X(a)    case a: fprintf(F, #a); break
1321 void dump_entity_node(FILE *F, entity *ent, int color)
1322 {
1323   fprintf (F, "node: {title: \"");
1324   PRINT_ENTID(ent); fprintf(F, "\"");
1325   fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1326   fprintf (F, "label: ");
1327   fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
1328   if (color)
1329     fprintf(F, "color: %d", color);
1330   else
1331     fprintf (F, ENTITY_NODE_ATTR);
1332   fprintf (F, "\n info1: \"");
1333
1334   dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
1335
1336   fprintf(F, "\"\n}\n");
1337 }
1338 #undef X
1339
1340 static void dump_enum_item(FILE *F, type *tp, int pos)
1341 {
1342   char buf[1024];
1343   ident *id  = get_enumeration_nameid(tp, pos);
1344   tarval *tv = get_enumeration_enum(tp, pos);
1345
1346   tarval_snprintf(buf, sizeof(buf), tv);
1347   fprintf (F, "node: {title: \"");
1348   PRINT_ITEMID(tp, pos); fprintf(F, "\"");
1349   fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE);
1350   fprintf (F, "label: ");
1351   fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id));
1352   fprintf (F, "\n info1: \"value: %s\"}\n", buf);
1353 }
1354
1355 /* dumps a type or entity and it's edges. */
1356 static void
1357 dump_type_info(type_or_ent *tore, void *env) {
1358   FILE *F = env;
1359   int i = 0;  /* to shutup gcc */
1360
1361   /* dump this type or entity */
1362
1363   switch (get_kind(tore)) {
1364   case k_entity:
1365     {
1366       entity *ent = (entity *)tore;
1367       ir_node *value;
1368       /* The node */
1369       dump_entity_node(F, ent, 0);
1370       /* The Edges */
1371       /* skip this to reduce graph.  Member edge of type is parallel to this edge. *
1372       fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1373                 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1374       print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1375       if(is_class_type(get_entity_owner(ent))) {
1376         for(i = 0; i < get_entity_n_overwrites(ent); i++)
1377           print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, ENT_OVERWRITES_EDGE_ATTR);
1378       }
1379       /* attached subgraphs */
1380       if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1381         if (is_atomic_entity(ent)) {
1382           value = get_atomic_ent_value(ent);
1383           if (value) {
1384             print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1385             /* DDMN(value);  $$$ */
1386             dump_const_expression(F, value);
1387           }
1388         }
1389         if (is_compound_entity(ent)) {
1390           for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1391             value = get_compound_ent_value(ent, i);
1392             if (value) {
1393               print_ent_node_edge(F, ent, value, ENT_VALUE_EDGE_ATTR, i);
1394               dump_const_expression(F, value);
1395               print_ent_ent_edge(F, ent, get_compound_ent_value_member(ent, i), 0, ENT_CORR_EDGE_ATTR, i);
1396               /*
1397               fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1398               ENT_CORR_EDGE_ATTR  "}\n", GET_ENTID(ent),
1399               get_compound_ent_value_member(ent, i), i);
1400               */
1401             }
1402           }
1403         }
1404       }
1405     } break;
1406   case k_type:
1407     {
1408       type *tp = (type *)tore;
1409       print_type_node(F, tp);
1410       /* and now the edges */
1411       switch (get_type_tpop_code(tp)) {
1412       case tpo_class:
1413         {
1414           for (i=0; i < get_class_n_supertypes(tp); i++)
1415             print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1416           for (i=0; i < get_class_n_members(tp); i++)
1417             print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1418         } break;
1419       case tpo_struct:
1420         {
1421           for (i=0; i < get_struct_n_members(tp); i++)
1422             print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1423         } break;
1424       case tpo_method:
1425         {
1426           for (i = 0; i < get_method_n_params(tp); i++)
1427             print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1428           for (i = 0; i < get_method_n_ress(tp); i++)
1429             print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1430         } break;
1431       case tpo_union:
1432         {
1433           for (i = 0; i < get_union_n_members(tp); i++)
1434             print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1435         } break;
1436       case tpo_array:
1437         {
1438           print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1439           print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1440           for (i = 0; i < get_array_n_dimensions(tp); i++) {
1441             ir_node *upper = get_array_upper_bound(tp, i);
1442             ir_node *lower = get_array_lower_bound(tp, i);
1443             print_node_type_edge(F, upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1444             print_node_type_edge(F, lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1445             dump_const_expression(F, upper);
1446             dump_const_expression(F, lower);
1447           }
1448
1449         } break;
1450       case tpo_enumeration:
1451         {
1452           for (i = 0; i < get_enumeration_n_enums(tp); ++i) {
1453             dump_enum_item(F, tp, i);
1454             print_enum_item_edge(F, tp, i, "label: \"item %d\"", i);
1455           }
1456         } break;
1457       case tpo_pointer:
1458         {
1459           print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1460         } break;
1461       case tpo_primitive:
1462         {
1463         } break;
1464       default: break;
1465       } /* switch type */
1466     }
1467     break; /* case k_type */
1468   default:
1469     {
1470       printf(" *** irdump,  dump_type_info(l.%i), faulty type.\n", __LINE__);
1471     } break;
1472   } /* switch kind_or_entity */
1473 }
1474
1475 typedef struct _h_env {
1476   int dump_ent;
1477   FILE *f;
1478 } h_env_t;
1479
1480 /** For dumping class hierarchies.
1481  * Dumps a class type node and a superclass edge.
1482  * If env->dump_ent dumps entities of classes and overwrites edges.
1483  */
1484 static void
1485 dump_class_hierarchy_node (type_or_ent *tore, void *ctx) {
1486   h_env_t *env = ctx;
1487   FILE *F = env->f;
1488   int i = 0;  /* to shutup gcc */
1489
1490   /* dump this type or entity */
1491   switch (get_kind(tore)) {
1492   case k_entity: {
1493     entity *ent = (entity *)tore;
1494     if (get_entity_owner(ent) == get_glob_type()) break;
1495     if (!is_method_type(get_entity_type(ent))) break;  /* GL */
1496     if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
1497       /* The node */
1498       dump_entity_node(F, ent, 0);
1499       /* The edges */
1500       print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1501       for(i = 0; i < get_entity_n_overwrites(ent); i++)
1502         print_ent_ent_edge(F, get_entity_overwrites(ent, i), ent, 0, ENT_OVERWRITES_EDGE_ATTR);
1503     }
1504   } break; /* case k_entity */
1505   case k_type:
1506     {
1507       type *tp = (type *)tore;
1508       if (tp == get_glob_type()) break;
1509       switch (get_type_tpop_code(tp)) {
1510         case tpo_class: {
1511           print_type_node(F, tp);
1512           /* and now the edges */
1513           for (i=0; i < get_class_n_supertypes(tp); i++)
1514           {
1515               print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1516           }
1517         } break;
1518         default: break;
1519       } /* switch type */
1520     }
1521     break; /* case k_type */
1522   default:
1523     {
1524       printf(" *** irdump,  dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1525     } break;
1526   } /* switch kind_or_entity */
1527 }
1528
1529 /*******************************************************************/
1530 /* dump analysis information that is expressed in graph terms.     */
1531 /*******************************************************************/
1532
1533 /* dump out edges */
1534 static void
1535 dump_out_edge(ir_node *n, void *env) {
1536   FILE *F = env;
1537   int i;
1538   for (i = 0; i < get_irn_n_outs(n); i++) {
1539     assert(get_irn_out(n, i));
1540     fprintf (F, "edge: {sourcename: \"");
1541     PRINT_NODEID(n);
1542     fprintf (F, "\" targetname: \"");
1543     PRINT_NODEID(get_irn_out(n, i));
1544     fprintf (F, "\" color: red linestyle: dashed");
1545     fprintf (F, "}\n");
1546   }
1547 }
1548
1549 static INLINE void
1550 dump_loop_label(FILE *F, ir_loop *loop) {
1551   fprintf (F, "loop %d, %d sons, %d nodes",
1552        get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1553 }
1554
1555 static INLINE void dump_loop_info(FILE *F, ir_loop *loop) {
1556   fprintf (F, " info1: \"");
1557   fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1558 #if DEBUG_libfirm   /* GL @@@ debug analyses */
1559   fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1560 #endif
1561   fprintf (F, "\"");
1562 }
1563
1564 static INLINE void
1565 dump_loop_node(FILE *F, ir_loop *loop) {
1566   fprintf (F, "node: {title: \"");
1567   PRINT_LOOPID(loop);
1568   fprintf (F, "\" label: \"");
1569   dump_loop_label(F, loop);
1570   fprintf (F, "\" ");
1571   dump_loop_info(F, loop);
1572   fprintf (F, "}\n");
1573
1574 }
1575
1576 static INLINE void
1577 dump_loop_node_edge(FILE *F, ir_loop *loop, int i) {
1578   assert(loop);
1579   fprintf (F, "edge: {sourcename: \"");
1580   PRINT_LOOPID(loop);
1581   fprintf (F, "\" targetname: \"");
1582   PRINT_NODEID(get_loop_node(loop, i));
1583   fprintf (F, "\" color: green");
1584   fprintf (F, "}\n");
1585 }
1586
1587 static INLINE void
1588 dump_loop_son_edge(FILE *F, ir_loop *loop, int i) {
1589   assert(loop);
1590   fprintf (F, "edge: {sourcename: \"");
1591   PRINT_LOOPID(loop);
1592   fprintf (F, "\" targetname: \"");
1593   PRINT_LOOPID(get_loop_son(loop, i));
1594   fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1595        get_loop_element_pos(loop, get_loop_son(loop, i)));
1596 }
1597
1598 static
1599 void dump_loops(FILE *F, ir_loop *loop) {
1600   int i;
1601   /* dump this loop node */
1602   dump_loop_node(F, loop);
1603
1604   /* dump edges to nodes in loop -- only if it is a real loop */
1605   if (get_loop_depth(loop) != 0) {
1606     for (i = 0; i < get_loop_n_nodes(loop); i++) {
1607       dump_loop_node_edge(F, loop, i);
1608     }
1609   }
1610   for (i = 0; i < get_loop_n_sons(loop); i++) {
1611     dump_loops(F, get_loop_son(loop, i));
1612     dump_loop_son_edge(F, loop, i);
1613   }
1614 }
1615
1616 static INLINE
1617 void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) {
1618   ir_graph *rem = current_ir_graph;
1619   current_ir_graph = irg;
1620
1621   if (get_irg_loop(irg)) dump_loops(F, get_irg_loop(irg));
1622
1623   current_ir_graph = rem;
1624 }
1625
1626
1627 /**
1628  * dumps the VCG header
1629  */
1630 INLINE void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
1631   char *label;
1632
1633   if (edge_label) {
1634     label = "yes";
1635   } else {
1636     label = "no";
1637   }
1638
1639   if (!orientation) orientation = "bottom_to_top";
1640
1641   /* print header */
1642   fprintf (F,
1643        "graph: { title: \"ir graph of %s\"\n"
1644        "display_edge_labels: %s\n"
1645        "layoutalgorithm: mindepth\n"
1646        "manhattan_edges: yes\n"
1647        "port_sharing: no\n"
1648        "orientation: %s\n"
1649        "classname 1:  \"intrablock Data\"\n"
1650        "classname 16: \"interblock Data\"\n"
1651        "classname 2:  \"Block\"\n"
1652        "classname 13: \"Control Flow\"\n"
1653        "classname 18: \"Exception Control Flow for Interval Analysis\"\n"
1654        "classname 14: \"intrablock Memory\"\n"
1655        "classname 17: \"interblock Memory\"\n"
1656        "classname 15: \"Dominators\"\n"
1657        "classname 3:  \"Entity type\"\n"
1658        "classname 4:  \"Entity owner\"\n"
1659        "classname 5:  \"Method Param\"\n"
1660        "classname 6:  \"Method Res\"\n"
1661        "classname 7:  \"Super\"\n"
1662        "classname 8:  \"Union\"\n"
1663        "classname 9:  \"Points-to\"\n"
1664        "classname 10: \"Array Element Type\"\n"
1665        "classname 11: \"Overwrites\"\n"
1666        "classname 12: \"Member\"\n"
1667        "infoname 1: \"Attribute\"\n"
1668        "infoname 2: \"Verification errors\"\n",
1669        name, label, orientation);
1670
1671   /* don't use all, the range is too whith/black. */
1672   n_colors   = 18;
1673   base_color = 105;
1674   fprintf (F,
1675        "colorentry 100:    0   0    0\n"
1676        "colorentry 101:   20   0    0\n"
1677        "colorentry 102:   40   0    0\n"
1678        "colorentry 103:   60   0    0\n"
1679        "colorentry 104:   80   0    0\n"
1680        "colorentry 105:  100   0    0\n"
1681        "colorentry 106:  120   0    0\n"
1682        "colorentry 107:  140   0    0\n"
1683        "colorentry 108:  150   0    0\n"
1684        "colorentry 109:  180   0    0\n"
1685        "colorentry 110:  200   0    0\n"
1686        "colorentry 111:  220   0    0\n"
1687        "colorentry 112:  240   0    0\n"
1688        "colorentry 113:  255   0    0\n"
1689        "colorentry 113:  255  20   20\n"
1690        "colorentry 114:  255  40   40\n"
1691        "colorentry 115:  255  60   60\n"
1692        "colorentry 116:  255  80   80\n"
1693        "colorentry 117:  255 100  100\n"
1694        "colorentry 118:  255 120  120\n"
1695        "colorentry 119:  255 140  140\n"
1696        "colorentry 120:  255 150  150\n"
1697        "colorentry 121:  255 180  180\n"
1698        "colorentry 122:  255 200  200\n"
1699        "colorentry 123:  255 220  220\n"
1700        "colorentry 124:  255 240  240\n"
1701        "colorentry 125:  255 250  250\n"
1702        );
1703
1704   fprintf (F, "\n");        /* a separator */
1705 }
1706
1707 /**
1708  * open a vcg file
1709  *
1710  * @param irg     The graph to be dumped
1711  * @param suffix1 first filename suffix
1712  * @param suffix2 second filename suffix
1713  */
1714 FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) {
1715   FILE *F;
1716   const char *nm = get_irg_dump_name(irg);
1717   int len = strlen(nm), i, j;
1718   char *fname;  /* filename to put the vcg information in */
1719
1720   if (!suffix1) suffix1 = "";
1721   if (!suffix2) suffix2 = "";
1722
1723   /* open file for vcg graph */
1724   fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5);
1725
1726   /* strncpy (fname, nm, len); */     /* copy the filename */
1727   j = 0;
1728   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
1729     if (nm[i] == '/') {
1730       fname[j] = '@'; j++; fname[j] = '1'; j++;
1731     } else if (nm[i] == '@') {
1732       fname[j] = '@'; j++; fname[j] = '2'; j++;
1733     } else {
1734       fname[j] = nm[i]; j++;
1735     }
1736   }
1737   fname[j] = '\0';
1738   strcat (fname, suffix1);  /* append file suffix */
1739   strcat (fname, suffix2);  /* append file suffix */
1740   strcat (fname, ".vcg");   /* append the .vcg suffix */
1741   F = fopen (fname, "w");   /* open file for writing */
1742   if (!F) {
1743     panic("cannot open %s for writing (%m)", fname);  /* not reached */
1744   }
1745   free(fname);
1746
1747   return F;
1748 }
1749
1750 /**
1751  * open a vcg file
1752  *
1753  * @param irg     The graph to be dumped
1754  * @param suffix  filename suffix
1755  */
1756 static FILE *vcg_open_name (const char *name, const char *suffix) {
1757   FILE *F;
1758   char *fname;  /* filename to put the vcg information in */
1759   int i, j, len = strlen(name);
1760
1761   if (!suffix) suffix = "";
1762
1763   /** open file for vcg graph */
1764   fname = malloc (len * 2 + 5 + strlen(suffix));
1765   /* strcpy (fname, name);*/    /* copy the filename */
1766   j = 0;
1767   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
1768     if (name[i] == '/') {
1769       fname[j] = '@'; j++; fname[j] = '1'; j++;
1770     } else if (name[i] == '@') {
1771       fname[j] = '@'; j++; fname[j] = '2'; j++;
1772     } else {
1773       fname[j] = name[i]; j++;
1774     }
1775   }
1776   fname[j] = '\0';
1777   strcat (fname, suffix);
1778   strcat (fname, ".vcg");  /* append the .vcg suffix */
1779   F = fopen (fname, "w");  /* open file for writing */
1780   if (!F) {
1781     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
1782   }
1783   free(fname);
1784
1785   return F;
1786 }
1787
1788 /**
1789  * Dumps the vcg file footer
1790  */
1791 static INLINE void dump_vcg_footer (FILE *F) {
1792   fprintf (F, "}\n");
1793 }
1794
1795 /**
1796  * close the vcg file
1797  */
1798 void vcg_close (FILE *F) {
1799   dump_vcg_footer(F);    /* print footer */
1800   fclose (F);           /* close vcg file */
1801 }
1802
1803 /************************************************************************/
1804 /************************************************************************/
1805 /* Routines that dump all or parts of the firm representation to a file */
1806 /************************************************************************/
1807 /************************************************************************/
1808
1809 /************************************************************************/
1810 /* Dump ir graphs, differnt formats and additional information.         */
1811 /************************************************************************/
1812
1813 /** Routine to dump a graph, blocks as conventional nodes.
1814  */
1815 void
1816 dump_ir_graph (ir_graph *irg, const char *suffix )
1817 {
1818   FILE *f;
1819   ir_graph *rem;
1820   char *suffix1;
1821   rem = current_ir_graph;
1822
1823   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
1824   current_ir_graph = irg;
1825   if (get_interprocedural_view()) suffix1 = "-pure-ip";
1826   else                            suffix1 = "-pure";
1827   f = vcg_open(irg, suffix, suffix1);
1828   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1829
1830   /* walk over the graph */
1831   /* dump_whole_node must be called in post visiting predecessors */
1832   irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1833
1834   /* dump the out edges in a separate walk */
1835   if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
1836     irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1837   }
1838
1839   vcg_close(f);
1840
1841   current_ir_graph = rem;
1842 }
1843
1844
1845 void
1846 dump_ir_block_graph (ir_graph *irg, const char *suffix)
1847 {
1848   FILE *f;
1849   int i;
1850   char *suffix1;
1851
1852   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1853     return;
1854
1855   if (get_interprocedural_view()) suffix1 = "-ip";
1856   else                            suffix1 = "";
1857   f = vcg_open(irg, suffix, suffix1);
1858   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1859
1860   construct_block_lists(irg);
1861
1862   for (i = 0; i < get_irp_n_irgs(); i++) {
1863     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1864     if (arr) {
1865       dump_graph(f, get_irp_irg(i));
1866       DEL_ARR_F(arr);
1867     }
1868   }
1869
1870   vcg_close(f);
1871 }
1872
1873 /** dumps a graph with type information
1874  */
1875 void
1876 dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
1877 {
1878   FILE *f;
1879   ir_graph *rem = current_ir_graph;
1880   char *suffix1;
1881
1882   /* if a filter is set, dump only the irg's that match the filter */
1883   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1884     return;
1885
1886   current_ir_graph = irg;
1887
1888   if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
1889   else                            suffix1 = "-pure-wtypes";
1890   f = vcg_open(irg,suffix, suffix1);
1891   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1892
1893   /* dump common ir graph */
1894   irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
1895   /* dump type info */
1896   type_walk_irg(irg, dump_type_info, NULL, f);
1897   inc_irg_visited(get_const_code_irg());
1898   /* dump edges from graph to type info */
1899   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1900
1901   vcg_close(f);
1902   current_ir_graph = rem;
1903 }
1904
1905 void
1906 dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
1907 {
1908   FILE *f;
1909   int i;
1910   char *suffix1;
1911   ir_graph *rem = current_ir_graph;
1912
1913   /* if a filter is set, dump only the irg's that match the filter */
1914   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
1915     return;
1916
1917   if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
1918   else                            suffix1 = "-wtypes";
1919   f = vcg_open(irg, suffix, suffix1);
1920   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
1921
1922   /* dump common blocked ir graph */
1923   construct_block_lists(irg);
1924
1925   for (i = 0; i < get_irp_n_irgs(); i++) {
1926     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1927     if (arr) {
1928       dump_graph(f, get_irp_irg(i));
1929       DEL_ARR_F(arr);
1930     }
1931   }
1932
1933   /* dump type info */
1934   current_ir_graph = irg;
1935   type_walk_irg(irg, dump_type_info, NULL, f);
1936   inc_irg_visited(get_const_code_irg());
1937
1938   /* dump edges from graph to type info */
1939   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
1940
1941   current_ir_graph = rem;
1942   vcg_close(f);
1943 }
1944
1945 /*---------------------------------------------------------------------*/
1946 /* The following routines dump a control flow graph.                   */
1947 /*---------------------------------------------------------------------*/
1948
1949 static void
1950 dump_block_to_cfg(ir_node *block, void *env) {
1951   FILE *F = env;
1952   int i, fl;
1953   ir_node *pred;
1954
1955   if (is_Block(block)) {
1956     /* This is a block. Dump a node for the block. */
1957     fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1958     fprintf (F, "\" label: \"");
1959     if (block == get_irg_start_block(get_irn_irg(block)))
1960       fprintf(F, "Start ");
1961     if (block == get_irg_end_block(get_irn_irg(block)))
1962       fprintf(F, "End ");
1963
1964     fprintf (F, "%s ", get_op_name(get_irn_op(block)));
1965     PRINT_NODEID(block);
1966     fprintf (F, "\" ");
1967     fprintf(F, "info1:\"");
1968     if (dump_dominator_information_flag)
1969       fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
1970
1971     /* show arity and possible Bad predecessors of the block */
1972     fprintf(F, "arity: %d\n", get_Block_n_cfgpreds(block));
1973     for (fl = i = 0; i < get_Block_n_cfgpreds(block); ++i) {
1974       ir_node *pred = get_Block_cfgpred(block, i);
1975       if (is_Bad(pred)) {
1976     if (! fl)
1977       fprintf(F, "Bad pred at pos: ");
1978     fprintf(F, "%d ", i);
1979     fl = 1;
1980       }
1981     }
1982     if (fl)
1983       fprintf(F, "\n");
1984
1985     fprintf (F, "\"");  /* closing quote of info */
1986
1987     if ((block == get_irg_start_block(get_irn_irg(block))) ||
1988     (block == get_irg_end_block(get_irn_irg(block)))     )
1989       fprintf(F, " color:blue ");
1990     else if (fl)
1991       fprintf(F, " color:yellow ");
1992
1993     fprintf (F, "}\n");
1994     /* Dump the edges */
1995     for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1996       if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1997         pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1998         fprintf (F, "edge: { sourcename: \"");
1999         PRINT_NODEID(block);
2000         fprintf (F, "\" targetname: \"");
2001         PRINT_NODEID(pred);
2002         fprintf (F, "\"}\n");
2003       }
2004
2005     /* Dump dominator edge */
2006     if (dump_dominator_information_flag && get_Block_idom(block)) {
2007       pred = get_Block_idom(block);
2008       fprintf (F, "edge: { sourcename: \"");
2009       PRINT_NODEID(block);
2010       fprintf (F, "\" targetname: \"");
2011       PRINT_NODEID(pred);
2012       fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
2013     }
2014   }
2015 }
2016
2017 void
2018 dump_cfg (ir_graph *irg, const char *suffix)
2019 {
2020   FILE *f;
2021   ir_graph *rem = current_ir_graph;
2022   int ddif = dump_dominator_information_flag;
2023   int ipv = get_interprocedural_view();
2024
2025   /* if a filter is set, dump only the irg's that match the filter */
2026   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2027     return;
2028
2029   current_ir_graph = irg;
2030
2031   f = vcg_open(irg, suffix, "-cfg");
2032   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2033
2034   if (ipv) {
2035     printf("Warning: dumping cfg not in interprocedural view!\n");
2036     set_interprocedural_view(false);
2037   }
2038
2039   if (get_irg_dom_state(irg) != dom_consistent)
2040     dump_dominator_information_flag = 0;
2041
2042   /* walk over the blocks in the graph */
2043   irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f);
2044   dump_node(f, get_irg_bad(irg));
2045
2046   dump_dominator_information_flag = ddif;
2047   set_interprocedural_view(ipv);
2048   vcg_close(f);
2049   current_ir_graph = rem;
2050 }
2051
2052 static int weight_overall(int rec, int loop) {
2053   return 2*rec + loop;
2054 }
2055
2056 static int compute_color (int my, int max) {
2057   int color;
2058   if (!max) {
2059     color = 0;
2060   } else {
2061     /* if small, scale to the full color range. */
2062     if (max < n_colors)
2063       my = my * (n_colors/max);
2064
2065     int step = 1 + (max / n_colors);
2066
2067     color = my/step;
2068   }
2069   return base_color + n_colors - color;
2070 }
2071
2072 static int get_entity_color(entity *ent) {
2073   assert(get_entity_irg(ent));
2074   ir_graph *irg = get_entity_irg(ent);
2075
2076   int rec_depth     = get_irg_recursion_depth(irg);
2077   int loop_depth    = get_irg_loop_depth(irg);
2078   int overall_depth = weight_overall(rec_depth, loop_depth);
2079
2080   int max_rec_depth     = irp->max_callgraph_recursion_depth;
2081   int max_loop_depth    = irp->max_callgraph_loop_depth;
2082   int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
2083
2084   /* int my_rec_color     = compute_color(rec_depth, max_rec_depth); */
2085   /* int my_loop_color    = compute_color(loop_depth, max_loop_depth); */
2086   int my_overall_color = compute_color(overall_depth, max_overall_depth);;
2087
2088   return my_overall_color;
2089 }
2090
2091 void dump_callgraph(const char *suffix) {
2092   FILE *F;
2093   int i, n_irgs = get_irp_n_irgs();
2094   int rem = edge_label;
2095   edge_label = 1;
2096   //ident *prefix = new_id_from_str("java/");
2097
2098   F = vcg_open_name("Callgraph", suffix);
2099   dump_vcg_header(F, "Callgraph", NULL);
2100
2101   for (i = 0; i < n_irgs; ++i) {
2102     ir_graph *irg = get_irp_irg(i);
2103     entity *ent = get_irg_entity(irg);
2104     int j, n_callees = get_irg_n_callees(irg);
2105
2106     /* Do not dump runtime system. */
2107     //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
2108
2109     dump_entity_node(F, ent, get_entity_color(ent));
2110     for (j = 0; j < n_callees; ++j) {
2111       entity *c = get_irg_entity(get_irg_callee(irg, j));
2112       //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
2113       int be = is_irg_callee_backedge(irg, j);
2114       char *attr;
2115       attr = (be) ?
2116         "label:\"recursion %d\" color: %d" :
2117         "label:\"calls %d\" color: %d";
2118       print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
2119     }
2120   }
2121
2122   edge_label = rem;
2123   vcg_close(F);
2124 }
2125
2126 /* Dump all irgs in interprocedural view to a single file. */
2127 void dump_all_cg_block_graph(const char *suffix) {
2128   FILE *f;
2129   int i;
2130   int rem_view = get_interprocedural_view();
2131   set_interprocedural_view(true);
2132
2133   f = vcg_open_name("All_graphs", suffix);
2134   dump_vcg_header(f, "All_graphs", NULL);
2135
2136   /* collect nodes in all irgs reachable in call graph*/
2137   for (i = 0; i < get_irp_n_irgs(); i++)
2138     ird_set_irg_link(get_irp_irg(i), NULL);
2139
2140   cg_walk(clear_link, collect_node, NULL);
2141
2142   /* dump all graphs */
2143   for (i = 0; i < get_irp_n_irgs(); i++) {
2144     current_ir_graph = get_irp_irg(i);
2145     assert(ird_get_irg_link(current_ir_graph));
2146     dump_graph(f, current_ir_graph);
2147     DEL_ARR_F(ird_get_irg_link(current_ir_graph));
2148   }
2149
2150   vcg_close(f);
2151   set_interprocedural_view(rem_view);
2152 }
2153
2154 /***********************************************************************/
2155 /* the following routines dumps type information without any ir nodes. */
2156 /***********************************************************************/
2157
2158 void
2159 dump_type_graph (ir_graph *irg, const char *suffix)
2160 {
2161   FILE *f;
2162   ir_graph *rem;
2163   rem = current_ir_graph;
2164
2165   /* if a filter is set, dump only the irg's that match the filter */
2166   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
2167
2168   current_ir_graph = irg;
2169
2170   f = vcg_open(irg, suffix, "-type");
2171   dump_vcg_header(f, get_irg_dump_name(irg), NULL);
2172
2173   /* walk over the blocks in the graph */
2174   type_walk_irg(irg, dump_type_info, NULL, f);
2175   /* The walker for the const code can be called several times for the
2176      same (sub) experssion.  So that no nodes are dumped several times
2177      we decrease the visited flag of the corresponding graph after each
2178      walk.  So now increase it finally. */
2179   inc_irg_visited(get_const_code_irg());
2180
2181   vcg_close(f);
2182   current_ir_graph = rem;
2183 }
2184
2185 void
2186 dump_all_types (const char *suffix)
2187 {
2188   FILE *f = vcg_open_name("All_types", suffix);
2189   dump_vcg_header(f, "All_types", NULL);
2190   type_walk(dump_type_info, NULL, f);
2191   inc_irg_visited(get_const_code_irg());
2192   vcg_close(f);
2193 }
2194
2195 void
2196 dump_class_hierarchy (bool entities, const char *suffix)
2197 {
2198   FILE *f = vcg_open_name("class_hierarchy", suffix);
2199   h_env_t env;
2200
2201   env.f = f;
2202   dump_vcg_header(f, "class_hierarchy", NULL);
2203   if (entities)
2204     env.dump_ent = 1;
2205   else
2206     env.dump_ent = 0;
2207   type_walk(dump_class_hierarchy_node, NULL, &env);
2208   vcg_close(f);
2209 }
2210
2211 /***********************************************************************/
2212 /* dumps all graphs with the graph-dumper passed. Possible dumpers:    */
2213 /*  dump_ir_graph                                                      */
2214 /*  dump_ir_block_graph                                                */
2215 /*  dump_cfg                                                           */
2216 /*  dump_type_graph                                                    */
2217 /*  dump_ir_graph_w_types                                              */
2218 /***********************************************************************/
2219
2220 void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) {
2221   int i, n_irgs = get_irp_n_irgs();
2222   for (i = 0; i < n_irgs; ++i) {
2223     dmp_grph(get_irp_irg(i), suffix);
2224   }
2225 }
2226
2227
2228 /**********************************************************************************
2229  * Dumps a stand alone loop graph with firm nodes which belong to one loop node   *
2230  * packed together in one subgraph/box                                            *
2231  **********************************************************************************/
2232
2233 void dump_loops_standalone(FILE *F, ir_loop *loop) {
2234   int i = 0, loop_node_started = 0, son_number = 0, first = 0;
2235   loop_element le;
2236   ir_loop *son = NULL;
2237
2238   /* Dump a new loop node. */
2239   dump_loop_node(F, loop);
2240
2241   /* Dump the loop elements. */
2242
2243   for(i = 0; i < get_loop_n_elements(loop); i++) {
2244     le = get_loop_element(loop, i);
2245     son = le.son;
2246     if (get_kind(son) == k_ir_loop) {
2247
2248       /* We are a loop son -> Recurse */
2249
2250       if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
2251         fprintf(F, "\" }\n");
2252         fprintf (F, "edge: {sourcename: \"");
2253         PRINT_LOOPID(loop);
2254         fprintf (F, "\" targetname: \"");
2255         PRINT_LOOPID(loop);
2256         fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2257         loop_node_started = 0;
2258       }
2259       dump_loop_son_edge(F, loop, son_number++);
2260       dump_loops_standalone(F, son);
2261     } else if (get_kind(son) == k_ir_node) {
2262       /* We are a loop node -> Collect firm nodes */
2263
2264       ir_node *n = le.node;
2265       int bad = 0;
2266
2267       if (!loop_node_started) {
2268     /* Start a new node which contains all firm nodes of the current loop */
2269     fprintf (F, "node: { title: \"");
2270     PRINT_LOOPID(loop);
2271     fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2272     loop_node_started = 1;
2273     first = i;
2274       }
2275       else
2276     fprintf(F, "\n");
2277
2278       bad |= dump_node_opcode(F, n);
2279       bad |= dump_node_mode(F, n);
2280       bad |= dump_node_typeinfo(F, n);
2281       fprintf (F, " ");
2282       bad |= dump_node_nodeattr(F, n);
2283       fprintf (F, " %ld", get_irn_node_nr(n));
2284       if (is_Block(n)) fprintf (F, "\t ->%d", (int)get_irn_link(n));
2285       if (has_backedges(n)) fprintf(F, "\t loop head!");
2286     } else { /* for callgraph loop tree */
2287       assert(get_kind(son) == k_ir_graph);
2288       /* We are a loop node -> Collect firm graphs */
2289       ir_graph *n = (ir_graph *)le.node;
2290       if (!loop_node_started) {
2291     /* Start a new node which contains all firm nodes of the current loop */
2292     fprintf (F, "node: { title: \"");
2293     PRINT_LOOPID(loop);
2294     fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2295     loop_node_started = 1;
2296     first = i;
2297       }
2298       else
2299     fprintf(F, "\n");
2300       fprintf (F, " %s", get_irg_dump_name(n));
2301       /* fprintf (F, " %s (depth %d)", get_irg_dump_name(n), n->callgraph_weighted_loop_depth); */
2302     }
2303   }
2304
2305   if (loop_node_started) {
2306     fprintf(F, "\" }\n");
2307     fprintf (F, "edge: {sourcename: \"");
2308     PRINT_LOOPID(loop);
2309     fprintf (F, "\" targetname: \"");
2310     PRINT_LOOPID(loop);
2311     fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2312     loop_node_started = 0;
2313   }
2314 }
2315
2316 void dump_loop_tree(ir_graph *irg, const char *suffix)
2317 {
2318   FILE *f;
2319   ir_graph *rem = current_ir_graph;
2320   int el_rem = edge_label;
2321   edge_label = 1;
2322
2323   /* if a filter is set, dump only the irg's that match the filter */
2324   if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
2325     return;
2326
2327   current_ir_graph = irg;
2328
2329   f = vcg_open(irg, suffix, "-looptree");
2330   dump_vcg_header(f, get_irg_dump_name(irg), "top_to_bottom");
2331
2332   if (get_irg_loop(irg)) dump_loops_standalone(f, get_irg_loop(irg));
2333
2334   vcg_close(f);
2335
2336   edge_label = el_rem;
2337   current_ir_graph = rem;
2338 }
2339
2340 void dump_callgraph_loop_tree(const char *suffix) {
2341   FILE *F;
2342   F = vcg_open_name("Callgraph_looptree", suffix);
2343   dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
2344   dump_loops_standalone(F, irp->outermost_cg_loop);
2345   vcg_close(F);
2346 }
2347
2348
2349 /*******************************************************************************/
2350 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
2351 /*******************************************************************************/
2352
2353 void collect_nodeloop(FILE *F, ir_loop *loop, eset *loopnodes) {
2354   int i, son_number = 0, node_number = 0;
2355
2356   if (dump_loop_information_flag) dump_loop_node(F, loop);
2357
2358   for (i = 0; i < get_loop_n_elements(loop); i++) {
2359     loop_element le = get_loop_element(loop, i);
2360     if (*(le.kind) == k_ir_loop) {
2361       if (dump_loop_information_flag) dump_loop_son_edge(F, loop, son_number++);
2362       /* Recur */
2363       collect_nodeloop(F, le.son, loopnodes);
2364     } else {
2365       if (dump_loop_information_flag) dump_loop_node_edge(F, loop, node_number++);
2366       eset_insert(loopnodes, le.node);
2367     }
2368   }
2369 }
2370
2371 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
2372   int i, j, start;
2373
2374   for(i = 0; i < get_loop_n_elements(loop); i++) {
2375     loop_element le = get_loop_element(loop, i);
2376     if (*(le.kind) == k_ir_loop) {
2377       /* Recur */
2378       collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
2379     } else {
2380       if (is_Block(le.node)) start = 0; else start = -1;
2381       for (j = start; j < get_irn_arity(le.node); j++) {
2382         ir_node *pred = get_irn_n(le.node, j);
2383         if (!eset_contains(loopnodes, pred)) {
2384           eset_insert(extnodes, pred);
2385           if (!is_Block(pred)) {
2386             pred = get_nodes_block(pred);
2387             if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
2388           }
2389         }
2390       }
2391     }
2392   }
2393 }
2394
2395 void dump_loop(ir_loop *l, const char *suffix) {
2396   FILE *F;
2397   char name[50];
2398   eset *loopnodes = eset_create();
2399   eset *extnodes = eset_create();
2400   ir_node *n, *b;
2401
2402   snprintf(name, sizeof(name), "loop_%d", get_loop_loop_nr(l));
2403   F = vcg_open_name (name, suffix);
2404   dump_vcg_header(F, name, NULL);
2405
2406   /* collect all nodes to dump */
2407   collect_nodeloop(F, l, loopnodes);
2408   collect_nodeloop_external_nodes(l, loopnodes, extnodes);
2409
2410   /* build block lists */
2411   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2412     set_irn_link(n, NULL);
2413   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2414     set_irn_link(n, NULL);
2415   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2416     if (!is_Block(n)) {
2417       b = get_nodes_block(n);
2418       set_irn_link(n, get_irn_link(b));
2419       set_irn_link(b, n);
2420     }
2421   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2422     if (!is_Block(n)) {
2423       b = get_nodes_block(n);
2424       set_irn_link(n, get_irn_link(b));
2425       set_irn_link(b, n);
2426     }
2427
2428   for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2429     if (is_Block(b)) {
2430       fprintf(F, "graph: { title: \"");
2431       PRINT_NODEID(b);
2432       fprintf(F, "\"  label: \"");
2433       dump_node_opcode(F, b);
2434       fprintf (F, " %ld", get_irn_node_nr(b));
2435       fprintf(F, "\" status:clustered color:yellow\n");
2436
2437       /* dump the blocks edges */
2438       dump_ir_data_edges(F, b);
2439
2440       /* dump the nodes that go into the block */
2441       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2442         if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2443         dump_node(F, n);
2444         overrule_nodecolor = NULL;
2445         if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n);
2446       }
2447
2448       /* Close the vcg information for the block */
2449       fprintf(F, "}\n");
2450       dump_const_node_local(F, b);
2451       fprintf(F, "\n");
2452     }
2453   for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2454     if (is_Block(b)) {
2455       fprintf(F, "graph: { title: \"");
2456       PRINT_NODEID(b);
2457       fprintf(F, "\"  label: \"");
2458       dump_node_opcode(F, b);
2459       fprintf (F, " %ld", get_irn_node_nr(b));
2460       fprintf(F, "\" status:clustered color:lightblue\n");
2461
2462       /* dump the nodes that go into the block */
2463       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2464         if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2465         dump_node(F, n);
2466         overrule_nodecolor = NULL;
2467         if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n);
2468       }
2469
2470       /* Close the vcg information for the block */
2471       fprintf(F, "}\n");
2472       dump_const_node_local(F, b);
2473       fprintf(F, "\n");
2474     }
2475
2476   eset_destroy(loopnodes);
2477   eset_destroy(extnodes);
2478   vcg_close(F);
2479 }