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