Added interprocedural view.
[libfirm] / ir / ir / irdump.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer
5 **
6 ** irdump.h: dumping of an intermediate representation graph
7 */
8
9 /* $Id$ */
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 # include "irnode_t.h"
16 # include "irgraph_t.h"
17 # include "irprog.h"
18 # include "irdump.h"
19 # include "panic.h"
20 # include <string.h>
21 # include "entity_t.h"
22 # include <stdlib.h>
23 # include "array.h"
24 # include "irop_t.h"
25 # include "tv.h"
26 # include "type_or_entity.h"
27 # include "irgwalk.h"
28 # include "typewalk.h"
29 # include "irouts.h"
30 # include "irdom.h"
31 # include "common_t.h"
32
33 # include "exc.h"
34
35 # include "pmap.h"
36
37 /* Attributes of nodes */
38 #define DEFAULT_NODE_ATTR ""
39 #define DEFAULT_TYPE_ATTRIBUTE ""
40
41 /* Attributes of edges between Firm nodes */
42 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
43 #define CF_EDGE_ATTR    "color: red"
44 #define MEM_EDGE_ATTR   "color: blue"
45 #define DOMINATOR_EDGE_ATTR "color: red"
46
47 /* Attributes of edges between Firm nodes and type/entity nodes */
48 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
49
50 /* Attributes of edges in type/entity graphs. */
51 #define TYPE_METH_NODE_ATTR  "color: lightyellow"
52 #define TYPE_CLASS_NODE_ATTR "color: green"
53 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
54 #define ENTITY_NODE_ATTR     "color: yellow"
55 #define ENT_TYPE_EDGE_ATTR   "class: 3 label: \"type\" color: red"
56 #define ENT_OWN_EDGE_ATTR    "class: 4 label: \"owner\" color: black"
57 #define METH_PAR_EDGE_ATTR   "class: 5 label: \"param %d\" color: green"
58 #define METH_RES_EDGE_ATTR   "class: 6 label: \"res %d\" color: green"
59 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
60 #define UNION_EDGE_ATTR      "class: 8 label: \"component\" color: blue"
61 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
62 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
63 #define ARR_ENT_EDGE_ATTR    "class: 10 label: \"arr ent\" color: green"
64 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
65 #define ENT_VALUE_EDGE_ATTR "label: \"value "
66 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
67 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
68
69
70 #if DEBUG_libfirm && NODEID_AS_LABEL
71 #define PRINT_NODEID(X) fprintf(F, "%ld", get_irn_node_nr(X))
72 #else
73 #define PRINT_NODEID(X) fprintf(F, "%p", X)
74 #endif
75
76 /* A suffix to manipulate the file name. */
77 char *dump_file_suffix = NULL;
78
79 /* file to dump to */
80 static FILE *F;
81
82 /* A compiler option to turn off edge labels */
83 int edge_label = 1;
84 /* A compiler option to turn off dumping values of constant entities */
85 int const_entities = 1;
86 /* A compiler option to dump the keep alive edges */
87 int dump_keepalive = 0;
88 /* A compiler option to dump the out edges in dump_ir_graph */
89 int dump_out_edge_flag = 0;
90 int dump_dominator_information_flag = 0;
91
92 /* A global variable to record output of the Bad node. */
93 int Bad_dumped;
94
95
96 void dump_ir_blocks_nodes (ir_node *n, void *env);
97 void dump_whole_node (ir_node *n, void* env);
98
99 /*******************************************************************/
100 /* routines to dump information about a single node                */
101 /*******************************************************************/
102
103
104
105 inline void
106 dump_node_opcode (ir_node *n)
107 {
108   assert(n && n->op);
109
110   /* Const */
111   if (n->op->code == iro_Const) {
112     xfprintf (F, "%v", n->attr.con);
113
114   /* SymConst */
115   } else if (n->op->code == iro_SymConst) {
116     if (get_SymConst_kind(n) == linkage_ptr_info) {
117       /* don't use get_SymConst_ptr_info as it mangles the name. */
118       xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
119     } else {
120       assert(get_kind(get_SymConst_type(n)) == k_type);
121       assert(get_type_ident(get_SymConst_type(n)));
122       xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
123       if (get_SymConst_kind == type_tag)
124         xfprintf (F, "tag");
125       else
126         xfprintf (F, "size");
127     }
128
129   /* Filter */
130   } else if (n->op->code == iro_Filter && !interprocedural_view) {
131     fprintf(F, "Proj'");
132
133   /* all others */
134   } else {
135     xfprintf (F, "%I", get_irn_opident(n));
136   }
137 }
138
139 inline void
140 dump_node_mode (ir_node *n)
141 {
142   switch (n->op->code) {
143   case iro_Phi:
144   case iro_Const:
145   case iro_Id:
146   case iro_Proj:
147   case iro_Filter:
148   case iro_Conv:
149   case iro_Tuple:
150   case iro_Add:
151   case iro_Sub:
152   case iro_Mul:
153   case iro_And:
154   case iro_Or:
155   case iro_Eor:
156   case iro_Shl:
157   case iro_Shr:
158   case iro_Abs:
159   case iro_Cmp:
160     xfprintf (F, "%I", get_mode_ident(n->mode));
161     break;
162   default:
163   }
164 }
165
166 inline void
167 dump_node_nodeattr (ir_node *n)
168 {
169   switch (n->op->code) {
170   case iro_Proj:
171     if (n->in[1]->op->code == iro_Cmp) {
172       xfprintf (F, "%s", get_pnc_string(n->attr.proj));
173     } else {
174       xfprintf (F, "%ld", n->attr.proj);
175     }
176     break;
177   case iro_Filter:
178     xfprintf (F, "%ld", n->attr.filter.proj);
179     break;
180   case iro_Sel: {
181     assert(get_kind(get_Sel_entity(n)) == k_entity);
182     xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
183     } break;
184   default:
185   } /* end switch */
186 }
187
188 inline void
189 dump_node_vcgattr (ir_node *n)
190 {
191   switch (n->op->code) {
192   case iro_Start:
193   case iro_EndReg:
194     /* fall through */
195   case iro_EndExcept:
196     /* fall through */
197   case iro_End:
198     xfprintf (F, "color: blue");
199     break;
200   case iro_Block:
201     xfprintf (F, "color: lightyellow");
202     break;
203   case iro_Phi:
204     xfprintf (F, "color: green");
205     break;
206   case iro_Const:
207   case iro_Proj:
208   case iro_Filter:
209   case iro_Tuple:
210     xfprintf (F, "color: yellow");
211     break;
212   default:
213     xfprintf (F, DEFAULT_NODE_ATTR);
214   }
215 }
216
217 void
218 dump_node (ir_node *n) {
219
220   /* dump this node */
221   xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
222
223   dump_node_opcode(n);
224   dump_node_mode (n);
225   xfprintf (F, " ");
226   dump_node_nodeattr(n);
227 #ifdef DEBUG_libfirm
228   xfprintf (F, " %ld", get_irn_node_nr(n));
229 #endif
230   xfprintf (F, "\" ");
231   dump_node_vcgattr(n);
232   xfprintf (F, "}\n");
233 }
234
235 void
236 dump_ir_node (ir_node *n)
237 {
238   /* dump this node */
239   fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
240
241   switch (n->op->code) {  /* node label */
242   case iro_Start:
243     xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
244     xfprintf (F, DEFAULT_NODE_ATTR);
245      break;
246   case iro_EndReg:
247     /* fall through */
248   case iro_EndExcept:
249     /* fall through */
250   case iro_End:
251     xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
252     xfprintf (F, DEFAULT_NODE_ATTR);
253     break;
254   case iro_Block:
255     xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
256     xfprintf (F, DEFAULT_NODE_ATTR);
257     break;
258   case iro_Phi:
259     xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
260     if (get_irn_modecode(n) == irm_M)
261       xfprintf (F, DEFAULT_NODE_ATTR " color: green");
262     else
263       xfprintf (F, DEFAULT_NODE_ATTR);
264     break;
265   case iro_Const:
266     xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
267     xfprintf (F, DEFAULT_NODE_ATTR);
268     break;
269   case iro_Id:
270     xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
271     xfprintf (F, DEFAULT_NODE_ATTR);
272     break;
273   case iro_Proj:
274     if (n->in[1]->op->code == iro_Cmp) {
275       xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
276                 get_pnc_string(n->attr.proj));
277     } else {
278       xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
279     }
280     xfprintf (F, DEFAULT_NODE_ATTR);
281     break;
282   case iro_Filter:
283     xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
284     xfprintf (F, DEFAULT_NODE_ATTR);
285     break;
286   case iro_Conv:
287     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
288     xfprintf (F, DEFAULT_NODE_ATTR);
289     break;
290   case iro_Tuple:
291     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
292     xfprintf (F, DEFAULT_NODE_ATTR);
293     break;
294   case iro_Add:
295     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
296     xfprintf (F, DEFAULT_NODE_ATTR);
297     break;
298   case iro_Sub:
299     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
300     xfprintf (F, DEFAULT_NODE_ATTR);
301     break;
302   case iro_Mul:
303     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
304     xfprintf (F, DEFAULT_NODE_ATTR);
305     break;
306   case iro_Quot:
307     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
308     xfprintf (F, DEFAULT_NODE_ATTR);
309     break;
310   case iro_DivMod:
311     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
312     xfprintf (F, DEFAULT_NODE_ATTR);
313     break;
314   case iro_Div:
315     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
316     xfprintf (F, DEFAULT_NODE_ATTR);
317     break;
318   case iro_Mod:
319     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
320     xfprintf (F, DEFAULT_NODE_ATTR);
321     break;
322   case iro_And:
323     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
324     xfprintf (F, DEFAULT_NODE_ATTR);
325     break;
326   case iro_Or:
327     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
328     xfprintf (F, DEFAULT_NODE_ATTR);
329     break;
330   case iro_Eor:
331     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
332     xfprintf (F, DEFAULT_NODE_ATTR);
333     break;
334   case iro_Shl:
335     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
336     xfprintf (F, DEFAULT_NODE_ATTR);
337     break;
338   case iro_Shr:
339     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
340     xfprintf (F, DEFAULT_NODE_ATTR);
341     break;
342   case iro_Abs:
343     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
344     xfprintf (F, DEFAULT_NODE_ATTR);
345     break;
346   case iro_Cmp:
347     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
348     xfprintf (F, DEFAULT_NODE_ATTR);
349     break;
350   case iro_Jmp:
351     xfprintf (F, "\"%I\"", get_irn_opident(n));
352     xfprintf (F, DEFAULT_NODE_ATTR);
353     break;
354   case iro_Break:
355     xfprintf (F, "\"%I\"", get_irn_opident(n));
356     xfprintf (F, DEFAULT_NODE_ATTR);
357     break;
358   case iro_Cond:
359     xfprintf (F, "\"%I\"", get_irn_opident(n));
360     xfprintf (F, DEFAULT_NODE_ATTR);
361     break;
362   case iro_Call:
363     xfprintf (F, "\"%I\"", get_irn_opident(n));
364     xfprintf (F, DEFAULT_NODE_ATTR);
365     break;
366   case iro_CallBegin:
367     xfprintf (F, "\"%I\"", get_irn_opident(n));
368     xfprintf (F, DEFAULT_NODE_ATTR);
369     break;
370   case iro_Return:
371     xfprintf (F, "\"%I\"", get_irn_opident(n));
372     xfprintf (F, DEFAULT_NODE_ATTR);
373     break;
374   case iro_Raise:
375     xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
376     xfprintf (F, DEFAULT_NODE_ATTR);
377     break;
378   case iro_Load:
379   case iro_Store:
380     xfprintf (F, "\"%R\"", n);
381     xfprintf (F, DEFAULT_NODE_ATTR);
382     break;
383   case iro_Alloc:
384     xfprintf (F, "\"%I\" ", get_irn_opident(n));
385     xfprintf (F, DEFAULT_NODE_ATTR);
386     break;
387   case iro_Sel:
388     assert(get_kind(get_Sel_entity(n)) == k_entity);
389     xfprintf (F, "\"%I ", get_irn_opident(n));
390     xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
391     xfprintf (F, DEFAULT_NODE_ATTR);
392     break;
393   case iro_SymConst:
394     assert(get_kind(get_SymConst_type(n)) == k_type);
395     assert(get_type_ident(get_SymConst_type(n)));
396     xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
397     switch (n->attr.i.num){
398     case type_tag:
399       xfprintf (F, "tag\" ");
400       break;
401     case size:
402       xfprintf (F, "size\" ");
403       break;
404     default:
405       assert(0);
406       break;
407     }
408     xfprintf (F, DEFAULT_NODE_ATTR);
409     break;
410   case iro_Sync:
411     xfprintf (F, "\"%I\" ", get_irn_opident(n));
412     xfprintf (F, DEFAULT_NODE_ATTR " color: green");
413     break;
414   case iro_Bad:
415     xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
416     xfprintf (F, DEFAULT_NODE_ATTR);
417     break;
418   case iro_Unknown:
419     xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
420     xfprintf (F, DEFAULT_NODE_ATTR);
421     break;
422   default:
423     xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
424   }
425   xfprintf (F, "}\n");          /* footer */
426 }
427
428
429 /* dump the edge to the block this node belongs to */
430 void
431 dump_ir_block_edge(ir_node *n)  {
432   if (is_no_Block(n)) {
433     xfprintf (F, "edge: { sourcename: \"");
434     PRINT_NODEID(n);
435     xfprintf (F, "\" targetname: \"");
436     PRINT_NODEID(get_nodes_Block(n));
437     xfprintf (F, "\" "  BLOCK_EDGE_ATTR "}\n");
438   }
439 }
440
441 void print_edge_vcgattr(ir_node *from, int to) {
442   assert(from);
443
444   switch (get_irn_opcode(from)) {
445   case iro_Block:
446     xfprintf (F, CF_EDGE_ATTR);
447     break;
448   case iro_Start:   break;
449   case iro_End:
450     if (to >= 0) {
451       if (get_irn_mode(get_End_keepalive(from, to)) == mode_R)
452         xfprintf (F, CF_EDGE_ATTR);
453       if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
454         xfprintf (F, MEM_EDGE_ATTR);
455     }
456     break;
457   case iro_EndReg: break;
458   case iro_EndExcept: break;
459   case iro_Jmp:     break;
460   case iro_Break:   break;
461   case iro_Cond:    break;
462   case iro_Return:
463   case iro_Raise:
464     if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
465     break;
466   case iro_Const:   break;
467   case iro_SymConst:break;
468   case iro_Sel:
469   case iro_Call:
470     if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
471     break;
472   case iro_CallBegin: break;
473   case iro_Add:     break;
474   case iro_Sub:     break;
475   case iro_Minus:   break;
476   case iro_Mul:     break;
477   case iro_Quot:
478   case iro_DivMod:
479   case iro_Div:
480   case iro_Mod:
481     if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
482     break;
483   case iro_Abs:    break;
484   case iro_And:    break;
485   case iro_Or:     break;
486   case iro_Eor:    break;
487   case iro_Shl:    break;
488   case iro_Shr:    break;
489   case iro_Shrs:   break;
490   case iro_Rot:    break;
491   case iro_Cmp:    break;
492   case iro_Conv:   break;
493   case iro_Phi:
494     if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
495     break;
496   case iro_Load:
497   case iro_Store:
498   case iro_Alloc:
499   case iro_Free:
500     if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
501     break;
502   case iro_Sync:
503     xfprintf (F, MEM_EDGE_ATTR);
504     break;
505   case iro_Tuple:  break;
506   case iro_Proj:
507   case iro_Filter:
508     switch (get_irn_modecode(from)) {
509     case irm_X:
510       xfprintf (F, CF_EDGE_ATTR);
511       break;
512     case irm_M:
513       xfprintf (F, MEM_EDGE_ATTR);
514       break;
515     default: break;
516     }
517     break;
518   case iro_Bad:    break;
519   case iro_Unknown: break;
520   case iro_Id:     break;
521   default:
522   }
523 }
524
525 /* dump edges to our inputs */
526 void
527 dump_ir_data_edges(ir_node *n)  {
528   int i, visited = get_irn_visited(n);
529
530   if ((get_irn_op(n) == op_End) && (!dump_keepalive))
531     return;
532
533   for (i = 0; i < get_irn_arity(n); i++) {
534     ir_node * pred = get_irn_n(n, i);
535     assert(pred);
536     if (interprocedural_view && get_irn_visited(pred) < visited) continue; /* pred not dumped */
537     fprintf (F, "edge: {sourcename: \"");
538     PRINT_NODEID(n);
539     fprintf (F, "\" targetname: \"");
540     PRINT_NODEID(pred);
541     fprintf (F, "\"");
542     fprintf (F, " label: \"%d\" ", i);
543     print_edge_vcgattr(n, i);
544     fprintf (F, "}\n");
545   }
546 }
547
548 /* dump out edges */
549 void
550 dump_out_edge (ir_node *n, void* env) {
551   int i;
552   for (i = 0; i < get_irn_n_outs(n); i++) {
553     assert(get_irn_out(n, i));
554     fprintf (F, "edge: {sourcename: \"");
555     PRINT_NODEID(n);
556     fprintf (F, "\" targetname: \"");
557     PRINT_NODEID(get_irn_out(n, i));
558     fprintf (F, "\" color: red linestyle: dashed");
559     fprintf (F, "}\n");
560   }
561 }
562
563
564 /* dumps the edges between nodes and their type or entity attributes. */
565 void dump_node2type_edges (ir_node *n, void *env)
566 {
567   assert(n);
568
569   switch (get_irn_opcode(n)) {
570   case iro_Const :
571     /* @@@ some consts have an entity */
572     break;
573   case iro_SymConst:
574     if (   (get_SymConst_kind(n) == type_tag)
575            || (get_SymConst_kind(n) == size)) {
576       xfprintf (F, "edge: { sourcename: \"");
577       PRINT_NODEID(n);
578       fprintf (F, "\" targetname: \"%p\" "
579                NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
580     }
581     break;
582   case iro_Sel: {
583     xfprintf (F, "edge: { sourcename: \"");
584     PRINT_NODEID(n);
585     fprintf (F, "\" targetname: \"%p\" "
586              NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
587     } break;
588   case iro_Call: {
589     xfprintf (F, "edge: { sourcename: \"");
590     PRINT_NODEID(n);
591     fprintf (F, "\" targetname: \"%p\" "
592              NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
593     } break;
594   case iro_Alloc: {
595     xfprintf (F, "edge: { sourcename: \"");
596     PRINT_NODEID(n);
597     fprintf (F, "\" targetname: \"%p\" "
598              NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
599     } break;
600   case iro_Free: {
601     xfprintf (F, "edge: { sourcename: \"");
602     PRINT_NODEID(n);
603     fprintf (F, "\" targetname: \"%p\" "
604              NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
605     } break;
606   default:
607     break;
608   }
609 }
610
611
612 void dump_const_expression(ir_node *value) {
613   ir_graph *rem = current_ir_graph;
614   current_ir_graph = get_const_code_irg();
615   irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
616   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
617   current_ir_graph = rem;
618 }
619
620
621 void print_type_info(type *tp) {
622   if (get_type_state(tp) == layout_undefined) {
623     xfprintf(F, "state: layout_undefined\n");
624   } else {
625     xfprintf(F, "state: layout_fixed,\n");
626   }
627   if (get_type_mode(tp))
628     xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
629   xfprintf(F, "size: %dB,\n", get_type_size(tp));
630 }
631
632
633 void print_typespecific_info(type *tp) {
634   switch (get_type_tpop_code(tp)) {
635   case tpo_class:
636     {
637       if(existent == get_class_peculiarity(tp))
638         xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
639       else
640         xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
641     } break;
642   case tpo_struct:
643     {
644       xfprintf (F, " " TYPE_METH_NODE_ATTR);
645     } break;
646   case tpo_method:
647     {
648     } break;
649   case tpo_union:
650     {
651     } break;
652   case tpo_array:
653     {
654     } break;
655   case tpo_enumeration:
656     {
657     } break;
658   case tpo_pointer:
659     {
660     } break;
661   case tpo_primitive:
662     {
663     } break;
664   default: break;
665   } /* switch type */
666 }
667
668 void print_type_node(type *tp) {
669   xfprintf (F, "node: {title: \"%p\" ", tp);
670   xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
671   xfprintf (F, "info1: \"");
672   print_type_info(tp);
673   xfprintf (F, "\"");
674   print_typespecific_info(tp);
675   xfprintf (F, "}\n");
676 }
677
678 /* dumps a type or entity and it's edges. */
679 void
680 dump_type_info (type_or_ent *tore, void *env) {
681   int i = 0;  /* to shutup gcc */
682
683   /* dump this type or entity */
684
685   switch (get_kind(tore)) {
686   case k_entity:
687     {
688       entity *ent = (entity *)tore;
689       ir_node *value;
690       /* The node */
691       xfprintf (F, "node: {title: \"%p\" ", tore);
692       xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
693       xfprintf (F, "label: ");
694       xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
695       if(dynamic_allocated == get_entity_allocation(ent))
696         xfprintf (F, " info1:\"dynamic allocated\n");
697       else
698         xfprintf (F, " info1:\"static allocated\n");
699       switch (get_entity_visibility(ent)) {
700         case local:              fprintf (F, "local\n");             break;
701         case external_visible:   fprintf (F, "external_visible\n");  break;
702         case external_allocated: fprintf (F, "external_allocate\n");break;
703       }
704       switch (get_entity_variability(ent)) {
705         case uninitialized: fprintf (F, "uninitialized");break;
706         case initialized:   fprintf (F, "initialized");  break;
707         case part_constant: fprintf (F, "part_constant");break;
708         case constant:      fprintf (F, "constant");     break;
709       }
710       if (is_method_type(get_entity_type(ent)))
711         xfprintf (F, "\n irg = %p ", get_entity_irg(ent));
712       xfprintf(F, "\"}\n");
713       /* The Edges */
714       /* skip this to reduce graph.  Member edge of type is parallel to this edge. *
715       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
716                 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
717       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
718                 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
719       if(is_class_type(get_entity_owner(ent))) {
720         for(i = 0; i < get_entity_n_overwrites(ent); i++)
721           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
722                     ENT_OVERWRITES_EDGE_ATTR "}\n",
723                     ent, get_entity_overwrites(ent, i));
724       }
725       /* attached subgraphs */
726       if (const_entities && (get_entity_variability(ent) != uninitialized)) {
727         if (is_atomic_entity(ent)) {
728           value = get_atomic_ent_value(ent);
729           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
730           PRINT_NODEID(value);
731           fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
732           dump_const_expression(value);
733         }
734         if (is_compound_entity(ent)) {
735           for (i = 0; i < get_compound_ent_n_values(ent); i++) {
736             value = get_compound_ent_value(ent, i);
737             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
738             PRINT_NODEID(value);
739             fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
740             dump_const_expression(value);
741             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
742                       ENT_CORR_EDGE_ATTR  "}\n", ent,
743                       get_compound_ent_value_member(ent, i), i);
744           }
745         }
746       }
747     } break;
748   case k_type:
749     {
750       type *tp = (type *)tore;
751       print_type_node(tp);
752       /* and now the edges */
753       switch (get_type_tpop_code(tp)) {
754       case tpo_class:
755         {
756           for (i=0; i < get_class_n_supertype(tp); i++)
757             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
758                       TYPE_SUPER_EDGE_ATTR "}\n",
759                       tp, get_class_supertype(tp, i));
760           for (i=0; i < get_class_n_member(tp); i++)
761             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
762                       TYPE_MEMBER_EDGE_ATTR "}\n",
763                       tp, get_class_member(tp, i));
764         } break;
765       case tpo_struct:
766         {
767           for (i=0; i < get_struct_n_member(tp); i++)
768             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
769                       TYPE_MEMBER_EDGE_ATTR "}\n",
770                       tp, get_struct_member(tp, i));
771         } break;
772       case tpo_method:
773         {
774           for (i = 0; i < get_method_n_params(tp); i++)
775             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
776                       METH_PAR_EDGE_ATTR "}\n",
777                       tp, get_method_param_type(tp, i), i);
778           for (i = 0; i < get_method_n_res(tp); i++)
779             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
780                       METH_RES_EDGE_ATTR "}\n",
781                       tp, get_method_res_type(tp, i), i);
782         } break;
783       case tpo_union:
784         {
785           for (i = 0; i < get_union_n_members(tp); i++)
786             xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
787                       "label: \"\"f" UNION_EDGE_ATTR "}\n",
788                       tp, get_union_member(tp, i));
789         } break;
790       case tpo_array:
791         {
792           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
793                     ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
794           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
795                     ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
796         } break;
797       case tpo_enumeration:
798         {
799         } break;
800       case tpo_pointer:
801         {
802           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
803                     PTR_PTS_TO_EDGE_ATTR "}\n", tp,
804                     get_pointer_points_to_type(tp), i);
805         } break;
806       case tpo_primitive:
807         {
808         } break;
809       default: break;
810       } /* switch type */
811     }
812     break; /* case k_type */
813   default:
814     {
815       printf(" *** irdump,  %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
816     } break;
817   } /* switch kind_or_entity */
818 }
819
820 /************************************************************************/
821 /* open and close vcg file                                              */
822 /************************************************************************/
823
824 void vcg_open (ir_graph *irg, char *suffix) {
825   char *fname;  /* filename to put the vcg information in */
826   const char *cp;
827   ident *id;
828   int len;
829   char label[4];
830   entity *ent;
831
832   /** open file for vcg graph */
833   ent = get_irg_ent(irg);
834   id    = ent->ld_name ? ent->ld_name : ent->name;
835   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
836   len   = id_to_strlen (id);
837   cp    = id_to_str (id);
838   if (dump_file_suffix)
839     fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
840   else
841     fname = malloc (len + 5 + strlen(suffix));
842   strncpy (fname, cp, len);      /* copy the filename */
843   fname[len] = '\0';
844   if (dump_file_suffix) strcat (fname, dump_file_suffix);  /* append file suffix */
845   strcat (fname, suffix);  /* append file suffix */
846   strcat (fname, ".vcg");   /* append the .vcg suffix */
847   F = fopen (fname, "w");   /* open file for writing */
848   if (!F) {
849     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
850   }
851
852   if (edge_label) {
853     strcpy(label, "yes");
854   } else {
855     strcpy (label, "no");
856   }
857
858   /* print header */
859   xfprintf (F,
860             "graph: { title: \"ir graph of %s\"\n"
861             "display_edge_labels: %s\n"
862             "layoutalgorithm: mindepth\n"
863             "manhattan_edges: yes\n"
864             "port_sharing: no\n"
865             "orientation: bottom_to_top\n"
866             "classname 1: \"Data\"\n"
867             "classname 2: \"Block\"\n"
868             "classname 3: \"Entity type\""
869             "classname 4: \"Entity owner\""
870             "classname 5: \"Method Param\""
871             "classname 6: \"Method Res\""
872             "classname 7: \"Super\""
873             "classname 8: \"Union\""
874             "classname 9: \"Points-to\""
875             "classname 10: \"Array Element Type\""
876             "classname 11: \"Overwrites\""
877             "classname 12: \"Member\""
878             , cp, label);
879
880   xfprintf (F, "\n");           /* a separator */
881 }
882
883 void vcg_open_name (const char *name) {
884   char *fname;  /* filename to put the vcg information in */
885   int len;
886   char label[4];
887
888   /** open file for vcg graph */
889   len   = strlen(name);
890   fname = malloc (len + 5);
891   strcpy (fname, name);    /* copy the filename */
892   strcat (fname, ".vcg");  /* append the .vcg suffix */
893   F = fopen (fname, "w");  /* open file for writing */
894   if (!F) {
895     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
896   }
897
898   if (edge_label) {
899     strcpy(label, "yes");
900   } else {
901     strcpy (label, "no");
902   }
903
904   /* print header */
905   xfprintf (F,
906             "graph: { title: \"ir graph of %s\"\n"
907             "display_edge_labels: %s\n"
908             "layoutalgorithm: mindepth\n"
909             "manhattan_edges: yes\n"
910             "port_sharing: no\n"
911             "orientation: bottom_to_top\n"
912             "classname 1: \"Data\"\n"
913             "classname 2: \"Block\"\n"
914             "classname 3: \"Entity type\"\n"
915             "classname 4: \"Entity owner\"\n"
916             "classname 5: \"Method Param\"\n"
917             "classname 6: \"Method Res\"\n"
918             "classname 7: \"Super\"\n"
919             "classname 8: \"Union\"\n"
920             "classname 9: \"Points-to\"\n"
921             "classname 10: \"Array Element Type\"\n"
922             "classname 11: \"Overwrites\"\n"
923             "classname 12: \"Member\"\n"
924             , name, label);
925
926   xfprintf (F, "\n");           /* a separator */
927 }
928
929 void
930 vcg_close () {
931   xfprintf (F, "}\n");  /* print footer */
932   fclose (F);           /* close vcg file */
933 }
934
935 /************************************************************************/
936 /* routines to dump a graph, blocks as conventional nodes.              */
937 /************************************************************************/
938
939 int node_floats(ir_node *n) {
940
941   return ((get_op_pinned(get_irn_op(n)) == floats) &&
942           (get_irg_pinned(current_ir_graph) == floats));
943 }
944
945 void
946 dump_whole_node (ir_node *n, void* env) {
947   dump_node(n);
948   if (!node_floats(n)) dump_ir_block_edge(n);
949   dump_ir_data_edges(n);
950 }
951
952 void
953 dump_ir_graph (ir_graph *irg)
954 {
955   ir_graph *rem;
956   rem = current_ir_graph;
957   current_ir_graph = irg;
958
959   vcg_open (irg, "");
960
961   /* walk over the graph */
962   /* dump_whole_node must be called in post visiting predecessors */
963   irg_walk(irg->end, NULL, dump_whole_node, NULL);
964
965   /* dump the out edges in a separate walk */
966   if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
967     irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
968   }
969
970   vcg_close();
971
972   current_ir_graph = rem;
973 }
974
975 /***********************************************************************/
976 /* the following routines dump the nodes as attached to the blocks.    */
977 /***********************************************************************/
978
979 void
980 dump_ir_blocks_nodes (ir_node *n, void *env) {
981   ir_node *block = (ir_node *)env;
982
983   if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
984     dump_node(n);
985     dump_ir_data_edges(n);
986   }
987   if (get_irn_op(n) == op_Bad)
988     Bad_dumped = 1;
989 }
990
991 void
992 dump_ir_block (ir_node *block, void *env) {
993   ir_graph *irg = (ir_graph *)env;
994
995   if (get_irn_opcode(block) == iro_Block) {
996
997     /* This is a block. So dump the vcg information to make a block. */
998     xfprintf(F, "graph: { title: \"");
999         PRINT_NODEID(block);
1000         fprintf(F, "\"  label: \"");
1001 #ifdef DEBUG_libfirm
1002     xfprintf (F, "%ld", get_irn_node_nr(block));
1003 #else
1004     xfprintf (F, "%I", block->op->name);
1005 #endif
1006     if (exc_normal != get_Block_exc (block))
1007       fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1008
1009     xfprintf(F, "\" status:clustered color:%s \n",
1010              get_Block_matured (block) ? "yellow" : "red");
1011     /* dump the blocks edges */
1012     dump_ir_data_edges(block);
1013
1014     /* dump the nodes that go into the block */
1015     irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1016
1017     /* Close the vcg information for the block */
1018     xfprintf(F, "}\n\n");
1019   }
1020 }
1021
1022
1023 void
1024 dump_blockless_nodes (ir_node *n, void *env) {
1025   if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1026     dump_node(n);
1027     dump_ir_data_edges(n);
1028     dump_ir_block_edge(n);
1029     if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1030     return;
1031   }
1032   if (node_floats(n)) {
1033     dump_node(n);
1034     dump_ir_data_edges(n);
1035     if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1036   }
1037 }
1038
1039 void dump_ir_block_graph_2  (ir_graph *irg)
1040 {
1041   Bad_dumped = 0;
1042   /* walk over the blocks in the graph */
1043   irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1044
1045   /* dump all nodes that are not in a Block */
1046   irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1047
1048   /* dump the Bad node */
1049   if (!Bad_dumped)
1050     dump_node(get_irg_bad(irg));
1051 }
1052
1053 void
1054 dump_ir_block_graph (ir_graph *irg)
1055 {
1056   ir_graph *rem;
1057   rem = current_ir_graph;
1058   current_ir_graph = irg;
1059
1060   vcg_open (irg, "");
1061
1062   dump_ir_block_graph_2 (irg);
1063
1064   vcg_close();
1065   current_ir_graph = rem;
1066 }
1067
1068
1069 /***********************************************************************/
1070 /* the following routines dump a control flow graph                    */
1071 /***********************************************************************/
1072
1073
1074 void
1075 dump_block_to_cfg (ir_node *block, void *env) {
1076   int i;
1077   ir_node *pred;
1078
1079   if (get_irn_opcode(block) == iro_Block) {
1080     /* This is a block. Dump a node for the block. */
1081     xfprintf (F, "node: {title:\""); PRINT_NODEID(block);
1082     xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1083
1084         if (exc_normal != get_Block_exc (block))
1085           xfprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1086
1087     xfprintf (F, "\" ");
1088     if (dump_dominator_information_flag)
1089       xfprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1090     xfprintf (F, "}\n");
1091     /* Dump the edges */
1092     for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1093       if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1094         pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1095         xfprintf (F, "edge: { sourcename: \"");
1096         PRINT_NODEID(block);
1097         fprintf (F, "\" targetname: \"");
1098         PRINT_NODEID(pred);
1099         fprintf (F, "\" }\n");
1100       }
1101
1102     /* Dump dominator edge */
1103     if (dump_dominator_information_flag && get_Block_idom(block)) {
1104       pred = get_Block_idom(block);
1105       xfprintf (F, "edge: { sourcename: \"");
1106       PRINT_NODEID(block);
1107       fprintf (F, "\" targetname: \"");
1108       PRINT_NODEID(pred);
1109       fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1110     }
1111   }
1112 }
1113
1114 void
1115 dump_cfg (ir_graph *irg)
1116 {
1117   ir_graph *rem = current_ir_graph;
1118   int ddif = dump_dominator_information_flag;
1119   current_ir_graph = irg;
1120   vcg_open (irg, "-cfg");
1121
1122   if (get_irg_dom_state(irg) != dom_consistent)
1123     dump_dominator_information_flag = 0;
1124
1125   /* walk over the blocks in the graph */
1126   irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1127   dump_ir_node (irg->bad);
1128
1129   dump_dominator_information_flag = ddif;
1130   vcg_close();
1131   current_ir_graph = rem;
1132 }
1133
1134
1135 /***********************************************************************/
1136 /* the following routine dumps all type information reachable from an  */
1137 /* irg                                                                 */
1138 /***********************************************************************/
1139
1140
1141 void
1142 dump_type_graph (ir_graph *irg)
1143 {
1144   ir_graph *rem;
1145   rem = current_ir_graph;
1146   current_ir_graph = irg;
1147
1148   vcg_open (irg, "-type");
1149
1150   /* walk over the blocks in the graph */
1151   type_walk_irg(irg, dump_type_info, NULL, NULL);
1152   /* The walker for the const code can be called several times for the
1153      same (sub) experssion.  So that no nodes are dumped several times
1154      we decrease the visited flag of the corresponding graph after each
1155      walk.  So now increase it finally. */
1156   inc_irg_visited(get_const_code_irg());
1157
1158   vcg_close();
1159   current_ir_graph = rem;
1160 }
1161
1162 /***********************************************************************/
1163 /* the following routine dumps all type information                    */
1164 /***********************************************************************/
1165
1166
1167 void
1168 dump_all_types (void)
1169 {
1170   vcg_open_name ("All_types");
1171   type_walk(dump_type_info, NULL, NULL);
1172   inc_irg_visited(get_const_code_irg());
1173   vcg_close();
1174 }
1175
1176 /***********************************************************************/
1177 /* dumps a graph with type information                                 */
1178 /***********************************************************************/
1179
1180
1181 void
1182 dump_ir_graph_w_types (ir_graph *irg)
1183 {
1184   ir_graph *rem;
1185   rem = current_ir_graph;
1186   current_ir_graph = irg;
1187
1188   vcg_open (irg, "-all");
1189
1190   /* dump common ir graph */
1191   irg_walk(irg->end, dump_whole_node, NULL, NULL);
1192   /* dump type info */
1193   type_walk_irg(irg, dump_type_info, NULL, NULL);
1194   inc_irg_visited(get_const_code_irg());
1195   /* dump edges from graph to type info */
1196   irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1197
1198   vcg_close();
1199   current_ir_graph = rem;
1200 }
1201
1202 void
1203 dump_ir_block_graph_w_types (ir_graph *irg)
1204 {
1205   ir_graph *rem;
1206   rem = current_ir_graph;
1207   current_ir_graph = irg;
1208
1209   vcg_open (irg, "-all");
1210
1211   /* dump common blocked ir graph */
1212   dump_ir_block_graph_2(irg);
1213   /* dump type info */
1214   type_walk_irg(irg, dump_type_info, NULL, NULL);
1215   inc_irg_visited(get_const_code_irg());
1216   /* dump edges from graph to type info */
1217   irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1218
1219   vcg_close();
1220   current_ir_graph = rem;
1221 }
1222
1223 /***********************************************************************/
1224 /* dumps all graphs with the graph-dumper passed. Possible dumpers:    */
1225 /*  dump_ir_graph                                                      */
1226 /*  dump_ir_block_graph                                                */
1227 /*  dump_cfg                                                           */
1228 /*  dump_type_graph                                                    */
1229 /*  dump_ir_graph_w_types                                              */
1230 /***********************************************************************/
1231 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
1232   int i;
1233   for (i=0; i < get_irp_n_irgs(); i++) {
1234     dump_graph(get_irp_irg(i));
1235   }
1236 }
1237
1238
1239 /* To turn off display of edge labels.  Edge labels offen cause xvcg to
1240    abort with a segmentation fault. */
1241 void turn_off_edge_labels() {
1242   edge_label = 0;
1243 }
1244
1245 void turn_off_constant_entity_values() {
1246   const_entities = 0;
1247 }
1248
1249 void dump_keepalive_edges() {
1250   dump_keepalive = 1;
1251 }
1252
1253 void dump_out_edges() {
1254   dump_out_edge_flag = 1;
1255 }
1256
1257 void dump_dominator_information() {
1258   dump_dominator_information_flag = 1;
1259 }
1260
1261
1262 static void clear_link(ir_node * node, void * env) {
1263   set_irn_link(node, NULL);
1264 }
1265
1266
1267 static inline bool is_Block(ir_node * node) {
1268   return !is_no_Block(node);
1269 }
1270
1271
1272 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1273   if (is_Block(node)
1274       || node_floats(node)
1275       || get_irn_op(node) == op_Bad
1276       || get_irn_op(node) == op_Unknown) {
1277     pmap_entry * entry = pmap_find(map, current_ir_graph);
1278     if (entry) {
1279       ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1280     } else {
1281       ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1282       arr[0] = node;
1283       pmap_insert(map, current_ir_graph, arr);
1284     }
1285   } else {
1286     ir_node * block = get_nodes_Block(node);
1287     set_irn_link(node, get_irn_link(block));
1288     set_irn_link(block, node);
1289   }
1290 }
1291
1292
1293 static void dump_cg_ir_block(ir_node * node, void * env) {
1294   assert(is_Block(node));
1295   xfprintf(F, "graph: { title: \"");
1296   PRINT_NODEID(node);
1297   fprintf(F, "\"  label: \"");
1298 #ifdef DEBUG_libfirm
1299   xfprintf (F, "%ld", get_irn_node_nr(node));
1300 #else
1301   xfprintf (F, "%I", node->op->name);
1302 #endif
1303   if (exc_normal != get_Block_exc(node)) {
1304     fprintf (F, " (%s)", exc_to_string (get_Block_exc(node)));
1305   }
1306
1307   xfprintf(F, "\" status:clustered color:%s \n",
1308            get_Block_matured(node) ? "yellow" : "red");
1309
1310   /* dump the blocks edges */
1311   dump_ir_data_edges(node);
1312
1313   /* dump the nodes that go into the block */
1314   for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1315     dump_node(node);
1316     dump_ir_data_edges(node);
1317   }
1318
1319   /* Close the vcg information for the block */
1320   xfprintf(F, "}\n\n");
1321 }
1322
1323
1324 /* dump interprocedural graph with surrounding methods */
1325 void dump_cg_block_graph(ir_graph * irg) {
1326   pmap * map = pmap_create();
1327   pmap_entry * entry;
1328   vcg_open(irg, "");
1329
1330   irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
1331   for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1332     ir_node ** arr = entry->value;
1333     int i;
1334
1335     xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1336              get_entity_ident(get_irg_ent(entry->key)),
1337              get_entity_ident(get_irg_ent(entry->key)));
1338
1339     for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1340       ir_node * node = arr[i];
1341       if (is_Block(node)) {
1342         dump_cg_ir_block(node, NULL);
1343       } else {
1344         dump_node(node);
1345         dump_ir_data_edges(node);
1346       }
1347     }
1348
1349     DEL_ARR_F(arr);
1350
1351     /* Close the vcg information for the irg */
1352     xfprintf(F, "}\n\n");
1353   }
1354
1355   pmap_destroy(map);
1356
1357   vcg_close();
1358 }
1359
1360
1361 /* dump interprocedural block graph with surrounding methods */
1362 void dump_cg_graph(ir_graph * irg) {
1363   pmap * map = pmap_create();
1364   pmap_entry * entry;
1365   vcg_open(irg, "");
1366
1367   irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
1368   for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1369     ir_node ** arr = entry->value;
1370     int i;
1371     ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1372
1373     xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1374              irg_ident, irg_ident);
1375
1376     for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1377       ir_node * node = arr[i];
1378       dump_node(node);
1379       dump_ir_data_edges(node);
1380       if (is_Block(node)) {
1381         for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1382           dump_node(node);
1383           dump_ir_block_edge(node);
1384           dump_ir_data_edges(node);
1385         }
1386       }
1387     }
1388
1389     DEL_ARR_F(arr);
1390
1391     /* Close the vcg information for the irg */
1392     xfprintf(F, "}\n\n");
1393   }
1394
1395   pmap_destroy(map);
1396
1397   vcg_close();
1398 }