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