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