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