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