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