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