2a2690554cf5d25d52438eef3413e5d921ceddf4
[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_t.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     xfprintf (F, "\"%I ", n->op->name);
293     xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
294     /*  xdoesn't work for some reason.
295         fprintf (F, "\"%I %I\" ", n->op->name, get_entity_ident(get_Sel_entity(n))); */
296     xfprintf (F, DEFAULT_NODE_ATTR);
297     break;
298   case iro_SymConst:
299     assert(get_kind(get_SymConst_type(n)) == k_type_class);
300     assert(get_class_ident((type_class *)get_SymConst_type(n)));
301     xfprintf (F, "\"%s ",
302               id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
303     switch (n->attr.i.num){
304     case type_tag:
305       xfprintf (F, "tag\" ");
306       break;
307     case size:
308       xfprintf (F, "size\" ");
309       break;
310     default:
311       assert(0);
312       break;
313     }
314     xfprintf (F, DEFAULT_NODE_ATTR);
315     break;
316   case iro_Sync:
317     xfprintf (F, "\"%I\" ", n->op->name);
318     xfprintf (F, DEFAULT_NODE_ATTR " color: green");
319     break;
320   case iro_Bad:
321     xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
322     xfprintf (F, DEFAULT_NODE_ATTR);
323     break;
324   default:
325     xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
326   }
327   xfprintf (F, "}\n");          /* footer */
328 }
329
330
331 /* dump the edge to the block this node belongs to */
332 void
333 dump_ir_block_edge(ir_node *n)  {
334   if (is_no_Block(n))
335     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
336                 BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
337 }
338
339
340 /* dump edges to our inputs */
341 void
342 dump_ir_data_edges(ir_node *n)  {
343   int i;
344
345   for (i = 0; i < get_irn_arity(n); i++) {
346     assert(get_irn_n(n, i));
347     xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
348               n, get_irn_n(n, i));
349     fprintf (F, " label: \"%d\"", i+1);
350     fprintf (F, "}\n");
351   }
352 }
353
354 /* dumps the edges between nodes and their type or entity attributes. */
355 void dump_node2type_edges (ir_node *n, void *env)
356 {
357   assert(n);
358
359   switch (get_irn_opcode(n)) {
360   case iro_SymConst:
361     if (   (get_SymConst_kind(n) == type_tag)
362         || (get_SymConst_kind(n) == size))
363       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
364                 NODE2TYPE_EDGE_ATTR "}\n", n, get_SymConst_type(n));
365     break;
366   case iro_Sel:
367     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
368               NODE2TYPE_EDGE_ATTR "}\n", n, get_Sel_entity(n));
369     break;
370   case iro_Call:
371     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
372               NODE2TYPE_EDGE_ATTR "}\n", n, get_Call_type(n));
373     break;
374   case iro_Alloc:
375     xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
376               NODE2TYPE_EDGE_ATTR "}\n", n, get_Alloc_type(n));
377     break;
378   case iro_Free:
379     printf(" in irdum\n");
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     }
411     break;
412   case k_type_class:
413     {
414       type_class *type = (type_class *)tore;
415       xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
416       for (i=0; i < get_class_n_supertype(type); i++)
417         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
418                   " label: \"supertype\" " TYPE_EDGE_ATTR "}\n",
419                   type, get_class_supertype(type, i));
420     }
421     break;
422   case k_type_strct:
423     {
424       type_strct *type = (type_strct *)tore;
425       xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
426     }
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     }
441     break;
442   case k_type_union:
443     {
444       type_union *type = (type_union *)tore;
445       xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
446       /* edges !!!??? */
447     }
448     break;
449   case k_type_array:
450     {
451       type_array *type = (type_array *)tore;
452       xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
453       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
454                 TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
455     }
456     break;
457   case k_type_enumeration:
458     {
459       type_enumeration *type = (type_enumeration *)tore;
460       xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
461     }
462     break;
463   case k_type_pointer:
464     {
465       type_pointer *type = (type_pointer *)tore;
466       xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
467       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
468                 TYPE_EDGE_ATTR "}\n", tore,
469                 get_pointer_points_to_type(type), i);
470     }
471     break;
472   case k_type_primitive:
473     {
474       type_primitive *type = (type_primitive *)tore;
475       xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
476                 get_mode_ident(get_primitive_mode(type)));
477     }
478     break;
479   default:
480     break;
481   }
482
483 }
484
485 /************************************************************************/
486 /* open and close vcg file                                              */
487 /************************************************************************/
488
489 void vcg_open (ir_graph *irg, char *suffix) {
490   char *fname;  /* filename to put the vcg information in */
491   const char *cp;
492   ident *id;
493   int len;
494
495   /** open file for vcg graph */
496   id    = get_entity_ld_name (get_irg_ent(irg));
497   len   = id_to_strlen (id);
498   cp    = id_to_str (id);
499   fname = malloc (len + 5 + strlen(suffix));
500   strcpy (fname, cp);      /* copy the filename */
501   strcat (fname, suffix);  /* append file suffix */
502   strcat (fname, ".vcg");  /* append the .vcg suffix */
503   F = fopen (fname, "w");  /* open file for writing */
504   if (!F) {
505     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
506   }
507
508   /* print header */
509   xfprintf (F,
510             "graph: { title: \"ir graph of %s\"\n"
511             "display_edge_labels: yes\n"
512             "layoutalgorithm: mindepth\n"
513             "manhattan_edges: yes\n"
514             "port_sharing: no\n"
515             "orientation: bottom_to_top\n"
516             "classname 1: \"Data\"\n"
517             "classname 2: \"Block\"\n", cp);
518
519   xfprintf (F, "\n");           /* a separator */
520 }
521
522 void vcg_open_name (const char *name) {
523   char *fname;  /* filename to put the vcg information in */
524   int len;
525
526   /** open file for vcg graph */
527   len   = strlen(name);
528   fname = malloc (len + 5);
529   strcpy (fname, name);    /* copy the filename */
530   strcat (fname, ".vcg");  /* append the .vcg suffix */
531   F = fopen (fname, "w");  /* open file for writing */
532   if (!F) {
533     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
534   }
535
536   /* print header */
537   xfprintf (F,
538             "graph: { title: \"ir graph of %s\"\n"
539             "display_edge_labels: yes\n"
540             "layoutalgorithm: mindepth\n"
541             "manhattan_edges: yes\n"
542             "port_sharing: no\n"
543             "orientation: bottom_to_top\n"
544             "classname 1: \"Data\"\n"
545             "classname 2: \"Block\"\n", name);
546
547   xfprintf (F, "\n");           /* a separator */
548 }
549
550 void
551 vcg_close () {
552   xfprintf (F, "}\n");  /* print footer */
553   fclose (F);           /* close vcg file */
554 }
555
556 /************************************************************************/
557 /* routines to dump a graph, blocks as conventional nodes.              */
558 /************************************************************************/
559
560 void
561 dump_whole_node (ir_node *n, void* env) {
562   dump_node(n);
563   dump_ir_block_edge(n);
564   dump_ir_data_edges(n);
565 }
566
567 void
568 dump_ir_graph (ir_graph *irg)
569 {
570   ir_graph *rem;
571   rem = current_ir_graph;
572   current_ir_graph = irg;
573
574   vcg_open (irg, "");
575
576   /* walk over the graph */
577   irg_walk(irg->end, dump_whole_node, NULL, NULL);
578
579   vcg_close();
580
581   current_ir_graph = rem;
582 }
583
584 /***********************************************************************/
585 /* the following routines dump the nodes as attached to the blocks.    */
586 /***********************************************************************/
587
588 void
589 dump_ir_blocks_nodes (ir_node *n, void *env) {
590   ir_node *block = (ir_node *)env;
591
592   if (is_no_Block(n) && get_nodes_Block(n) == block) {
593     dump_node(n);
594     dump_ir_data_edges(n);
595   }
596 }
597
598 void
599 dump_ir_block (ir_node *block, void *env) {
600   ir_graph *irg = (ir_graph *)env;
601
602   if (get_irn_opcode(block) == iro_Block) {
603
604     /* This is a block. So dump the vcg information to make a block. */
605     xfprintf(F, "graph: { title: \"%p\"  label: \"", block);
606 #ifdef DEBUG_libfirm
607     xfprintf (F, "%ld", get_irn_node_nr(block));
608 #else
609     xfprintf (F, "%I", block->op->name);
610 #endif
611     xfprintf(F, "\" status:clustered color:lightyellow \n");
612     /* dump the blocks edges */
613     dump_ir_data_edges(block);
614
615     /* dump the nodes that go into the block */
616     irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
617
618     /* Close the vcg information for the block */
619     xfprintf(F, "}\n\n");
620   }
621 }
622
623 void
624 dump_ir_block_graph (ir_graph *irg)
625 {
626   ir_graph *rem;
627   rem = current_ir_graph;
628   current_ir_graph = irg;
629
630   vcg_open (irg, "");
631
632   /* walk over the blocks in the graph */
633   irg_block_walk(irg->end, dump_ir_block, NULL, irg);
634
635   vcg_close();
636   current_ir_graph = rem;
637 }
638
639
640 /***********************************************************************/
641 /* the following routines dump a control flow graph                    */
642 /***********************************************************************/
643
644
645 void
646 dump_block_to_cfg (ir_node *block, void *env) {
647   int i;
648   ir_node *pred;
649
650   if (get_irn_opcode(block) == iro_Block) {
651     /* This is a block. Dump a node for the block. */
652     xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
653               block->op->name);
654     /* Dump the edges */
655     for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
656       pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
657       xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" }\n",
658                 block, pred);
659     }
660   }
661 }
662
663 void
664 dump_cfg (ir_graph *irg)
665 {
666   vcg_open (irg, "-cfg");
667
668   /* walk over the blocks in the graph */
669   irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
670
671   vcg_close();
672 }
673
674
675 /***********************************************************************/
676 /* the following routine dumps all type information reachable from an  */
677 /* irg                                                                 */
678 /***********************************************************************/
679
680
681 void
682 dump_type_graph (ir_graph *irg)
683 {
684   ir_graph *rem;
685   rem = current_ir_graph;
686   current_ir_graph = irg;
687
688   vcg_open (irg, "-type");
689
690   /* walk over the blocks in the graph */
691   type_walk_irg(irg, dump_type_info, NULL, NULL);
692
693   vcg_close();
694   current_ir_graph = rem;
695 }
696
697 /***********************************************************************/
698 /* the following routine dumps all type information                    */
699 /***********************************************************************/
700
701
702 void
703 dump_all_types (void)
704 {
705   vcg_open_name ("All_types");
706   type_walk(dump_type_info, NULL, NULL);
707   vcg_close();
708 }
709
710 /***********************************************************************/
711 /* dumps a graph with type information                                 */
712 /***********************************************************************/
713
714
715 void
716 dump_ir_graph_w_types (ir_graph *irg)
717 {
718   ir_graph *rem;
719   rem = current_ir_graph;
720   current_ir_graph = irg;
721
722   vcg_open (irg, "-all");
723
724   /* dump common ir graph */
725   /*  irg_block_walk(irg->end, dump_ir_block, NULL, irg); */
726   irg_walk(irg->end, dump_whole_node, NULL, NULL);
727   /* dump type info */
728   type_walk_irg(irg, dump_type_info, NULL, NULL);
729   /* dump edges from graph to type info */
730   irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
731
732   vcg_close();
733   current_ir_graph = rem;
734 }