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