*** empty log message ***
[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 # include "irnode_t.h"
10 # include "irgraph_t.h"
11 # include "irprog.h"
12 # include "irdump.h"
13 # include "panic.h"
14 # include <string.h>
15 # include "entity.h"
16 # include <stdlib.h>
17 # include "array.h"
18 # include "irop_t.h"
19 # include "tv.h"
20 # include "type_or_entity.h"
21 # include "irgwalk.h"
22 # include "typewalk.h"
23
24 #define DEFAULT_NODE_ATTR ""
25 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
26 #define NODE2TYPE_EDGE_ATTR ""
27 #define DEFAULT_TYPE_ATTRIBUTE ""
28 #define TYPE_EDGE_ATTR ""
29
30 #define PRINT_NODEID(X) fprintf(F, "%p", X)
31
32 /* file to dump to */
33 static FILE *F;
34
35
36 /*******************************************************************/
37 /* routines to dump information about a single node                */
38 /*******************************************************************/
39
40
41
42 inline void
43 dump_node_opcode (ir_node *n)
44 {
45   /* Const */
46   if (n->op->code == iro_Const) {
47     xfprintf (F, "%v", n->attr.con);
48   /* SymConst */
49   } else if (n->op->code == iro_SymConst) {
50     if (get_SymConst_kind(n) == linkage_ptr_info) {
51       xfprintf (F, "%I", get_SymConst_ptrinfo(n));
52     } else {
53       assert(get_kind(get_SymConst_type(n)) == k_type_class);
54       assert(get_class_ident((type_class *)get_SymConst_type(n)));
55       xfprintf (F, "%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
56       if (get_SymConst_kind == type_tag)
57         xfprintf (F, "tag");
58       else
59         xfprintf (F, "size");
60     }
61   /* all others */
62   } else {
63     xfprintf (F, "%I", n->op->name);
64   }
65 }
66
67 inline void
68 dump_node_mode (ir_node *n)
69 {
70   switch (n->op->code) {
71   case iro_Phi:
72   case iro_Const:
73   case iro_Id:
74   case iro_Proj:
75   case iro_Conv:
76   case iro_Tuple:
77   case iro_Add:
78   case iro_Sub:
79   case iro_Mul:
80   case iro_And:
81   case iro_Or:
82   case iro_Eor:
83   case iro_Shl:
84   case iro_Shr:
85   case iro_Abs:
86   case iro_Cmp:
87     xfprintf (F, "%I", n->mode->name);
88     break;
89   default:
90   }
91 }
92
93 inline void
94 dump_node_nodeattr (ir_node *n)
95 {
96   switch (n->op->code) {
97   case iro_Proj:
98     if (n->in[1]->op->code == iro_Cmp) {
99       xfprintf (F, "%s", get_pnc_string(n->attr.proj));
100     } else {
101       xfprintf (F, "%ld", n->attr.proj);
102     }
103     break;
104   case iro_Sel:
105     /*assert(n->attr.s.ent->kind == k_entity);*/
106     assert(get_kind(get_Sel_entity(n)) == k_entity);
107     xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
108
109     /*  xdoesn't work for some reason.
110         fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
111     break;
112   default:
113   } /* end switch */
114 }
115
116 inline void
117 dump_node_vcgattr (ir_node *n)
118 {
119   switch (n->op->code) {
120   case iro_Start:
121   case iro_End:
122     xfprintf (F, "color: blue");
123     break;
124   case iro_Block:
125     xfprintf (F, "color: lightyellow");
126     break;
127   case iro_Phi:
128     xfprintf (F, "color: green");
129     break;
130   case iro_Const:
131   case iro_Proj:
132   case iro_Tuple:
133     xfprintf (F, "color: yellow");
134     break;
135   default:
136     xfprintf (F, DEFAULT_NODE_ATTR);
137   }
138 }
139
140 void
141 dump_node (ir_node *n) {
142
143   /* dump this node */
144   xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
145
146   dump_node_opcode(n);
147   dump_node_mode (n);
148   xfprintf (F, " ");
149   dump_node_nodeattr(n);
150 #ifdef DEBUG_libfirm
151   xfprintf (F, " %ld", get_irn_node_nr(n));
152 #endif
153   xfprintf (F, "\" ");
154   dump_node_vcgattr(n);
155   xfprintf (F, "}\n");
156 }
157
158 void
159 dump_ir_node (ir_node *n)
160 {
161   /* dump this node */
162   fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
163
164   switch (n->op->code) {  /* node label */
165   case iro_Start:
166     xfprintf (F, "\"%I\" color: blue ", n->op->name);
167     xfprintf (F, DEFAULT_NODE_ATTR);
168      break;
169   case iro_End:
170     xfprintf (F, "\"%I\" color: blue ", n->op->name);
171     xfprintf (F, DEFAULT_NODE_ATTR);
172     break;
173   case iro_Block:
174     xfprintf (F, "\"%I\" color: lightyellow ", n->op->name);
175     xfprintf (F, DEFAULT_NODE_ATTR);
176     break;
177   case iro_Phi:
178     xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name);
179     if (n->mode->code == irm_M)
180       xfprintf (F, DEFAULT_NODE_ATTR " color: green");
181     else
182       xfprintf (F, DEFAULT_NODE_ATTR);
183     break;
184   case iro_Const:
185     xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name);
186     xfprintf (F, DEFAULT_NODE_ATTR);
187     break;
188   case iro_Id:
189     xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
190     xfprintf (F, DEFAULT_NODE_ATTR);
191     break;
192   case iro_Proj:
193     if (n->in[1]->op->code == iro_Cmp) {
194       xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name,
195                 get_pnc_string(n->attr.proj));
196     } else {
197       xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj);
198     }
199     xfprintf (F, DEFAULT_NODE_ATTR);
200     break;
201   case iro_Conv:
202     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
203     xfprintf (F, DEFAULT_NODE_ATTR);
204     break;
205   case iro_Tuple:
206     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
207     xfprintf (F, DEFAULT_NODE_ATTR);
208     break;
209   case iro_Add:
210     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
211     xfprintf (F, DEFAULT_NODE_ATTR);
212     break;
213   case iro_Sub:
214     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
215     xfprintf (F, DEFAULT_NODE_ATTR);
216     break;
217   case iro_Mul:
218     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
219     xfprintf (F, DEFAULT_NODE_ATTR);
220     break;
221   case iro_Quot:
222     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
223     xfprintf (F, DEFAULT_NODE_ATTR);
224     break;
225   case iro_DivMod:
226     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
227     xfprintf (F, DEFAULT_NODE_ATTR);
228     break;
229   case iro_Div:
230     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
231     xfprintf (F, DEFAULT_NODE_ATTR);
232     break;
233   case iro_Mod:
234     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
235     xfprintf (F, DEFAULT_NODE_ATTR);
236     break;
237   case iro_And:
238     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
239     xfprintf (F, DEFAULT_NODE_ATTR);
240     break;
241   case iro_Or:
242     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
243     xfprintf (F, DEFAULT_NODE_ATTR);
244     break;
245   case iro_Eor:
246     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
247     xfprintf (F, DEFAULT_NODE_ATTR);
248     break;
249   case iro_Shl:
250     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
251     xfprintf (F, DEFAULT_NODE_ATTR);
252     break;
253   case iro_Shr:
254     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
255     xfprintf (F, DEFAULT_NODE_ATTR);
256     break;
257   case iro_Abs:
258     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
259     xfprintf (F, DEFAULT_NODE_ATTR);
260     break;
261   case iro_Cmp:
262     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
263     xfprintf (F, DEFAULT_NODE_ATTR);
264     break;
265   case iro_Jmp:
266     xfprintf (F, "\"%I\"", n->op->name);
267     xfprintf (F, DEFAULT_NODE_ATTR);
268     break;
269   case iro_Cond:
270     xfprintf (F, "\"%I\"", n->op->name);
271     xfprintf (F, DEFAULT_NODE_ATTR);
272     break;
273   case iro_Call:
274     xfprintf (F, "\"%I\"", n->op->name);
275     xfprintf (F, DEFAULT_NODE_ATTR);
276     break;
277   case iro_Return:
278     xfprintf (F, "\"%I\"", n->op->name);
279     xfprintf (F, DEFAULT_NODE_ATTR);
280     break;
281   case iro_Raise:
282     xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
283     xfprintf (F, DEFAULT_NODE_ATTR);
284     break;
285   case iro_Load:
286   case iro_Store:
287     xfprintf (F, "\"%R\"", n);
288     xfprintf (F, DEFAULT_NODE_ATTR);
289     break;
290   case iro_Alloc:
291     xfprintf (F, "\"%I\" ", n->op->name);
292     xfprintf (F, DEFAULT_NODE_ATTR);
293     break;
294   case iro_Sel:
295     assert(get_kind(get_Sel_entity(n)) == k_entity);
296     xfprintf (F, "\"%I ", n->op->name);
297     xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
298     /*  xdoesn't work for some reason.
299         fprintf (F, "\"%I %I\" ", n->op->name, get_entity_ident(get_Sel_entity(n))); */
300     xfprintf (F, DEFAULT_NODE_ATTR);
301     break;
302   case iro_SymConst:
303     assert(get_kind(get_SymConst_type(n)) == k_type_class);
304     assert(get_class_ident((type_class *)get_SymConst_type(n)));
305     xfprintf (F, "\"%s ",
306               id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
307     switch (n->attr.i.num){
308     case type_tag:
309       xfprintf (F, "tag\" ");
310       break;
311     case size:
312       xfprintf (F, "size\" ");
313       break;
314     default:
315       assert(0);
316       break;
317     }
318     xfprintf (F, DEFAULT_NODE_ATTR);
319     break;
320   case iro_Sync:
321     xfprintf (F, "\"%I\" ", n->op->name);
322     xfprintf (F, DEFAULT_NODE_ATTR " color: green");
323     break;
324   case iro_Bad:
325     xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
326     xfprintf (F, DEFAULT_NODE_ATTR);
327     break;
328   default:
329     xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
330   }
331   xfprintf (F, "}\n");          /* footer */
332 }
333
334
335 /* dump the edge to the block this node belongs to */
336 void
337 dump_ir_block_edge(ir_node *n)  {
338   if (is_no_Block(n))
339     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
340                 BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
341 }
342
343
344 /* dump edges to our inputs */
345 void
346 dump_ir_data_edges(ir_node *n)  {
347   int i;
348
349   for (i = 0; i < get_irn_arity(n); i++) {
350     assert(get_irn_n(n, i));
351     xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
352               n, get_irn_n(n, i));
353     fprintf (F, " label: \"%d\"", i+1);
354     fprintf (F, "}\n");
355   }
356 }
357
358 /* dumps the edges between nodes and their type or entity attributes. */
359 void dump_node2type_edges (ir_node *n, void *env)
360 {
361   assert(n);
362
363   switch (get_irn_opcode(n)) {
364   case iro_SymConst:
365     if (   (get_SymConst_kind(n) == type_tag)
366         || (get_SymConst_kind(n) == size))
367       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
368                 NODE2TYPE_EDGE_ATTR "}\n", n, get_SymConst_type(n));
369     break;
370   case iro_Sel:
371     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
372               NODE2TYPE_EDGE_ATTR "}\n", n, get_Sel_entity(n));
373     break;
374   case iro_Call:
375     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
376               NODE2TYPE_EDGE_ATTR "}\n", n, get_Call_type(n));
377     break;
378   case iro_Alloc:
379     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
380               NODE2TYPE_EDGE_ATTR "}\n", n, get_Alloc_type(n));
381     break;
382   case iro_Free:
383     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
384               NODE2TYPE_EDGE_ATTR "}\n", n, get_Free_type(n));
385     break;
386   default:
387     break;
388   }
389 }
390
391
392 /* dumps a type or entity and it's edges. */
393 void
394 dump_type_info (type_or_ent *tore, void *env) {
395   int i = 0;  /* to shutup gcc */
396
397   /* dump this type or entity */
398   xfprintf (F, "node: {title: \"%p\" ", tore);
399   xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
400   xfprintf (F, "label: ");
401
402   switch (get_kind(tore)) {
403   case k_entity:
404     {
405       entity *ent = (entity *)tore;
406       xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
407       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
408                 " label: \"owner\" "
409                 TYPE_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
410       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
411                 " label: \"type\" "
412                 TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
413     } break;
414   case k_type_class:
415     {
416       type_class *type = (type_class *)tore;
417       xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
418       for (i=0; i < get_class_n_supertype(type); i++)
419         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
420                   " label: \"supertype\" " TYPE_EDGE_ATTR "}\n",
421                   type, get_class_supertype(type, i));
422     } break;
423   case k_type_strct:
424     {
425       type_strct *type = (type_strct *)tore;
426       xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
427     } break;
428   case k_type_method:
429     {
430       type_method *type = (type_method *)tore;
431       xfprintf (F, "\"meth %I\"}\n", get_method_ident(type));
432       for (i = 0; i < get_method_arity(type); i++)
433         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
434                   " label: \"param %d\" " TYPE_EDGE_ATTR "}\n",
435                   tore, get_method_param_type(type, i), i);
436       for (i = 0; i < get_method_n_res(type); i++)
437         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
438                   " label: \"res %d\" " TYPE_EDGE_ATTR "}\n",
439                   tore, get_method_res_type(type, i), i);
440     } break;
441   case k_type_union:
442     {
443       type_union *type = (type_union *)tore;
444       xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
445       /* edges !!!??? */
446     } break;
447   case k_type_array:
448     {
449       type_array *type = (type_array *)tore;
450       xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
451       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
452                 TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
453     } break;
454   case k_type_enumeration:
455     {
456       type_enumeration *type = (type_enumeration *)tore;
457       xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
458     } break;
459   case k_type_pointer:
460     {
461       type_pointer *type = (type_pointer *)tore;
462       xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
463       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
464                 TYPE_EDGE_ATTR "}\n", tore,
465                 get_pointer_points_to_type(type), i);
466     } break;
467   case k_type_primitive:
468     {
469       type_primitive *type = (type_primitive *)tore;
470       xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
471                 get_mode_ident(get_primitive_mode(type)));
472     } break;
473   default:
474     {
475       xfprintf (F, "\" faulty type \"}\n");
476       printf(" *** irdump,  %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
477     } break;
478   }
479 }
480
481 /************************************************************************/
482 /* open and close vcg file                                              */
483 /************************************************************************/
484
485 void vcg_open (ir_graph *irg, char *suffix) {
486   char *fname;  /* filename to put the vcg information in */
487   const char *cp;
488   ident *id;
489   int len;
490
491   /** open file for vcg graph */
492   id    = get_entity_ld_name (get_irg_ent(irg));
493   len   = id_to_strlen (id);
494   cp    = id_to_str (id);
495
496   fname = malloc (len + 5 + strlen(suffix));
497   strncpy (fname, cp, len);      /* copy the filename */
498   fname[len] = '\0';
499   strcat (fname, suffix);  /* append file suffix */
500
501   fname = malloc (len + 5 + strlen(suffix));
502   strncpy (fname, cp, len); /* copy the filename */
503   fname[len] = '\0';        /* ensure string termination */
504   /*strcpy (fname, cp);      * copy the filename *
505     this produces wrong, too long strings in conjuction with the
506     jocca frontend.  The \0 seems to be missing. */
507   strcat (fname, suffix);   /* append file suffix */
508   strcat (fname, ".vcg");   /* append the .vcg suffix */
509   F = fopen (fname, "w");   /* open file for writing */
510   if (!F) {
511     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
512   }
513
514   /* print header */
515   xfprintf (F,
516             "graph: { title: \"ir graph of %s\"\n"
517             "display_edge_labels: yes\n"
518             "layoutalgorithm: mindepth\n"
519             "manhattan_edges: yes\n"
520             "port_sharing: no\n"
521             "orientation: bottom_to_top\n"
522             "classname 1: \"Data\"\n"
523             "classname 2: \"Block\"\n", cp);
524
525   xfprintf (F, "\n");           /* a separator */
526 }
527
528 void vcg_open_name (const char *name) {
529   char *fname;  /* filename to put the vcg information in */
530   int len;
531
532   /** open file for vcg graph */
533   len   = strlen(name);
534   fname = malloc (len + 5);
535   strcpy (fname, name);    /* copy the filename */
536   strcat (fname, ".vcg");  /* append the .vcg suffix */
537   F = fopen (fname, "w");  /* open file for writing */
538   if (!F) {
539     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
540   }
541
542   /* print header */
543   xfprintf (F,
544             "graph: { title: \"ir graph of %s\"\n"
545             "display_edge_labels: yes\n"
546             "layoutalgorithm: mindepth\n"
547             "manhattan_edges: yes\n"
548             "port_sharing: no\n"
549             "orientation: bottom_to_top\n"
550             "classname 1: \"Data\"\n"
551             "classname 2: \"Block\"\n", name);
552
553   xfprintf (F, "\n");           /* a separator */
554 }
555
556 void
557 vcg_close () {
558   xfprintf (F, "}\n");  /* print footer */
559   fclose (F);           /* close vcg file */
560 }
561
562 /************************************************************************/
563 /* routines to dump a graph, blocks as conventional nodes.              */
564 /************************************************************************/
565
566 void
567 dump_whole_node (ir_node *n, void* env) {
568   dump_node(n);
569   dump_ir_block_edge(n);
570   dump_ir_data_edges(n);
571 }
572
573 void
574 dump_ir_graph (ir_graph *irg)
575 {
576   ir_graph *rem;
577   rem = current_ir_graph;
578   current_ir_graph = irg;
579
580   vcg_open (irg, "");
581
582   /* walk over the graph */
583   irg_walk(irg->end, dump_whole_node, NULL, NULL);
584
585   vcg_close();
586
587   current_ir_graph = rem;
588 }
589
590 /***********************************************************************/
591 /* the following routines dump the nodes as attached to the blocks.    */
592 /***********************************************************************/
593
594 void
595 dump_ir_blocks_nodes (ir_node *n, void *env) {
596   ir_node *block = (ir_node *)env;
597
598   if (is_no_Block(n) && get_nodes_Block(n) == block) {
599     dump_node(n);
600     dump_ir_data_edges(n);
601   }
602 }
603
604 void
605 dump_ir_block (ir_node *block, void *env) {
606   ir_graph *irg = (ir_graph *)env;
607
608   if (get_irn_opcode(block) == iro_Block) {
609
610     /* This is a block. So dump the vcg information to make a block. */
611     xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\"  label: \"");
612 #ifdef DEBUG_libfirm
613     xfprintf (F, "%ld", get_irn_node_nr(block));
614 #else
615     xfprintf (F, "%I", block->op->name);
616 #endif
617     xfprintf(F, "\" status:clustered color:lightyellow \n");
618     /* dump the blocks edges */
619     dump_ir_data_edges(block);
620
621     /* dump the nodes that go into the block */
622     irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
623
624     /* Close the vcg information for the block */
625     xfprintf(F, "}\n\n");
626   }
627 }
628
629 void
630 dump_ir_block_graph (ir_graph *irg)
631 {
632   ir_graph *rem;
633   rem = current_ir_graph;
634   current_ir_graph = irg;
635
636   vcg_open (irg, "");
637
638   /* walk over the blocks in the graph */
639   irg_block_walk(irg->end, dump_ir_block, NULL, irg);
640
641   vcg_close();
642   current_ir_graph = rem;
643 }
644
645
646 /***********************************************************************/
647 /* the following routines dump a control flow graph                    */
648 /***********************************************************************/
649
650
651 void
652 dump_block_to_cfg (ir_node *block, void *env) {
653   int i;
654   ir_node *pred;
655
656   if (get_irn_opcode(block) == iro_Block) {
657     /* This is a block. Dump a node for the block. */
658     xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
659               block->op->name);
660     /* Dump the edges */
661     for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
662       pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
663       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" }\n",
664                 block, pred);
665     }
666   }
667 }
668
669 void
670 dump_cfg (ir_graph *irg)
671 {
672   vcg_open (irg, "-cfg");
673
674   /* walk over the blocks in the graph */
675   irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
676
677   vcg_close();
678 }
679
680
681 /***********************************************************************/
682 /* the following routine dumps all type information reachable from an  */
683 /* irg                                                                 */
684 /***********************************************************************/
685
686
687 void
688 dump_type_graph (ir_graph *irg)
689 {
690   ir_graph *rem;
691   rem = current_ir_graph;
692   current_ir_graph = irg;
693
694   vcg_open (irg, "-type");
695
696   /* walk over the blocks in the graph */
697   type_walk_irg(irg, dump_type_info, NULL, NULL);
698
699   vcg_close();
700   current_ir_graph = rem;
701 }
702
703 /***********************************************************************/
704 /* the following routine dumps all type information                    */
705 /***********************************************************************/
706
707
708 void
709 dump_all_types (void)
710 {
711   vcg_open_name ("All_types");
712   type_walk(dump_type_info, NULL, NULL);
713   vcg_close();
714 }
715
716 /***********************************************************************/
717 /* dumps a graph with type information                                 */
718 /***********************************************************************/
719
720
721 void
722 dump_ir_graph_w_types (ir_graph *irg)
723 {
724   ir_graph *rem;
725   rem = current_ir_graph;
726   current_ir_graph = irg;
727
728   vcg_open (irg, "-all");
729
730   /* dump common ir graph */
731   /*  irg_block_walk(irg->end, dump_ir_block, NULL, irg); */
732   irg_walk(irg->end, dump_whole_node, NULL, NULL);
733   /* dump type info */
734   type_walk_irg(irg, dump_type_info, NULL, NULL);
735   /* dump edges from graph to type info */
736   irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
737
738   vcg_close();
739   current_ir_graph = rem;
740 }
741
742 /***********************************************************************/
743 /* dumps all graphs with the graph-dumper passed. Possible dumpers:    */
744 /*  dump_ir_graph                                                      */
745 /*  dump_ir_block_graph                                                */
746 /*  dump_cfg                                                           */
747 /*  dump_type_graph                                                    */
748 /*  dump_ir_graph_w_types                                              */
749 /***********************************************************************/
750 void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
751   int i;
752   for (i=0; i < get_irp_n_irgs(); i++) {
753     dump_graph(get_irp_irg(i));
754   }
755 }