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