Fixed 'inline' lossage --flo
[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   /* Loop node   Someone else please tell me what's wrong ...
615   if (get_irn_loop(n)) {
616     ir_loop *loop = get_irn_loop(n);
617     assert(loop);
618     fprintf(F, " in loop %d with depth %d\n",
619             get_loop_loop_nr(loop), get_loop_depth(loop));
620   }
621   */
622
623   /* Source types */
624   switch (get_irn_opcode(n)) {
625   case iro_Start: {
626     type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
627     fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
628     for (i = 0; i < get_method_n_params(tp); ++i)
629       fprintf(F, "  param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
630   } break;
631   case iro_Alloc: {
632     fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
633   } break;
634   case iro_Free: {
635     fprintf(F, "freeing entity of type %s \n", get_type_name_ex(get_Free_type(n), &bad));
636   } break;
637   case iro_Sel: {
638     entity *ent = get_Sel_entity(n);
639
640     if (ent) {
641       fprintf(F, "Selecting entity of type %s\n", get_type_name_ex(get_entity_type(ent), &bad));
642       fprintf(F, "  from entity of type %s\n", get_type_name_ex(get_entity_owner(ent), &bad));
643     }
644     else {
645       fprintf(F, "<NULL entity>\n");
646       bad = 1;
647     }
648   } break;
649   case iro_Call: {
650     type *tp = get_Call_type(n);
651     fprintf(F, "calling method of type %s \n", get_type_name_ex(tp, &bad));
652     for (i = 0; i < get_method_n_params(tp); ++i)
653       fprintf(F, "  param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
654     for (i = 0; i < get_method_n_ress(tp); ++i)
655       fprintf(F, "  resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
656     if (Call_has_callees(n)) {
657       fprintf(F, "possible callees: \n");
658       for (i = 0; i < get_Call_n_callees(n); i++) {
659     if (!get_Call_callee(n, i)) {
660       fprintf(F, "  %d external method\n", i);
661     } else {
662       fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
663     }
664       }
665     }
666   } break;
667   case iro_CallBegin: {
668     ir_node *call = get_CallBegin_call(n);
669     if (Call_has_callees(call)) {
670       fprintf(F, "possible callees: \n");
671       for (i = 0; i < get_Call_n_callees(call); i++) {
672     if (!get_Call_callee(call, i)) {
673       fprintf(F, "  %d external method\n", i);
674     } else {
675       fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
676     }
677       }
678     }
679   } break;
680   case iro_Return: {
681     if (!interprocedural_view) {
682       type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
683       fprintf(F, "return in method of type %s \n", get_type_name_ex(tp, &bad));
684       for (i = 0; i < get_method_n_ress(tp); ++i)
685     fprintf(F, "  res %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
686     }
687     } break;
688   case iro_Const: {
689     type *tp = get_Const_type(n);
690     assert(tp != none_type);
691     fprintf(F, "Const of type %s \n", get_type_name_ex(get_Const_type(n), &bad));
692   } break;
693   case iro_Filter: {
694     int i;
695     if (interprocedural_view) {
696       fprintf(F, "intra predecessor nodes:\n");
697       for (i = 0; i < get_irn_intra_arity(n); i++) {
698     ir_node *pred = get_irn_intra_n(n, i);
699     fprintf(F, "  %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
700       }
701     } else {
702       fprintf(F, "inter predecessor nodes:\n");
703       for (i = 0; i < get_irn_inter_arity(n); i++) {
704     ir_node *pred = get_irn_inter_n(n, i);
705     fprintf(F, "  %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
706         get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
707       }
708     }
709   } break;
710   default: ;
711   }
712
713   if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent  ||
714       get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent  )
715     if (get_irn_type(n) != none_type)
716       fprintf (F, "\nAnalysed type: %s", get_type_name_ex(get_irn_type(n), &bad));
717
718   fprintf (F, "\"");
719
720   return bad;
721 }
722
723
724 static INLINE
725 bool is_constlike_node(ir_node *n) {
726   ir_op *op = get_irn_op(n);
727   return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
728 }
729
730
731 /* outputs the predecessors of n, that are constants, local.  I.e.,
732    generates a copy of the constant predecessors for each node called with. */
733 static void dump_const_node_local(ir_node *n) {
734   int i;
735   if (!get_opt_dump_const_local()) return;
736
737   /* Use visited flag to avoid outputting nodes twice.
738      initialize it first. */
739   for (i = 0; i < get_irn_arity(n); i++) {
740     ir_node *con = get_irn_n(n, i);
741     if (is_constlike_node(con)) {
742       set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
743     }
744   }
745
746   for (i = 0; i < get_irn_arity(n); i++) {
747     ir_node *con = get_irn_n(n, i);
748     if (is_constlike_node(con) && irn_not_visited(con)) {
749       int bad = 0;
750
751       mark_irn_visited(con);
752       /* Generate a new name for the node by appending the names of
753      n and const. */
754       fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
755       fprintf(F, " label: \"");
756       bad |= dump_node_opcode(F, con);
757       dump_node_mode (con);
758       bad |= dump_node_typeinfo(con);
759       fprintf (F, " ");
760       bad |= dump_node_nodeattr(con);
761       fprintf(F, " %ld", get_irn_node_nr(con));
762       fprintf(F, "\" ");
763       bad |= dump_node_info(con);
764       dump_node_vcgattr(con, bad);
765       fprintf(F, "}\n");
766     }
767   }
768 }
769
770 static void print_node_error(const char *p)
771 {
772   if (! p)
773     return;
774
775   fprintf (F, " info2: \"%s\"", p);
776 }
777
778 static void dump_node(ir_node *n)
779 {
780   int bad = 0;
781   const char *p;
782
783   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
784   /* dump this node */
785   fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
786
787   bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
788   bad |= dump_node_opcode(F, n);
789   dump_node_mode (n);
790   bad |= dump_node_typeinfo(n);
791   fprintf(F, " ");
792   bad |= dump_node_nodeattr(n);
793   fprintf(F, " %ld", get_irn_node_nr(n));
794   fprintf(F, "\" ");
795   bad |= dump_node_info(n);
796   print_node_error(p);
797   dump_node_vcgattr(n, bad);
798   fprintf(F, "}\n");
799   dump_const_node_local(n);
800 #ifdef HEAPANAL
801   dump_chi_term(F, n);
802   dump_state(F, n);
803 #endif
804 }
805
806 /* dump the edge to the block this node belongs to */
807 static void
808 dump_ir_block_edge(ir_node *n)  {
809   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
810   if (is_no_Block(n)) {
811     fprintf (F, "edge: { sourcename: \"");
812     PRINT_NODEID(n);
813     fprintf (F, "\" targetname: \"");
814     PRINT_NODEID(get_nodes_block(n));
815     fprintf (F, "\" "   BLOCK_EDGE_ATTR "}\n");
816   }
817 }
818
819 static void print_edge_vcgattr(ir_node *from, int to) {
820   assert(from);
821
822   if (dump_backedge_information_flag && is_backedge(from, to))
823     fprintf (F, BACK_EDGE_ATTR);
824
825   switch (get_irn_opcode(from)) {
826   case iro_Block:
827     fprintf (F, CF_EDGE_ATTR);
828     break;
829   case iro_Start:   break;
830   case iro_End:
831     if (to >= 0) {
832       if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
833     fprintf (F, CF_EDGE_ATTR);
834       if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
835     fprintf (F, MEM_EDGE_ATTR);
836     }
837     break;
838   case iro_EndReg: break;
839   case iro_EndExcept: break;
840   case iro_Jmp:     break;
841   case iro_Break:   break;
842   case iro_Cond:    break;
843   case iro_Return:
844   case iro_Raise:
845     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
846     break;
847   case iro_Const:   break;
848   case iro_SymConst:break;
849   case iro_Sel:
850   case iro_Call:
851     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
852     break;
853   case iro_CallBegin: break;
854   case iro_Add:     break;
855   case iro_Sub:     break;
856   case iro_Minus:   break;
857   case iro_Mul:     break;
858   case iro_Quot:
859   case iro_DivMod:
860   case iro_Div:
861   case iro_Mod:
862     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
863     break;
864   case iro_Abs:    break;
865   case iro_And:    break;
866   case iro_Or:     break;
867   case iro_Eor:    break;
868   case iro_Shl:    break;
869   case iro_Shr:    break;
870   case iro_Shrs:   break;
871   case iro_Rot:    break;
872   case iro_Cmp:    break;
873   case iro_Conv:   break;
874   case iro_Phi:
875     if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
876     break;
877   case iro_Load:
878   case iro_Store:
879   case iro_Alloc:
880   case iro_Free:
881     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
882     break;
883   case iro_Sync:
884     fprintf (F, MEM_EDGE_ATTR);
885     break;
886   case iro_Tuple:  break;
887   case iro_Proj:
888   case iro_Filter:
889     switch (get_irn_modecode(from)) {
890     case irm_X:
891       fprintf (F, CF_EDGE_ATTR);
892       break;
893     case irm_M:
894       fprintf (F, MEM_EDGE_ATTR);
895       break;
896     default: break;
897     }
898     break;
899   case iro_Bad:    break;
900   case iro_Unknown: break;
901   case iro_Id:     break;
902   default:
903     ;
904   }
905 }
906
907 /* dump edges to our inputs */
908 static void
909 dump_ir_data_edges(ir_node *n)  {
910   int i, visited = get_irn_visited(n);
911
912   if ((get_irn_op(n) == op_End) && (!dump_keepalive))
913     return;
914
915   for (i = 0; i < get_irn_arity(n); i++) {
916     ir_node * pred = get_irn_n(n, i);
917     assert(pred);
918
919     if ((interprocedural_view && get_irn_visited(pred) < visited))
920       continue; /* pred not dumped */
921
922     if (dump_backedge_information_flag && is_backedge(n, i))
923       fprintf (F, "backedge: {sourcename: \"");
924     else
925       fprintf (F, "edge: {sourcename: \"");
926     PRINT_NODEID(n);
927     fprintf (F, "\" targetname: ");
928     if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
929       PRINT_CONSTID(n, pred);
930     } else {
931       fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
932     }
933     fprintf (F, " label: \"%d\" ", i);
934     print_edge_vcgattr(n, i);
935     fprintf (F, "}\n");
936   }
937 }
938
939 /** Dumps a node and its edges but not the block edge
940  */
941 static INLINE void
942 dump_node_wo_blockedge (ir_node *n, void* env) {
943   dump_node(n);
944   dump_ir_data_edges(n);
945 }
946
947 /** Dumps a node and its edges.
948  */
949 static void
950 dump_whole_node (ir_node *n, void* env) {
951   dump_node_wo_blockedge(n, env);
952   if (!node_floats(n)) dump_ir_block_edge(n);
953 }
954
955 static void
956 dump_const_node(ir_node *n, void *env) {
957   if (is_Block(n)) return;
958   dump_node_wo_blockedge(n, env);
959 }
960
961 /***********************************************************************/
962 /* the following routines dump the nodes/irgs bracketed to graphs.     */
963 /***********************************************************************/
964
965 /** Dumps a constant expression as entity initializer, array bound ...
966  */
967 static void dump_const_expression(ir_node *value) {
968   ir_graph *rem = current_ir_graph;
969   int rem_dump_const_local = dump_const_local;
970   dump_const_local = 0;
971   current_ir_graph = get_const_code_irg();
972   irg_walk(value, dump_const_node, NULL, NULL);
973   /* Decrease visited flag so that we walk with the same flag for the next
974      expresssion.  This guarantees that we don't dump the same node twice,
975      as for const expressions cse is performed to save memory. */
976   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
977   current_ir_graph = rem;
978   dump_const_local = rem_dump_const_local;
979 }
980
981 /** Dump a block as graph containing its nodes.
982  *
983  *  Expects to find nodes belonging to the block as list in its
984  *  link field.
985  *  Dumps the edges of all nodes including itself. */
986 static void
987 dump_whole_block(ir_node *block) {
988   ir_node *node;
989   assert(is_Block(block));
990
991   fprintf(F, "graph: { title: \"");
992   PRINT_NODEID(block);
993   fprintf(F, "\"  label: \"");
994   dump_node_opcode(F, block);
995   fprintf (F, " %ld", get_irn_node_nr(block));
996 #ifdef HEAPANAL
997   if (get_opt_dump_abstvals())
998     fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
999 #endif
1000   fprintf(F, "\" status:clustered color:%s \n",
1001        get_Block_matured(block) ? "yellow" : "red");
1002
1003   /* dump the blocks edges */
1004   dump_ir_data_edges(block);
1005
1006   /* dump the nodes that go into the block */
1007   for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
1008     dump_node(node);
1009     dump_ir_data_edges(node);
1010   }
1011
1012   /* Close the vcg information for the block */
1013   fprintf(F, "}\n");
1014   dump_const_node_local(block);
1015 #ifdef HEAPANAL
1016   dump_chi_term(F, block);
1017 #endif
1018   fprintf(F, "\n");
1019 }
1020
1021 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
1022  *  The outermost nodes: blocks and nodes not pinned, Bad, Unknown. */
1023 static void
1024 dump_block_graph(ir_graph *irg) {
1025   int i;
1026   ir_graph *rem = current_ir_graph;
1027   ir_node **arr = ird_get_irg_link(irg);
1028   current_ir_graph = irg;
1029
1030   for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1031     ir_node * node = arr[i];
1032     if (is_Block(node)) {
1033       /* Dumps the block and all the nodes in the block, which are to
1034      be found in Block->link. */
1035       dump_whole_block(node);
1036     } else {
1037       /* Nodes that are not in a Block. */
1038       dump_node(node);
1039       dump_ir_data_edges(node);
1040     }
1041   }
1042
1043   if (dump_loop_information_flag) dump_loop_nodes_into_graph(irg);
1044
1045   current_ir_graph = rem;
1046 }
1047
1048 /** Dumps an irg as a graph.
1049  *  If interprocedural view edges can point to nodes out of this graph.
1050  */
1051 static void dump_graph(ir_graph *irg) {
1052
1053   fprintf(F, "graph: { title: \"");
1054   PRINT_IRGID(irg);
1055   fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
1056       get_ent_dump_name(get_irg_ent(irg)));
1057
1058   dump_block_graph (irg);
1059
1060   /* Close the vcg information for the irg */
1061   fprintf(F, "}\n\n");
1062 }
1063
1064 /*******************************************************************/
1065 /* Basic type and entity nodes and edges.                          */
1066 /*******************************************************************/
1067
1068 /* dumps the edges between nodes and their type or entity attributes. */
1069 static void dump_node2type_edges (ir_node *n, void *env)
1070 {
1071   assert(n);
1072
1073   switch (get_irn_opcode(n)) {
1074   case iro_Const :
1075     /* @@@ some consts have an entity */
1076     break;
1077   case iro_SymConst:
1078     if (   (get_SymConst_kind(n) == type_tag)
1079        || (get_SymConst_kind(n) == size))
1080       {
1081     print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1082       }
1083     break;
1084   case iro_Sel: {
1085       print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1086     } break;
1087   case iro_Call: {
1088       print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1089     } break;
1090   case iro_Alloc: {
1091       print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1092     } break;
1093   case iro_Free: {
1094       print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1095     } break;
1096   case iro_Cast: {
1097       print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1098     } break;
1099   default:
1100     break;
1101   }
1102 }
1103
1104
1105 static void print_type_info(type *tp) {
1106   if (get_type_state(tp) == layout_undefined) {
1107     fprintf(F, "state: layout_undefined\n");
1108   } else {
1109     fprintf(F, "state: layout_fixed,\n");
1110   }
1111   if (get_type_mode(tp))
1112     fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
1113   fprintf(F, "size: %dB,\n", get_type_size(tp));
1114 }
1115
1116 static void print_typespecific_info(type *tp) {
1117   switch (get_type_tpop_code(tp)) {
1118   case tpo_class:
1119     {
1120       fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1121     } break;
1122   case tpo_struct:
1123     {
1124     } break;
1125   case tpo_method:
1126     {
1127       fprintf(F, "variadicity: %s\n", get_variadicity_name(get_method_variadicity(tp)));
1128       fprintf(F, "params: %d\n", get_method_n_params(tp));
1129       fprintf(F, "results: %d\n", get_method_n_ress(tp));
1130     } break;
1131   case tpo_union:
1132     {
1133     } break;
1134   case tpo_array:
1135     {
1136     } break;
1137   case tpo_enumeration:
1138     {
1139     } break;
1140   case tpo_pointer:
1141     {
1142     } break;
1143   case tpo_primitive:
1144     {
1145     } break;
1146   default: break;
1147   } /* switch type */
1148 }
1149
1150
1151 static void print_typespecific_vcgattr(type *tp) {
1152   switch (get_type_tpop_code(tp)) {
1153   case tpo_class:
1154     {
1155       if (peculiarity_existent == get_class_peculiarity(tp))
1156     fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1157       else
1158     fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1159     } break;
1160   case tpo_struct:
1161     {
1162       fprintf (F, " " TYPE_METH_NODE_ATTR);
1163     } break;
1164   case tpo_method:
1165     {
1166     } break;
1167   case tpo_union:
1168     {
1169     } break;
1170   case tpo_array:
1171     {
1172     } break;
1173   case tpo_enumeration:
1174     {
1175     } break;
1176   case tpo_pointer:
1177     {
1178     } break;
1179   case tpo_primitive:
1180     {
1181     } break;
1182   default: break;
1183   } /* switch type */
1184 }
1185
1186 static int print_type_node(type *tp)
1187 {
1188   int bad = 0;
1189
1190   fprintf (F, "node: {title: ");
1191   PRINT_TYPEID(tp);
1192   fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
1193   fprintf (F, " info1: \"");
1194   print_type_info(tp);
1195   print_typespecific_info(tp);
1196   fprintf (F, "\"");
1197   print_typespecific_vcgattr(tp);
1198   fprintf (F, "}\n");
1199
1200   return bad;
1201 }
1202
1203 #define X(a)    case a: fprintf(F, #a); break
1204 void dump_entity_node(entity *ent)
1205 {
1206   fprintf (F, "node: {title: \"");
1207   PRINT_ENTID(ent); fprintf(F, "\"");
1208   fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1209   fprintf (F, "label: ");
1210   fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
1211   fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
1212
1213   fprintf (F, "\nallocation:  ");
1214   switch (get_entity_allocation(ent)) {
1215     X(allocation_dynamic);
1216     X(allocation_automatic);
1217     X(allocation_static);
1218     X(allocation_parameter);
1219   }
1220
1221   fprintf (F, "\nvisibility:  ");
1222   switch (get_entity_visibility(ent)) {
1223     X(visibility_local);
1224     X(visibility_external_visible);
1225     X(visibility_external_allocated);
1226   }
1227
1228   fprintf (F, "\nvariability: ");
1229   switch (get_entity_variability(ent)) {
1230     X(variability_uninitialized);
1231     X(variability_initialized);
1232     X(variability_part_constant);
1233     X(variability_constant);
1234   }
1235
1236   fprintf (F, "\nvolatility:  ");
1237   switch (get_entity_volatility(ent)) {
1238     X(volatility_non_volatile);
1239     X(volatility_is_volatile);
1240   }
1241
1242   fprintf(F, "\npeculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent)));
1243   fprintf(F, "\nname:    %s\nld_name: %s",
1244       get_entity_name(ent), ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
1245   fprintf(F, "\noffset:  %d", get_entity_offset(ent));
1246   if (is_method_type(get_entity_type(ent))) {
1247     if (get_entity_irg(ent))   /* can be null */
1248       { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
1249     else
1250       { fprintf (F, "\nirg = NULL"); }
1251   }
1252   fprintf(F, "\"\n}\n");
1253 }
1254 #undef X
1255
1256 static void dump_enum_item(type *tp, int pos)
1257 {
1258   char buf[1024];
1259   ident *id  = get_enumeration_nameid(tp, pos);
1260   tarval *tv = get_enumeration_enum(tp, pos);
1261
1262   tarval_snprintf(buf, sizeof(buf), tv);
1263   fprintf (F, "node: {title: \"");
1264   PRINT_ITEMID(tp, pos); fprintf(F, "\"");
1265   fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE);
1266   fprintf (F, "label: ");
1267   fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, id_to_str(id));
1268   fprintf (F, "\n info1: \"value: %s\"}\n", buf);
1269 }
1270
1271 /* dumps a type or entity and it's edges. */
1272 static void
1273 dump_type_info (type_or_ent *tore, void *env) {
1274   int i = 0;  /* to shutup gcc */
1275
1276   /* dump this type or entity */
1277
1278   switch (get_kind(tore)) {
1279   case k_entity:
1280     {
1281       entity *ent = (entity *)tore;
1282       ir_node *value;
1283       /* The node */
1284       dump_entity_node(ent);
1285       /* The Edges */
1286       /* skip this to reduce graph.  Member edge of type is parallel to this edge. *
1287       fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1288                 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1289       print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1290       if(is_class_type(get_entity_owner(ent))) {
1291     for(i = 0; i < get_entity_n_overwrites(ent); i++){
1292       print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
1293     }
1294       }
1295       /* attached subgraphs */
1296       if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1297     if (is_atomic_entity(ent)) {
1298       value = get_atomic_ent_value(ent);
1299       if (value) {
1300             print_ent_node_edge(F,ent, value, ENT_VALUE_EDGE_ATTR, i);
1301         /* DDMN(value);  $$$ */
1302         dump_const_expression(value);
1303       }
1304     }
1305     if (is_compound_entity(ent)) {
1306       for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1307         value = get_compound_ent_value(ent, i);
1308         if (value) {
1309               print_ent_node_edge(F,ent,value,ENT_VALUE_EDGE_ATTR,i);
1310           dump_const_expression(value);
1311           print_ent_ent_edge(F,ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
1312           /*
1313         fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1314         ENT_CORR_EDGE_ATTR  "}\n", GET_ENTID(ent),
1315         get_compound_ent_value_member(ent, i), i);
1316           */
1317         }
1318       }
1319     }
1320       }
1321     } break;
1322   case k_type:
1323     {
1324       type *tp = (type *)tore;
1325       print_type_node(tp);
1326       /* and now the edges */
1327       switch (get_type_tpop_code(tp)) {
1328       case tpo_class:
1329     {
1330       for (i=0; i < get_class_n_supertypes(tp); i++) {
1331         print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1332       }
1333
1334       for (i=0; i < get_class_n_members(tp); i++) {
1335         print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1336       }
1337     } break;
1338       case tpo_struct:
1339     {
1340       for (i=0; i < get_struct_n_members(tp); i++) {
1341         print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1342       }
1343     } break;
1344       case tpo_method:
1345     {
1346       for (i = 0; i < get_method_n_params(tp); i++)
1347       {
1348              print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1349       }
1350       for (i = 0; i < get_method_n_ress(tp); i++)
1351       {
1352              print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1353       }
1354     } break;
1355       case tpo_union:
1356     {
1357       for (i = 0; i < get_union_n_members(tp); i++)
1358       {
1359             print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1360       }
1361     } break;
1362       case tpo_array:
1363     {
1364       print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1365       print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1366       for (i = 0; i < get_array_n_dimensions(tp); i++) {
1367         ir_node *upper = get_array_upper_bound(tp, i);
1368         ir_node *lower = get_array_lower_bound(tp, i);
1369         print_node_type_edge(F,upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1370         print_node_type_edge(F,lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1371         dump_const_expression(upper);
1372         dump_const_expression(lower);
1373       }
1374
1375     } break;
1376       case tpo_enumeration:
1377     {
1378       for (i = 0; i < get_enumeration_n_enums(tp); ++i) {
1379         dump_enum_item(tp, i);
1380         print_enum_item_edge(F, tp, i, "label: \"item %d\"", i);
1381       }
1382     } break;
1383       case tpo_pointer:
1384     {
1385           print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1386     } break;
1387       case tpo_primitive:
1388     {
1389     } break;
1390       default: break;
1391       } /* switch type */
1392     }
1393     break; /* case k_type */
1394   default:
1395     {
1396       printf(" *** irdump,  dump_type_info(l.%i), faulty type.\n", __LINE__);
1397     } break;
1398   } /* switch kind_or_entity */
1399 }
1400
1401 /** For dumping class hierarchies.
1402  * Dumps a class type node and a superclass edge.
1403  * If env != null dumps entities of classes and overwrites edges.
1404  */
1405 static void
1406 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1407   int i = 0;  /* to shutup gcc */
1408
1409   /* dump this type or entity */
1410   switch (get_kind(tore)) {
1411   case k_entity: {
1412     entity *ent = (entity *)tore;
1413     if (get_entity_owner(ent) == get_glob_type()) break;
1414     if ((env) && is_class_type(get_entity_owner(ent))) {
1415       /* The node */
1416       dump_entity_node(ent);
1417       /* The edges */
1418       print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1419       for(i = 0; i < get_entity_n_overwrites(ent); i++)
1420       {
1421       print_ent_ent_edge(F,get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1422       }
1423     }
1424   } break; /* case k_entity */
1425   case k_type:
1426     {
1427       type *tp = (type *)tore;
1428       if (tp == get_glob_type()) break;
1429       switch (get_type_tpop_code(tp)) {
1430         case tpo_class: {
1431       print_type_node(tp);
1432       /* and now the edges */
1433       for (i=0; i < get_class_n_supertypes(tp); i++)
1434       {
1435           print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1436       }
1437         } break;
1438         default: break;
1439       } /* switch type */
1440     }
1441     break; /* case k_type */
1442   default:
1443     {
1444       printf(" *** irdump,  dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1445     } break;
1446   } /* switch kind_or_entity */
1447 }
1448
1449 /*******************************************************************/
1450 /* dump analysis information that is expressed in graph terms.     */
1451 /*******************************************************************/
1452
1453 /* dump out edges */
1454 static void
1455 dump_out_edge (ir_node *n, void* env) {
1456   int i;
1457   for (i = 0; i < get_irn_n_outs(n); i++) {
1458     assert(get_irn_out(n, i));
1459     fprintf (F, "edge: {sourcename: \"");
1460     PRINT_NODEID(n);
1461     fprintf (F, "\" targetname: \"");
1462     PRINT_NODEID(get_irn_out(n, i));
1463     fprintf (F, "\" color: red linestyle: dashed");
1464     fprintf (F, "}\n");
1465   }
1466 }
1467
1468 static INLINE void
1469 dump_loop_label(ir_loop *loop) {
1470   fprintf (F, "loop %d, %d sons, %d nodes",
1471        get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1472 }
1473
1474 static INLINE void dump_loop_info(ir_loop *loop) {
1475   fprintf (F, " info1: \"");
1476   fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1477 #if DEBUG_libfirm   /* GL @@@ debug analyses */
1478   fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1479 #endif
1480   fprintf (F, "\"");
1481 }
1482
1483 static INLINE void
1484 dump_loop_node(ir_loop *loop) {
1485   fprintf (F, "node: {title: \"");
1486   PRINT_LOOPID(loop);
1487   fprintf (F, "\" label: \"");
1488   dump_loop_label(loop);
1489   fprintf (F, "\" ");
1490   dump_loop_info(loop);
1491   fprintf (F, "}\n");
1492
1493 }
1494
1495 static INLINE void
1496 dump_loop_node_edge (ir_loop *loop, int i) {
1497   assert(loop);
1498   fprintf (F, "edge: {sourcename: \"");
1499   PRINT_LOOPID(loop);
1500   fprintf (F, "\" targetname: \"");
1501   PRINT_NODEID(get_loop_node(loop, i));
1502   fprintf (F, "\" color: green");
1503   fprintf (F, "}\n");
1504 }
1505
1506 static INLINE void
1507 dump_loop_son_edge (ir_loop *loop, int i) {
1508   assert(loop);
1509   fprintf (F, "edge: {sourcename: \"");
1510   PRINT_LOOPID(loop);
1511   fprintf (F, "\" targetname: \"");
1512   PRINT_LOOPID(get_loop_son(loop, i));
1513   fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1514        get_loop_element_pos(loop, get_loop_son(loop, i)));
1515 }
1516
1517 static
1518 void dump_loops (ir_loop *loop) {
1519   int i;
1520   /* dump this loop node */
1521   dump_loop_node(loop);
1522
1523   /* dump edges to nodes in loop -- only if it is a real loop */
1524   if (get_loop_depth(loop) != 0) {
1525     for (i = 0; i < get_loop_n_nodes(loop); i++) {
1526       dump_loop_node_edge(loop, i);
1527     }
1528   }
1529   for (i = 0; i < get_loop_n_sons(loop); i++) {
1530     dump_loops(get_loop_son(loop, i));
1531     dump_loop_son_edge(loop, i);
1532   }
1533 }
1534
1535 static INLINE
1536 void dump_loop_nodes_into_graph(ir_graph *irg) {
1537   ir_graph *rem = current_ir_graph;
1538   current_ir_graph = irg;
1539
1540   if (get_irg_loop(irg)) dump_loops(get_irg_loop(irg));
1541
1542   current_ir_graph = rem;
1543 }
1544
1545
1546 /************************************************************************/
1547 /* open and close vcg file                                              */
1548 /************************************************************************/
1549
1550 static INLINE void
1551 dump_vcg_header(const char *name, const char *orientation) {
1552   char *label;
1553
1554   if (edge_label) {
1555     label = "yes";
1556   } else {
1557     label = "no";
1558   }
1559
1560   if (!orientation) orientation = "bottom_to_top";
1561
1562   /* print header */
1563   fprintf (F,
1564        "graph: { title: \"ir graph of %s\"\n"
1565        "display_edge_labels: %s\n"
1566        "layoutalgorithm: mindepth\n"
1567        "manhattan_edges: yes\n"
1568        "port_sharing: no\n"
1569        "orientation: %s\n"
1570        "classname 1: \"Data\"\n"
1571        "classname 2: \"Block\"\n"
1572        "classname 13:\"Control Flow\"\n"
1573        "classname 14:\"Memory\"\n"
1574        "classname 15:\"Dominators\"\n"
1575        "classname 3: \"Entity type\"\n"
1576        "classname 4: \"Entity owner\"\n"
1577        "classname 5: \"Method Param\"\n"
1578        "classname 6: \"Method Res\"\n"
1579        "classname 7: \"Super\"\n"
1580        "classname 8: \"Union\"\n"
1581        "classname 9: \"Points-to\"\n"
1582        "classname 10: \"Array Element Type\"\n"
1583        "classname 11: \"Overwrites\"\n"
1584        "classname 12: \"Member\"\n"
1585            "infoname 1: \"Attribute\"\n"
1586        "infoname 2: \"Verification errors\"\n",
1587        name, label, orientation);
1588
1589   fprintf (F, "\n");        /* a separator */
1590 }
1591
1592 static void vcg_open (ir_graph *irg, char * suffix1, char *suffix2) {
1593   const char *nm = get_irg_dump_name(irg);
1594   int len = strlen(nm), i, j;
1595   char *fname;  /* filename to put the vcg information in */
1596
1597   if (!suffix1) suffix1 = "";
1598   if (!suffix2) suffix2 = "";
1599
1600   /** open file for vcg graph */
1601   fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5);
1602
1603   //strncpy (fname, nm, len);      /* copy the filename */
1604   j = 0;
1605   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
1606     if (nm[i] == '/') {
1607       fname[j] = '@'; j++; fname[j] = '1'; j++;
1608     } else if (nm[i] == '@') {
1609       fname[j] = '@'; j++; fname[j] = '2'; j++;
1610     } else {
1611       fname[j] = nm[i]; j++;
1612     }
1613   }
1614   fname[j] = '\0';
1615   strcat (fname, suffix1);  /* append file suffix */
1616   strcat (fname, suffix2);  /* append file suffix */
1617   strcat (fname, ".vcg");   /* append the .vcg suffix */
1618   F = fopen (fname, "w");   /* open file for writing */
1619   if (!F) {
1620     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
1621   }
1622   free(fname);
1623 }
1624
1625 static void vcg_open_name (const char *name, char *suffix) {
1626   char *fname;  /* filename to put the vcg information in */
1627   int i, j, len = strlen(name);
1628
1629   if (!suffix) suffix = "";
1630
1631   /** open file for vcg graph */
1632   fname = malloc (len * 2 + 5 + strlen(suffix));
1633   //strcpy (fname, name);    /* copy the filename */
1634   j = 0;
1635   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
1636     if (name[i] == '/') {
1637       fname[j] = '@'; j++; fname[j] = '1'; j++;
1638     } else if (name[i] == '@') {
1639       fname[j] = '@'; j++; fname[j] = '2'; j++;
1640     } else {
1641       fname[j] = name[i]; j++;
1642     }
1643   }
1644   fname[j] = '\0';
1645   strcat (fname, suffix);
1646   strcat (fname, ".vcg");  /* append the .vcg suffix */
1647   F = fopen (fname, "w");  /* open file for writing */
1648   if (!F) {
1649     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
1650   }
1651   free(fname);
1652 }
1653
1654 static INLINE void dump_vcg_footer (void) {
1655   fprintf (F, "}\n");
1656 }
1657
1658 static void
1659 vcg_close (void) {
1660   dump_vcg_footer();    /* print footer */
1661   fclose (F);           /* close vcg file */
1662 }
1663
1664 /************************************************************************/
1665 /************************************************************************/
1666 /* Routines that dump all or parts of the firm representation to a file */
1667 /************************************************************************/
1668 /************************************************************************/
1669
1670 /************************************************************************/
1671 /* Dump ir graphs, differnt formats and additional information.         */
1672 /************************************************************************/
1673
1674 /** Routine to dump a graph, blocks as conventional nodes.
1675  */
1676 void
1677 dump_ir_graph (ir_graph *irg)
1678 {
1679   ir_graph *rem;
1680   char *suffix;
1681   rem = current_ir_graph;
1682
1683   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1684
1685   current_ir_graph = irg;
1686   if (interprocedural_view) suffix = "-pure-ip";
1687   else                      suffix = "-pure";
1688   vcg_open (irg, dump_file_suffix, suffix);
1689   dump_vcg_header(get_irg_dump_name(irg), NULL);
1690
1691   /* walk over the graph */
1692   /* dump_whole_node must be called in post visiting predecessors */
1693   irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1694
1695   /* dump the out edges in a separate walk */
1696   if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1697     irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1698   }
1699
1700   vcg_close();
1701
1702   current_ir_graph = rem;
1703 }
1704
1705
1706 void
1707 dump_ir_block_graph (ir_graph *irg)
1708 {
1709   int i;
1710   char *suffix;
1711
1712   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1713
1714   if (interprocedural_view) suffix = "-ip";
1715   else                      suffix = "";
1716   vcg_open (irg, dump_file_suffix, suffix);
1717   dump_vcg_header(get_irg_dump_name(irg), NULL);
1718
1719   construct_block_lists(irg);
1720
1721   for (i = 0; i < get_irp_n_irgs(); i++) {
1722     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1723     if (arr) {
1724       dump_graph(get_irp_irg(i));
1725       DEL_ARR_F(arr);
1726     }
1727   }
1728
1729   vcg_close();
1730 }
1731
1732 /** dumps a graph with type information
1733  */
1734 void
1735 dump_ir_graph_w_types (ir_graph *irg)
1736 {
1737   ir_graph *rem = current_ir_graph;
1738   char *suffix;
1739
1740   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1741
1742   current_ir_graph = irg;
1743
1744   if (interprocedural_view) suffix = "-pure-wtypes-ip";
1745   else                      suffix = "-pure-wtypes";
1746   vcg_open (irg, dump_file_suffix, suffix);
1747   dump_vcg_header(get_irg_dump_name(irg), NULL);
1748
1749   /* dump common ir graph */
1750   irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1751   /* dump type info */
1752   type_walk_irg(irg, dump_type_info, NULL, NULL);
1753   inc_irg_visited(get_const_code_irg());
1754   /* dump edges from graph to type info */
1755   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1756
1757   vcg_close();
1758   current_ir_graph = rem;
1759 }
1760
1761 void
1762 dump_ir_block_graph_w_types (ir_graph *irg)
1763 {
1764   int i;
1765   char *suffix;
1766   ir_graph *rem = current_ir_graph;
1767
1768   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1769
1770   if (interprocedural_view) suffix = "-wtypes-ip";
1771   else                      suffix = "-wtypes";
1772   vcg_open (irg, dump_file_suffix, suffix);
1773   dump_vcg_header(get_irg_dump_name(irg), NULL);
1774
1775   /* dump common blocked ir graph */
1776   construct_block_lists(irg);
1777
1778   for (i = 0; i < get_irp_n_irgs(); i++) {
1779     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1780     if (arr) {
1781       dump_graph(get_irp_irg(i));
1782       DEL_ARR_F(arr);
1783     }
1784   }
1785
1786   /* dump type info */
1787   current_ir_graph = irg;
1788   type_walk_irg(irg, dump_type_info, NULL, NULL);
1789   inc_irg_visited(get_const_code_irg());
1790
1791   /* dump edges from graph to type info */
1792   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1793
1794   current_ir_graph = rem;
1795   vcg_close();
1796 }
1797
1798 /***********************************************************************/
1799 /* The following routines dump a control flow graph.                   */
1800 /***********************************************************************/
1801
1802 static void
1803 dump_block_to_cfg (ir_node *block, void *env) {
1804   int i;
1805   ir_node *pred;
1806
1807   if (is_Block(block)) {
1808     /* This is a block. Dump a node for the block. */
1809     fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1810     fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1811     PRINT_NODEID(block);
1812     fprintf (F, "\" ");
1813     if (dump_dominator_information_flag)
1814       fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1815     fprintf (F, "}\n");
1816     /* Dump the edges */
1817     for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1818       if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1819     pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1820     fprintf (F, "edge: { sourcename: \"");
1821     PRINT_NODEID(block);
1822     fprintf (F, "\" targetname: \"");
1823     PRINT_NODEID(pred);
1824     fprintf (F, "\"}\n");
1825       }
1826
1827     /* Dump dominator edge */
1828     if (dump_dominator_information_flag && get_Block_idom(block)) {
1829       pred = get_Block_idom(block);
1830       fprintf (F, "edge: { sourcename: \"");
1831       PRINT_NODEID(block);
1832       fprintf (F, "\" targetname: \"");
1833       PRINT_NODEID(pred);
1834       fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1835     }
1836   }
1837 }
1838
1839 void
1840 dump_cfg (ir_graph *irg)
1841 {
1842   ir_graph *rem = current_ir_graph;
1843   int ddif = dump_dominator_information_flag;
1844   int ipv = interprocedural_view;
1845
1846   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1847
1848   current_ir_graph = irg;
1849
1850   vcg_open (irg, dump_file_suffix, "-cfg");
1851   dump_vcg_header(get_irg_dump_name(irg), NULL);
1852
1853   if (interprocedural_view) {
1854     printf("Warning: dumping cfg not in interprocedural view!\n");
1855     interprocedural_view = 0;
1856   }
1857
1858   if (get_irg_dom_state(irg) != dom_consistent)
1859     dump_dominator_information_flag = 0;
1860
1861   /* walk over the blocks in the graph */
1862   irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1863   dump_node (get_irg_bad(irg));
1864
1865   dump_dominator_information_flag = ddif;
1866   interprocedural_view = ipv;
1867   vcg_close();
1868   current_ir_graph = rem;
1869 }
1870
1871
1872
1873 /* Dump all irgs in interprocedural view to a single file. */
1874 void dump_all_cg_block_graph(void) {
1875   int i;
1876   int rem_view = interprocedural_view;
1877   interprocedural_view = 1;
1878
1879   vcg_open_name ("All_graphs", dump_file_suffix);
1880   dump_vcg_header("All_graphs", NULL);
1881
1882   /* collect nodes in all irgs reachable in call graph*/
1883   for (i = 0; i < get_irp_n_irgs(); i++)
1884     ird_set_irg_link(get_irp_irg(i), NULL);
1885
1886   cg_walk(clear_link, collect_node, NULL);
1887
1888   /* dump all graphs */
1889   for (i = 0; i < get_irp_n_irgs(); i++) {
1890     current_ir_graph = get_irp_irg(i);
1891     assert(ird_get_irg_link(current_ir_graph));
1892     dump_graph(current_ir_graph);
1893     DEL_ARR_F(ird_get_irg_link(current_ir_graph));
1894   }
1895
1896   vcg_close();
1897   interprocedural_view = rem_view;
1898 }
1899
1900 /***********************************************************************/
1901 /* the following routines dumps type information without any ir nodes. */
1902 /***********************************************************************/
1903
1904 void
1905 dump_type_graph (ir_graph *irg)
1906 {
1907   ir_graph *rem;
1908   rem = current_ir_graph;
1909
1910   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
1911
1912   current_ir_graph = irg;
1913
1914   vcg_open (irg, dump_file_suffix, "-type");
1915   dump_vcg_header(get_irg_dump_name(irg), NULL);
1916
1917   /* walk over the blocks in the graph */
1918   type_walk_irg(irg, dump_type_info, NULL, NULL);
1919   /* The walker for the const code can be called several times for the
1920      same (sub) experssion.  So that no nodes are dumped several times
1921      we decrease the visited flag of the corresponding graph after each
1922      walk.  So now increase it finally. */
1923   inc_irg_visited(get_const_code_irg());
1924
1925   vcg_close();
1926   current_ir_graph = rem;
1927 }
1928
1929 void
1930 dump_all_types (void)
1931 {
1932   vcg_open_name ("All_types", dump_file_suffix);
1933   dump_vcg_header("All_types", NULL);
1934   type_walk(dump_type_info, NULL, NULL);
1935   inc_irg_visited(get_const_code_irg());
1936   vcg_close();
1937 }
1938
1939 void
1940 dump_class_hierarchy (bool entities)
1941 {
1942   vcg_open_name ("class_hierarchy", dump_file_suffix);
1943   dump_vcg_header("class_hierarchy", NULL);
1944   if (entities)
1945     type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1946   else
1947     type_walk(dump_class_hierarchy_node, NULL, NULL);
1948   vcg_close();
1949 }
1950
1951 /***********************************************************************/
1952 /* dumps all graphs with the graph-dumper passed. Possible dumpers:    */
1953 /*  dump_ir_graph                                                      */
1954 /*  dump_ir_block_graph                                                */
1955 /*  dump_cfg                                                           */
1956 /*  dump_type_graph                                                    */
1957 /*  dump_ir_graph_w_types                                              */
1958 /***********************************************************************/
1959
1960 void dump_all_ir_graphs (dump_graph_func *dmp_grph) {
1961   int i;
1962   for (i=0; i < get_irp_n_irgs(); i++) {
1963     dmp_grph(get_irp_irg(i));
1964   }
1965 }
1966
1967
1968 /**********************************************************************************
1969  * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes  *
1970  * packed together in one subgraph                                                *
1971  **********************************************************************************/
1972
1973
1974
1975 void dump_loops_standalone (ir_loop *loop) {
1976   int i = 0, loop_node_started = 0, son_number = 0, first = 0;
1977   loop_element le;
1978   ir_loop *son = NULL;
1979
1980   /* Dump a new loop node. */
1981   dump_loop_node(loop);
1982
1983   /* Dump the loop elements. */
1984
1985   if (get_kind(son) == k_ir_loop)
1986     {
1987       /* We are a loop son -> Recurse */
1988       le = get_loop_element(loop, i);
1989
1990       son = le.son;
1991       if (get_kind(son) == k_ir_loop) {
1992         /* We are a loop son -> Recurse */
1993
1994         if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
1995           fprintf(F, "\" }\n");
1996           fprintf (F, "edge: {sourcename: \"");
1997           PRINT_LOOPID(loop);
1998           fprintf (F, "\" targetname: \"");
1999           PRINT_LOOPID(loop);
2000           fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2001           loop_node_started = 0;
2002         }
2003         dump_loop_son_edge(loop, son_number++);
2004         dump_loops_standalone(son);
2005       }
2006       else {
2007         /* We are a loop node -> Collect firm nodes */
2008
2009         ir_node *n = le.node;
2010
2011         if (!loop_node_started) {
2012           /* Start a new node which contains all firm nodes of the current loop */
2013           fprintf (F, "node: { title: \"");
2014           PRINT_LOOPID(loop);
2015           fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
2016           loop_node_started = 1;
2017           first = i;
2018         }
2019         else
2020           fprintf(F, "\n");
2021
2022         dump_node_opcode(F, n);
2023         dump_node_mode (n);
2024         dump_node_typeinfo(n);
2025         fprintf (F, " ");
2026         dump_node_nodeattr(n);
2027         fprintf (F, " %ld", get_irn_node_nr(n));
2028       }
2029     }
2030
2031   if (loop_node_started) {
2032     fprintf(F, "\" }\n");
2033     fprintf (F, "edge: {sourcename: \"");
2034     PRINT_LOOPID(loop);
2035     fprintf (F, "\" targetname: \"");
2036     PRINT_LOOPID(loop);
2037     fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
2038     loop_node_started = 0;
2039   }
2040 }
2041
2042 void dump_loop_tree(ir_graph *irg, char *suffix)
2043 {
2044   ir_graph *rem = current_ir_graph;
2045   int el_rem = edge_label;
2046   edge_label = 1;
2047
2048   if(strncmp(get_irg_dump_name(irg),dump_file_filter,strlen(dump_file_filter))!=0) return;
2049
2050   current_ir_graph = irg;
2051
2052   vcg_open(irg, suffix, "-looptree");
2053   dump_vcg_header(get_irg_dump_name(irg), "top_to_bottom");
2054
2055   if (get_irg_loop(irg)) dump_loops_standalone(get_irg_loop(irg));
2056
2057   vcg_close();
2058
2059   edge_label = el_rem;
2060   current_ir_graph = rem;
2061 }
2062
2063
2064 /*******************************************************************************/
2065 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
2066 /*******************************************************************************/
2067
2068 void collect_nodeloop(ir_loop *loop, eset *loopnodes) {
2069   int i, son_number = 0, node_number = 0;
2070
2071   if (dump_loop_information_flag) dump_loop_node(loop);
2072
2073   for (i = 0; i < get_loop_n_elements(loop); i++) {
2074     loop_element le = get_loop_element(loop, i);
2075     if (*(le.kind) == k_ir_loop) {
2076       if (dump_loop_information_flag) dump_loop_son_edge(loop, son_number++);
2077       /* Recur */
2078       collect_nodeloop(le.son, loopnodes);
2079     } else {
2080       if (dump_loop_information_flag) dump_loop_node_edge(loop, node_number++);
2081       eset_insert(loopnodes, le.node);
2082     }
2083   }
2084 }
2085
2086 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
2087   int i, j, start;
2088
2089   for(i = 0; i < get_loop_n_elements(loop); i++) {
2090     loop_element le = get_loop_element(loop, i);
2091     if (*(le.kind) == k_ir_loop) {
2092       /* Recur */
2093       collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
2094     } else {
2095       if (is_Block(le.node)) start = 0; else start = -1;
2096       for (j = start; j < get_irn_arity(le.node); j++) {
2097     ir_node *pred = get_irn_n(le.node, j);
2098     if (!eset_contains(loopnodes, pred)) {
2099       eset_insert(extnodes, pred);
2100       if (!is_Block(pred)) {
2101         pred = get_nodes_block(pred);
2102         if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
2103           }
2104     }
2105       }
2106     }
2107   }
2108 }
2109
2110 void dump_loop (ir_loop *l, char *suffix) {
2111   char name[50];
2112   eset *loopnodes = eset_create();
2113   eset *extnodes = eset_create();
2114   ir_node *n, *b;
2115
2116   sprintf(name, "loop_%d", get_loop_loop_nr(l));
2117   vcg_open_name (name, suffix);
2118   dump_vcg_header(name, NULL);
2119
2120   /* collect all nodes to dump */
2121   collect_nodeloop(l, loopnodes);
2122   collect_nodeloop_external_nodes(l, loopnodes, extnodes);
2123
2124   /* build block lists */
2125   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2126     set_irn_link(n, NULL);
2127   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2128     set_irn_link(n, NULL);
2129   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
2130     if (!is_Block(n)) {
2131       b = get_nodes_block(n);
2132       set_irn_link(n, get_irn_link(b));
2133       set_irn_link(b, n);
2134     }
2135   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
2136     if (!is_Block(n)) {
2137       b = get_nodes_block(n);
2138       set_irn_link(n, get_irn_link(b));
2139       set_irn_link(b, n);
2140     }
2141
2142   for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2143     if (is_Block(b)) {
2144       fprintf(F, "graph: { title: \"");
2145       PRINT_NODEID(b);
2146       fprintf(F, "\"  label: \"");
2147       dump_node_opcode(F, b);
2148       fprintf (F, " %ld", get_irn_node_nr(b));
2149       fprintf(F, "\" status:clustered color:yellow\n");
2150
2151       /* dump the blocks edges */
2152       dump_ir_data_edges(b);
2153
2154       /* dump the nodes that go into the block */
2155       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2156     if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2157     dump_node(n);
2158     overrule_nodecolor = NULL;
2159     if (!eset_contains(extnodes, n)) dump_ir_data_edges(n);
2160       }
2161
2162       /* Close the vcg information for the block */
2163       fprintf(F, "}\n");
2164       dump_const_node_local(b);
2165       fprintf(F, "\n");
2166     }
2167   for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2168     if (is_Block(b)) {
2169       fprintf(F, "graph: { title: \"");
2170       PRINT_NODEID(b);
2171       fprintf(F, "\"  label: \"");
2172       dump_node_opcode(F, b);
2173       fprintf (F, " %ld", get_irn_node_nr(b));
2174       fprintf(F, "\" status:clustered color:lightblue\n");
2175
2176       /* dump the nodes that go into the block */
2177       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2178     if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2179     dump_node(n);
2180     overrule_nodecolor = NULL;
2181     if (eset_contains(loopnodes, n)) dump_ir_data_edges(n);
2182       }
2183
2184       /* Close the vcg information for the block */
2185       fprintf(F, "}\n");
2186       dump_const_node_local(b);
2187       fprintf(F, "\n");
2188     }
2189
2190   eset_destroy(loopnodes);
2191   eset_destroy(extnodes);
2192   vcg_close();
2193 }