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