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