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