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