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