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