Added FuncCall op
[libfirm] / ir / ir / irdump.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irdump.c
4  * Purpose:     Write vcg representation of firm to file.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier, Hubert Schmidt
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
17
18 # include <string.h>
19 # include <stdlib.h>
20 # include <stdarg.h>
21
22 # include "irnode_t.h"
23 # include "irgraph_t.h"
24 # include "entity_t.h"
25 # include "irop_t.h"
26 # include "firm_common_t.h"
27
28 # include "irdump.h"
29
30 # include "irgwalk.h"
31 # include "typewalk.h"
32 # include "irprog.h"
33 # include "tv_t.h"
34 # include "type_or_entity.h"
35 # include "irouts.h"
36 # include "irdom.h"
37 # include "irloop.h"
38
39 # include "panic.h"
40 # include "array.h"
41 # include "pmap.h"
42 # include "eset.h"
43
44 #undef HEAPANAL
45 #ifdef HEAPANAL
46 void dump_chi_term(FILE *FL, ir_node *n);
47 void dump_state(FILE *FL, ir_node *n);
48 int  get_opt_dump_abstvals(void);
49 typedef unsigned long SeqNo;
50 SeqNo get_Block_seqno(ir_node *n);
51 #endif
52
53 /* Attributes of nodes */
54 #define PRINT_DEFAULT_NODE_ATTR
55 #define DEFAULT_NODE_ATTR " "
56 #define DEFAULT_TYPE_ATTRIBUTE " "
57
58 /* Attributes of edges between Firm nodes */
59 #define BLOCK_EDGE_ATTR     "class: 2 priority: 2 linestyle: dotted"
60 #define CF_EDGE_ATTR        "color: red"
61 #define MEM_EDGE_ATTR       "color: blue"
62 #define DOMINATOR_EDGE_ATTR "color: red"
63
64 #define BACK_EDGE_ATTR "linestyle: dashed "
65
66 /* Attributes of edges between Firm nodes and type/entity nodes */
67 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
68
69 /* Attributes of edges in type/entity graphs. */
70 #define TYPE_METH_NODE_ATTR  "color: lightyellow"
71 #define TYPE_CLASS_NODE_ATTR "color: green"
72 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
73 #define ENTITY_NODE_ATTR     "color: yellow"
74 #define ENT_TYPE_EDGE_ATTR   "class: 3 label: \"type\" color: red"
75 #define ENT_OWN_EDGE_ATTR    "class: 4 label: \"owner\" color: black"
76 #define METH_PAR_EDGE_ATTR   "class: 5 label: \"param %d\" color: green"
77 #define METH_RES_EDGE_ATTR   "class: 6 label: \"res %d\" color: green"
78 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
79 #define UNION_EDGE_ATTR      "class: 8 label: \"component\" color: blue"
80 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
81 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
82 #define ARR_ENT_EDGE_ATTR    "class: 10 label: \"arr ent\" color: green"
83 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
84 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
85 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
86 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
87
88
89 #if DEBUG_libfirm && NODEID_AS_LABEL
90 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
91 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
92 #define PRINT_ENTID(X)  fprintf(F, "e%ld", get_entity_nr(X))
93 #define PRINT_IRGID(X)  fprintf(F, "g%ld", get_irg_graph_nr(X))
94 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
95 #define PRINT_LOOPID(X) fprintf(F, "l%d", get_loop_loop_nr(X))
96
97 #else
98 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
99 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
100 #define PRINT_ENTID(X)  fprintf(F, "e%p", (void*) X)
101 #define PRINT_IRGID(X)  fprintf(F, "g%p",(void*) X)
102 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
103 #define PRINT_LOOPID(X) fprintf(F, "l%p", (void *)X)
104 #endif
105
106 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
107 {
108   va_list ap;
109
110   va_start(ap, fmt);
111   fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
112   fprintf(F, " targetname: "); PRINT_TYPEID(T);
113   vfprintf(F, fmt, ap);
114   fprintf(F,"}\n");
115   va_end(ap);
116 }
117
118 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
119 {
120   va_list ap;
121
122   va_start(ap, fmt);
123   fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
124   fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
125   vfprintf(F, fmt, ap);
126   fprintf(F, "}\n");
127   va_end(ap);
128 }
129
130 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, const char *fmt, ...)
131 {
132   va_list ap;
133
134   va_start(ap, fmt);
135   fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
136   fprintf(F, "\" targetname: \""); PRINT_ENTID(T);  fprintf(F, "\"");
137   vfprintf(F, fmt, ap);
138   fprintf(F, "}\n");
139   va_end(ap);
140 }
141
142 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
143 {
144   va_list ap;
145
146   va_start(ap, fmt);
147   fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
148   fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
149   vfprintf(F, fmt, ap);
150   fprintf(F,"}\n");
151   va_end(ap);
152 }
153
154 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
155 {
156   va_list ap;
157
158   va_start(ap, fmt);
159   fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
160   fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
161   vfprintf(F, fmt, ap);
162   fprintf(F,"}\n");
163   va_end(ap);
164 }
165
166 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
167 {
168   va_list ap;
169
170   va_start(ap, fmt);
171   fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
172   fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
173   fprintf(F, "\"");
174   vfprintf(F, fmt, ap);
175   fprintf(F,"}\n");
176   va_end(ap);
177 }
178
179 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
180 {
181   va_list ap;
182
183   va_start(ap, fmt);
184   fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
185   fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
186   vfprintf(F, fmt, ap);
187   fprintf(F,"}\n");
188   va_end(ap);
189 }
190
191 /*******************************************************************/
192 /* global and ahead declarations                                   */
193 /*******************************************************************/
194
195 /* A suffix to manipulate the file name. */
196 char *dump_file_suffix = "";
197
198 /* file to dump to */
199 static FILE *F;
200
201 static void dump_whole_node(ir_node *n, void* env);
202 static INLINE void dump_loop_nodes_into_graph(ir_graph *irg);
203
204 /*******************************************************************/
205 /* Helper functions.                                                */
206 /*******************************************************************/
207
208 /* Use private link attr to be able to call dumper anywhere without
209    destroying link fields. */
210
211 static pmap *irdump_link_map = NULL;
212
213 static void init_irdump(void) {
214   /* We need a new, empty map. */
215   if (irdump_link_map) pmap_destroy(irdump_link_map);
216   irdump_link_map = pmap_create();
217 }
218
219
220 void *ird_get_irn_link(ir_node *n) {
221   void *res = NULL;
222   if (!irdump_link_map) return NULL;
223
224   if (pmap_contains(irdump_link_map, (void *)n))
225     res = pmap_get(irdump_link_map, (void *)n);
226   return res;
227 }
228
229 void ird_set_irn_link(ir_node *n, void *x) {
230   if (!irdump_link_map) init_irdump();
231   pmap_insert(irdump_link_map, (void *)n, x);
232 }
233
234 void *ird_get_irg_link(ir_graph *irg) {
235   void *res = NULL;
236   if (!irdump_link_map) return NULL;
237
238   if (pmap_contains(irdump_link_map, (void *)irg))
239     res = pmap_get(irdump_link_map, (void *)irg);
240   return res;
241 }
242
243 void ird_set_irg_link(ir_graph *irg, void *x) {
244   if (!irdump_link_map) init_irdump();
245   pmap_insert(irdump_link_map, (void *)irg, x);
246 }
247
248 static void clear_link(ir_node * node, void * env) {
249   ird_set_irn_link(node, NULL);
250 }
251
252
253 static int node_floats(ir_node *n) {
254   return ((get_op_pinned(get_irn_op(n)) == floats) &&
255           (get_irg_pinned(current_ir_graph) == floats));
256 }
257
258 static const char *get_ent_dump_name (entity *ent) {
259   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
260   if (ent->ld_name) return get_id_str(ent->ld_name);
261   return get_id_str(ent->name);
262 }
263
264 static const char *get_irg_dump_name (ir_graph *irg) {
265   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
266   entity *ent = get_irg_ent(irg);
267   return get_ent_dump_name(ent);
268 }
269
270 static void collect_node(ir_node * node, void *env) {
271   if (is_Block(node)
272       || node_floats(node)
273       || get_irn_op(node) == op_Bad
274       || get_irn_op(node) == op_Unknown) {
275     ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
276     if (!arr) arr = NEW_ARR_F(ir_node *, 0);
277     ARR_APP1(ir_node *, arr, node);
278     ird_set_irg_link(get_irn_irg(node), arr);    /* arr is an l-value, APP_ARR might change it! */
279   } else {
280     ir_node * block = get_nodes_block(node);
281     ird_set_irn_link(node, ird_get_irn_link(block));
282     ird_set_irn_link(block, node);
283   }
284 }
285
286 /** Construct lists to walk ir block-wise.
287  *
288  * Collects all blocks, nodes not pinned,
289  * Bad and Unknown into a flexible array in link field of
290  * irg they belong to.  Sets the irg link field to NULL in all
291  * graphs not visited.
292  * Free the list with DEL_ARR_F.  */
293 static ir_node ** construct_block_lists(ir_graph *irg) {
294   int i;
295   ir_graph *rem = current_ir_graph;
296   current_ir_graph = irg;
297
298   for (i = 0; i < get_irp_n_irgs(); i++)
299     ird_set_irg_link(get_irp_irg(i), NULL);
300
301   irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
302
303   current_ir_graph = rem;
304   return ird_get_irg_link(irg);
305 }
306
307 /*******************************************************************/
308 /* flags to steer output                                           */
309 /*******************************************************************/
310
311 /* A compiler option to turn off edge labels */
312 int edge_label = 1;
313 /* A compiler option to turn off dumping values of constant entities */
314 int const_entities = 1;
315 /* A compiler option to dump the keep alive edges */
316 int dump_keepalive = 0;
317 /* Compiler options to dump analysis information in dump_ir_graph */
318 int dump_out_edge_flag = 0;
319 int dump_dominator_information_flag = 0;
320 int dump_loop_information_flag = 0;
321 int dump_backedge_information_flag = 1;
322 int dump_const_local = 0;
323 bool opt_dump_analysed_type_info = 1;
324 bool opt_dump_pointer_values_to_info = 0;  /* default off: for test compares!! */
325
326 char* overrule_nodecolor = NULL;
327
328 INLINE bool get_opt_dump_const_local(void) {
329   if (!dump_out_edge_flag && !dump_loop_information_flag)
330     return dump_const_local;
331   else
332     return false;
333 }
334
335 /* To turn off display of edge labels.  Edge labels offen cause xvcg to
336    abort with a segmentation fault. */
337 void turn_off_edge_labels(void) {
338   edge_label = 0;
339 }
340
341 void dump_consts_local(bool b) {
342   dump_const_local = b;
343 }
344
345 void turn_off_constant_entity_values(void) {
346   const_entities = 0;
347 }
348
349 void dump_keepalive_edges(bool b) {
350   dump_keepalive = b;
351 }
352
353 bool get_opt_dump_keepalive_edges(void) {
354   return dump_keepalive;
355 }
356
357 void dump_out_edges(void) {
358   dump_out_edge_flag = 1;
359 }
360
361 void dump_dominator_information(void) {
362   dump_dominator_information_flag = 1;
363 }
364
365 void dump_loop_information(void) {
366   dump_loop_information_flag = 1;
367 }
368
369 void dont_dump_loop_information(void) {
370   dump_loop_information_flag = 0;
371 }
372
373 void dump_backedge_information(bool b) {
374   dump_backedge_information_flag = b;
375 }
376
377 /* Dump the information of type field specified in ana/irtypeinfo.h.
378  * If the flag is set, the type name is output in [] in the node label,
379  * else it is output as info.
380  */
381 void dump_analysed_type_info(bool b) {
382   opt_dump_analysed_type_info = b;
383 }
384
385 void dump_pointer_values_to_info(bool b) {
386   opt_dump_pointer_values_to_info = b;
387 }
388
389 /*******************************************************************/
390 /* Routines to dump information about a single ir node.            */
391 /*******************************************************************/
392
393 static INLINE void
394 dump_node_opcode (ir_node *n)
395 {
396
397   switch(get_irn_opcode(n)) {
398
399   case iro_Const: {
400     int res;
401     char buf[1024];
402     res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
403     assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
404     fprintf(F, buf);
405   } break;
406
407   case iro_SymConst: {
408     if (get_SymConst_kind(n) == linkage_ptr_info) {
409       /* don't use get_SymConst_ptr_info as it mangles the name. */
410       fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
411     } else {
412       assert(get_kind(get_SymConst_type(n)) == k_type);
413       assert(get_type_ident(get_SymConst_type(n)));
414       fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
415       if (get_SymConst_kind(n) == type_tag)
416         fprintf (F, "tag");
417       else
418         fprintf (F, "size");
419     }
420   } break;
421
422   case iro_Filter: {
423     if (!interprocedural_view) fprintf(F, "Proj'");
424     else                       fprintf(F, "%s", get_irn_opname(n));
425   } break;
426
427   case iro_Start: {
428     if (interprocedural_view) {
429       fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_ent(get_irn_irg(n))));
430       break;
431     }
432   } /* fall through */
433
434   default: {
435     fprintf (F, "%s", get_irn_opname(n));
436   }
437
438   }  /* end switch */
439 }
440
441 static INLINE void
442 dump_node_mode (ir_node *n)
443 {
444   switch (get_irn_opcode(n)) {
445   case iro_Phi:
446   case iro_Const:
447   case iro_Id:
448   case iro_Proj:
449   case iro_Filter:
450   case iro_Conv:
451   case iro_Tuple:
452   case iro_Add:
453   case iro_Sub:
454   case iro_Mul:
455   case iro_And:
456   case iro_Or:
457   case iro_Eor:
458   case iro_Shl:
459   case iro_Shr:
460   case iro_Abs:
461   case iro_Cmp:
462   case iro_Confirm:
463     fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
464     break;
465   default:
466     ;
467   }
468 }
469
470 static void dump_node_typeinfo(ir_node *n) {
471   if (!opt_dump_analysed_type_info) return;
472   if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent  ||
473       get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent  ) {
474     type *tp = get_irn_type(n);
475     if (tp != none_type)
476       fprintf (F, " [%s]", get_type_name(tp));
477     else
478       fprintf (F, " []");
479   }
480 }
481
482 static INLINE void
483 dump_node_nodeattr (ir_node *n)
484 {
485   switch (get_irn_opcode(n)) {
486   case iro_Start:
487     if (false && interprocedural_view) {
488       fprintf (F, "%s", get_ent_dump_name(get_irg_ent(current_ir_graph)));
489     }
490     break;
491   case iro_Proj:
492     if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
493       fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
494     } else {
495       fprintf (F, "%ld", get_Proj_proj(n));
496     }
497     break;
498   case iro_Filter:
499     fprintf (F, "%ld", get_Filter_proj(n));
500     break;
501   case iro_Sel: {
502     fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
503     } break;
504   case iro_Cast: {
505     fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
506     } break;
507   case iro_Confirm: {
508     fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
509     } break;
510
511   default:
512     ;
513   } /* end switch */
514 }
515
516 static INLINE void
517 dump_node_vcgattr (ir_node *n)
518 {
519   switch (get_irn_opcode(n)) {
520   case iro_Start:
521   case iro_EndReg:
522     /* fall through */
523   case iro_EndExcept:
524     /* fall through */
525   case iro_End:
526     fprintf (F, "color: blue");
527     break;
528   case iro_Block:
529     fprintf (F, "color: lightyellow");
530     break;
531   case iro_Phi:
532     fprintf (F, "color: green");
533     break;
534   case iro_Const:
535   case iro_Proj:
536   case iro_Filter:
537   case iro_Tuple:
538     fprintf (F, "color: yellow");
539     break;
540   default:
541     PRINT_DEFAULT_NODE_ATTR;
542   }
543
544   if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor);
545 }
546
547 static INLINE void
548 dump_node_info (ir_node *n) {
549   int i;
550   char comma;
551   ir_graph *irg;
552   fprintf (F, " info1: \"");
553   if (opt_dump_pointer_values_to_info)
554     fprintf (F, "addr:    %p \n", (void *)n);
555   fprintf (F, "visited: %ld \n", get_irn_visited(n));
556   irg = get_irn_irg(n);
557   if (irg != get_const_code_irg())
558     fprintf (F, "irg:     %s\n", get_ent_dump_name(get_irg_entity(irg)));
559
560   fprintf(F, "arity: %d", get_irn_arity(n));
561   if ((get_irn_op(n) == op_Block) ||
562       (get_irn_op(n) == op_Phi) ||
563       ((get_irn_op(n) == op_Filter) && interprocedural_view)) {
564     fprintf(F, " backedges:");
565     comma = ' ';
566     for (i = 0; i < get_irn_arity(n); i++)
567       if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
568   }
569   fprintf(F, "\n");
570
571
572   /* Source types */
573   switch (get_irn_opcode(n)) {
574   case iro_Start: {
575     type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
576     fprintf(F, "start of method of type %s \n", get_type_name(tp));
577     for (i = 0; i < get_method_n_params(tp); ++i)
578       fprintf(F, "  param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
579   } break;
580   case iro_Alloc: {
581     fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
582   } break;
583   case iro_Free: {
584     fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
585   } break;
586   case iro_Sel: {
587     fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
588     fprintf(F, "  from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
589   } break;
590   case iro_Call: {
591     type *tp = get_Call_type(n);
592     fprintf(F, "calling method of type %s \n", get_type_name(tp));
593     for (i = 0; i < get_method_n_params(tp); ++i)
594       fprintf(F, "  param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
595     for (i = 0; i < get_method_n_ress(tp); ++i)
596       fprintf(F, "  resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
597     if (Call_has_callees(n)) {
598       fprintf(F, "possible callees: \n");
599       for (i = 0; i < get_Call_n_callees(n); i++) {
600         if (!get_Call_callee(n, i)) {
601           fprintf(F, "  %d external method\n", i);
602         } else {
603           fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
604         }
605       }
606     }
607   } break;
608   case iro_CallBegin: {
609     ir_node *call = get_CallBegin_call(n);
610     if (Call_has_callees(call)) {
611       fprintf(F, "possible callees: \n");
612       for (i = 0; i < get_Call_n_callees(call); i++) {
613         if (!get_Call_callee(call, i)) {
614           fprintf(F, "  %d external method\n", i);
615         } else {
616           fprintf(F, "  %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
617         }
618       }
619     }
620   } break;
621   case iro_Return: {
622     if (!interprocedural_view) {
623       type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
624       fprintf(F, "return in method of type %s \n", get_type_name(tp));
625       for (i = 0; i < get_method_n_ress(tp); ++i)
626         fprintf(F, "  res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
627     }
628     } break;
629   case iro_Const: {
630     type *tp = get_Const_type(n);
631     assert(tp != none_type);
632     fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
633   } break;
634   case iro_Filter: {
635     int i;
636     if (interprocedural_view) {
637       fprintf(F, "intra predecessor nodes:\n");
638       for (i = 0; i < get_irn_intra_arity(n); i++) {
639         ir_node *pred = get_irn_intra_n(n, i);
640         fprintf(F, "  %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
641       }
642     } else {
643       fprintf(F, "inter predecessor nodes:\n");
644       for (i = 0; i < get_irn_inter_arity(n); i++) {
645         ir_node *pred = get_irn_inter_n(n, i);
646         fprintf(F, "  %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
647                 get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
648       }
649     }
650   } break;
651   default: ;
652   }
653
654
655   if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent  ||
656       get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent  )
657     if (get_irn_type(n) != none_type)
658       fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
659
660   fprintf (F, "\"");
661 }
662
663
664 static INLINE
665 bool is_constlike_node(ir_node *n) {
666   ir_op *op = get_irn_op(n);
667   return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
668 }
669
670
671 /* outputs the predecessors of n, that are constants, local.  I.e.,
672    generates a copy of the constant predecessors for each node called with. */
673 static void dump_const_node_local(ir_node *n) {
674   int i;
675   if (!get_opt_dump_const_local()) return;
676
677   /* Use visited flag to avoid outputting nodes twice.
678      initialize it first. */
679   for (i = 0; i < get_irn_arity(n); i++) {
680     ir_node *con = get_irn_n(n, i);
681     if (is_constlike_node(con)) {
682       set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
683     }
684   }
685
686   for (i = 0; i < get_irn_arity(n); i++) {
687     ir_node *con = get_irn_n(n, i);
688     if (is_constlike_node(con) && irn_not_visited(con)) {
689       mark_irn_visited(con);
690       /* Generate a new name for the node by appending the names of
691          n and const. */
692       fprintf (F, "node: {title: "); PRINT_CONSTID(n, con);
693       fprintf(F, " label: \"");
694       dump_node_opcode(con);
695       dump_node_mode (con);
696       dump_node_typeinfo(con);
697       fprintf (F, " ");
698       dump_node_nodeattr(con);
699       fprintf (F, " %ld", get_irn_node_nr(con));
700       fprintf (F, "\" ");
701       dump_node_vcgattr(con);
702       dump_node_info(con);
703       fprintf (F, "}\n");
704     }
705   }
706 }
707
708 static void
709 dump_node (ir_node *n) {
710   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
711   /* dump this node */
712   fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
713
714   dump_node_opcode(n);
715   dump_node_mode (n);
716   dump_node_typeinfo(n);
717   fprintf (F, " ");
718   dump_node_nodeattr(n);
719   fprintf (F, " %ld", get_irn_node_nr(n));
720   fprintf (F, "\" ");
721   dump_node_vcgattr(n);
722   dump_node_info(n);
723   fprintf (F, "}\n");
724   dump_const_node_local(n);
725 #ifdef HEAPANAL
726   dump_chi_term(F, n);
727   dump_state(F, n);
728 #endif
729 }
730
731 /* dump the edge to the block this node belongs to */
732 static void
733 dump_ir_block_edge(ir_node *n)  {
734   if (get_opt_dump_const_local() && is_constlike_node(n)) return;
735   if (is_no_Block(n)) {
736     fprintf (F, "edge: { sourcename: \"");
737     PRINT_NODEID(n);
738     fprintf (F, "\" targetname: \"");
739     PRINT_NODEID(get_nodes_block(n));
740     fprintf (F, "\" "   BLOCK_EDGE_ATTR "}\n");
741   }
742 }
743
744 static void print_edge_vcgattr(ir_node *from, int to) {
745   assert(from);
746
747   if (dump_backedge_information_flag && is_backedge(from, to))
748     fprintf (F, BACK_EDGE_ATTR);
749
750   switch (get_irn_opcode(from)) {
751   case iro_Block:
752     fprintf (F, CF_EDGE_ATTR);
753     break;
754   case iro_Start:   break;
755   case iro_End:
756     if (to >= 0) {
757       if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
758         fprintf (F, CF_EDGE_ATTR);
759       if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
760         fprintf (F, MEM_EDGE_ATTR);
761     }
762     break;
763   case iro_EndReg: break;
764   case iro_EndExcept: break;
765   case iro_Jmp:     break;
766   case iro_Break:   break;
767   case iro_Cond:    break;
768   case iro_Return:
769   case iro_Raise:
770     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
771     break;
772   case iro_Const:   break;
773   case iro_SymConst:break;
774   case iro_Sel:
775   case iro_Call:
776     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
777     break;
778   case iro_CallBegin: break;
779   case iro_Add:     break;
780   case iro_Sub:     break;
781   case iro_Minus:   break;
782   case iro_Mul:     break;
783   case iro_Quot:
784   case iro_DivMod:
785   case iro_Div:
786   case iro_Mod:
787     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
788     break;
789   case iro_Abs:    break;
790   case iro_And:    break;
791   case iro_Or:     break;
792   case iro_Eor:    break;
793   case iro_Shl:    break;
794   case iro_Shr:    break;
795   case iro_Shrs:   break;
796   case iro_Rot:    break;
797   case iro_Cmp:    break;
798   case iro_Conv:   break;
799   case iro_Phi:
800     if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
801     break;
802   case iro_Load:
803   case iro_Store:
804   case iro_Alloc:
805   case iro_Free:
806     if (to == 0) fprintf (F, MEM_EDGE_ATTR);
807     break;
808   case iro_Sync:
809     fprintf (F, MEM_EDGE_ATTR);
810     break;
811   case iro_Tuple:  break;
812   case iro_Proj:
813   case iro_Filter:
814     switch (get_irn_modecode(from)) {
815     case irm_X:
816       fprintf (F, CF_EDGE_ATTR);
817       break;
818     case irm_M:
819       fprintf (F, MEM_EDGE_ATTR);
820       break;
821     default: break;
822     }
823     break;
824   case iro_Bad:    break;
825   case iro_Unknown: break;
826   case iro_Id:     break;
827   default:
828     ;
829   }
830 }
831
832 /* dump edges to our inputs */
833 static void
834 dump_ir_data_edges(ir_node *n)  {
835   int i, visited = get_irn_visited(n);
836
837   if ((get_irn_op(n) == op_End) && (!dump_keepalive))
838     return;
839
840   for (i = 0; i < get_irn_arity(n); i++) {
841     ir_node * pred = get_irn_n(n, i);
842     assert(pred);
843
844     if ((interprocedural_view && get_irn_visited(pred) < visited))
845       continue; /* pred not dumped */
846
847     if (dump_backedge_information_flag && is_backedge(n, i))
848       fprintf (F, "backedge: {sourcename: \"");
849     else
850       fprintf (F, "edge: {sourcename: \"");
851     PRINT_NODEID(n);
852     fprintf (F, "\" targetname: ");
853     if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
854       PRINT_CONSTID(n, pred);
855     } else {
856       fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
857     }
858     fprintf (F, " label: \"%d\" ", i);
859     print_edge_vcgattr(n, i);
860     fprintf (F, "}\n");
861   }
862 }
863
864 /** Dumps a node and its edges but not the block edge
865  */
866 static INLINE void
867 dump_node_wo_blockedge (ir_node *n, void* env) {
868   dump_node(n);
869   dump_ir_data_edges(n);
870 }
871
872 /** Dumps a node and its edges.
873  */
874 static void
875 dump_whole_node (ir_node *n, void* env) {
876   dump_node_wo_blockedge(n, env);
877   if (!node_floats(n)) dump_ir_block_edge(n);
878 }
879
880 static void
881 dump_const_node(ir_node *n, void *env) {
882   if (is_Block(n)) return;
883   dump_node_wo_blockedge(n, env);
884 }
885
886 /***********************************************************************/
887 /* the following routines dump the nodes/irgs bracketed to graphs.     */
888 /***********************************************************************/
889
890 /** Dumps a constant expression as entity initializer, array bound ...
891  */
892 static void dump_const_expression(ir_node *value) {
893   ir_graph *rem = current_ir_graph;
894   int rem_dump_const_local = dump_const_local;
895   dump_const_local = 0;
896   current_ir_graph = get_const_code_irg();
897   irg_walk(value, dump_const_node, NULL, NULL);
898   /* Decrease visited flag so that we walk with the same flag for the next
899      expresssion.  This guarantees that we don't dump the same node twice,
900      as for const expressions cse is performed to save memory. */
901   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
902   current_ir_graph = rem;
903   dump_const_local = rem_dump_const_local;
904 }
905
906 /** Dump a block as graph containing its nodes.
907  *
908  *  Expects to find nodes belonging to the block as list in its
909  *  link field.
910  *  Dumps the edges of all nodes including itself. */
911 static void
912 dump_whole_block(ir_node *block) {
913   ir_node *node;
914   assert(is_Block(block));
915
916   fprintf(F, "graph: { title: \"");
917   PRINT_NODEID(block);
918   fprintf(F, "\"  label: \"");
919   dump_node_opcode(block);
920   fprintf (F, " %ld", get_irn_node_nr(block));
921 #ifdef HEAPANAL
922   if (get_opt_dump_abstvals())
923     fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
924 #endif
925   fprintf(F, "\" status:clustered color:%s \n",
926            get_Block_matured(block) ? "yellow" : "red");
927
928   /* dump the blocks edges */
929   dump_ir_data_edges(block);
930
931   /* dump the nodes that go into the block */
932   for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
933     dump_node(node);
934     dump_ir_data_edges(node);
935   }
936
937   /* Close the vcg information for the block */
938   fprintf(F, "}\n");
939   dump_const_node_local(block);
940 #ifdef HEAPANAL
941   dump_chi_term(F, block);
942 #endif
943   fprintf(F, "\n");
944 }
945
946 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
947  *  The outermost nodes: blocks and nodes not pinned, Bad, Unknown. */
948 static void
949 dump_block_graph (ir_graph *irg) {
950   int i;
951   ir_graph *rem = current_ir_graph;
952   ir_node **arr = ird_get_irg_link(irg);
953   current_ir_graph = irg;
954
955   for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
956     ir_node * node = arr[i];
957     if (is_Block(node)) {
958       /* Dumps the block and all the nodes in the block, which are to
959          be found in Block->link. */
960       dump_whole_block(node);
961     } else {
962       /* Nodes that are not in a Block. */
963       dump_node(node);
964       dump_ir_data_edges(node);
965     }
966   }
967
968   if (dump_loop_information_flag) dump_loop_nodes_into_graph(irg);
969
970   current_ir_graph = rem;
971 }
972
973 /** Dumps an irg as a graph.
974  *  If interprocedural view edges can point to nodes out of this graph.
975  */
976 static void dump_graph(ir_graph *irg) {
977
978   fprintf(F, "graph: { title: \"");
979   PRINT_IRGID(irg);
980   fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
981           get_ent_dump_name(get_irg_ent(irg)));
982
983   dump_block_graph (irg);
984
985   /* Close the vcg information for the irg */
986   fprintf(F, "}\n\n");
987 }
988
989 /*******************************************************************/
990 /* Basic type and entity nodes and edges.                          */
991 /*******************************************************************/
992
993 /* dumps the edges between nodes and their type or entity attributes. */
994 static void dump_node2type_edges (ir_node *n, void *env)
995 {
996   assert(n);
997
998   switch (get_irn_opcode(n)) {
999   case iro_Const :
1000     /* @@@ some consts have an entity */
1001     break;
1002   case iro_SymConst:
1003     if (   (get_SymConst_kind(n) == type_tag)
1004            || (get_SymConst_kind(n) == size))
1005       {
1006         print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
1007       }
1008     break;
1009   case iro_Sel: {
1010       print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
1011     } break;
1012   case iro_Call: {
1013       print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
1014     } break;
1015   case iro_Alloc: {
1016       print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
1017     } break;
1018   case iro_Free: {
1019       print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
1020     } break;
1021   case iro_Cast: {
1022       print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
1023     } break;
1024   default:
1025     break;
1026   }
1027 }
1028
1029
1030 static void print_type_info(type *tp) {
1031   if (get_type_state(tp) == layout_undefined) {
1032     fprintf(F, "state: layout_undefined\n");
1033   } else {
1034     fprintf(F, "state: layout_fixed,\n");
1035   }
1036   if (get_type_mode(tp))
1037     fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
1038   fprintf(F, "size: %dB,\n", get_type_size(tp));
1039 }
1040
1041 static void print_typespecific_info(type *tp) {
1042   switch (get_type_tpop_code(tp)) {
1043   case tpo_class:
1044     {
1045       fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
1046     } break;
1047   case tpo_struct:
1048     {
1049     } break;
1050   case tpo_method:
1051     {
1052     } break;
1053   case tpo_union:
1054     {
1055     } break;
1056   case tpo_array:
1057     {
1058     } break;
1059   case tpo_enumeration:
1060     {
1061     } break;
1062   case tpo_pointer:
1063     {
1064     } break;
1065   case tpo_primitive:
1066     {
1067     } break;
1068   default: break;
1069   } /* switch type */
1070 }
1071
1072
1073 static void print_typespecific_vcgattr(type *tp) {
1074   switch (get_type_tpop_code(tp)) {
1075   case tpo_class:
1076     {
1077       if (peculiarity_existent == get_class_peculiarity(tp))
1078         fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1079       else
1080         fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1081     } break;
1082   case tpo_struct:
1083     {
1084       fprintf (F, " " TYPE_METH_NODE_ATTR);
1085     } break;
1086   case tpo_method:
1087     {
1088     } break;
1089   case tpo_union:
1090     {
1091     } break;
1092   case tpo_array:
1093     {
1094     } break;
1095   case tpo_enumeration:
1096     {
1097     } break;
1098   case tpo_pointer:
1099     {
1100     } break;
1101   case tpo_primitive:
1102     {
1103     } break;
1104   default: break;
1105   } /* switch type */
1106 }
1107
1108 static void print_type_node(type *tp)
1109 {
1110   fprintf (F, "node: {title: ");
1111   PRINT_TYPEID(tp);
1112   fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
1113   fprintf (F, " info1: \"");
1114   print_type_info(tp);
1115   print_typespecific_info(tp);
1116   fprintf (F, "\"");
1117   print_typespecific_vcgattr(tp);
1118   fprintf (F, "}\n");
1119 }
1120
1121 #define X(a)    case a: fprintf(F, #a); break
1122 void dump_entity_node(entity *ent)
1123 {
1124   fprintf (F, "node: {title: \"");
1125   PRINT_ENTID(ent); fprintf(F, "\"");
1126   fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1127   fprintf (F, "label: ");
1128   fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
1129   fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
1130
1131   fprintf (F, "\nallocation:  ");
1132   switch (get_entity_allocation(ent)) {
1133     X(allocation_dynamic);
1134     X(allocation_automatic);
1135     X(allocation_static);
1136     X(allocation_parameter);
1137   }
1138
1139   fprintf (F, "\nvisibility:  ");
1140   switch (get_entity_visibility(ent)) {
1141     X(visibility_local);
1142     X(visibility_external_visible);
1143     X(visibility_external_allocated);
1144   }
1145
1146   fprintf (F, "\nvariability: ");
1147   switch (get_entity_variability(ent)) {
1148     X(variability_uninitialized);
1149     X(variability_initialized);
1150     X(variability_part_constant);
1151     X(variability_constant);
1152   }
1153
1154   fprintf (F, "\nvolatility:  ");
1155   switch (get_entity_volatility(ent)) {
1156     X(volatility_non_volatile);
1157     X(volatility_is_volatile);
1158   }
1159
1160   fprintf(F, "\npeculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent)));
1161   fprintf(F, "\nname:    %s\nld_name: %s",
1162           get_ent_dump_name(ent), ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
1163   fprintf(F, "\noffset:  %d", get_entity_offset(ent));
1164   if (is_method_type(get_entity_type(ent))) {
1165     if (get_entity_irg(ent))   /* can be null */
1166       { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
1167     else
1168       { fprintf (F, "\nirg = NULL"); }
1169   }
1170   fprintf(F, "\"\n}\n");
1171 }
1172 #undef X
1173
1174 /* dumps a type or entity and it's edges. */
1175 static void
1176 dump_type_info (type_or_ent *tore, void *env) {
1177   int i = 0;  /* to shutup gcc */
1178
1179   /* dump this type or entity */
1180
1181   switch (get_kind(tore)) {
1182   case k_entity:
1183     {
1184       entity *ent = (entity *)tore;
1185       ir_node *value;
1186       /* The node */
1187       dump_entity_node(ent);
1188       /* The Edges */
1189       /* skip this to reduce graph.  Member edge of type is parallel to this edge. *
1190       fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1191                 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1192       print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1193       if(is_class_type(get_entity_owner(ent))) {
1194         for(i = 0; i < get_entity_n_overwrites(ent); i++){
1195           print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
1196         }
1197       }
1198       /* attached subgraphs */
1199       if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1200         if (is_atomic_entity(ent)) {
1201           value = get_atomic_ent_value(ent);
1202           if (value) {
1203             print_ent_node_edge(F,ent, value, ENT_VALUE_EDGE_ATTR, i);
1204             /* DDMN(value);  $$$ */
1205             dump_const_expression(value);
1206           }
1207         }
1208         if (is_compound_entity(ent)) {
1209           for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1210             value = get_compound_ent_value(ent, i);
1211             if (value) {
1212               print_ent_node_edge(F,ent,value,ENT_VALUE_EDGE_ATTR,i);
1213               dump_const_expression(value);
1214               print_ent_ent_edge(F,ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
1215               /*
1216                 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1217                 ENT_CORR_EDGE_ATTR  "}\n", GET_ENTID(ent),
1218                 get_compound_ent_value_member(ent, i), i);
1219               */
1220             }
1221           }
1222         }
1223       }
1224     } break;
1225   case k_type:
1226     {
1227       type *tp = (type *)tore;
1228       print_type_node(tp);
1229       /* and now the edges */
1230       switch (get_type_tpop_code(tp)) {
1231       case tpo_class:
1232         {
1233           for (i=0; i < get_class_n_supertypes(tp); i++) {
1234             print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1235           }
1236
1237           for (i=0; i < get_class_n_members(tp); i++) {
1238             print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1239           }
1240         } break;
1241       case tpo_struct:
1242         {
1243           for (i=0; i < get_struct_n_members(tp); i++) {
1244             print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1245           }
1246         } break;
1247       case tpo_method:
1248         {
1249           for (i = 0; i < get_method_n_params(tp); i++)
1250           {
1251              print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1252           }
1253           for (i = 0; i < get_method_n_ress(tp); i++)
1254           {
1255              print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1256           }
1257         } break;
1258       case tpo_union:
1259         {
1260           for (i = 0; i < get_union_n_members(tp); i++)
1261           {
1262                   print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1263           }
1264         } break;
1265       case tpo_array:
1266         {
1267                   print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1268                   print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1269                   for (i = 0; i < get_array_n_dimensions(tp); i++) {
1270                     ir_node *upper = get_array_upper_bound(tp, i);
1271                     ir_node *lower = get_array_lower_bound(tp, i);
1272                     print_node_type_edge(F,upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1273                     print_node_type_edge(F,lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1274                     dump_const_expression(upper);
1275                     dump_const_expression(lower);
1276                   }
1277
1278         } break;
1279       case tpo_enumeration:
1280         {
1281         } break;
1282       case tpo_pointer:
1283         {
1284                   print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1285         } break;
1286       case tpo_primitive:
1287         {
1288         } break;
1289       default: break;
1290       } /* switch type */
1291     }
1292     break; /* case k_type */
1293   default:
1294     {
1295       printf(" *** irdump,  dump_type_info(l.%i), faulty type.\n", __LINE__);
1296     } break;
1297   } /* switch kind_or_entity */
1298 }
1299
1300 /** For dumping class hierarchies.
1301  * Dumps a class type node and a superclass edge.
1302  * If env != null dumps entities of classes and overwrites edges.
1303  */
1304 static void
1305 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1306   int i = 0;  /* to shutup gcc */
1307
1308   /* dump this type or entity */
1309   switch (get_kind(tore)) {
1310   case k_entity: {
1311     entity *ent = (entity *)tore;
1312     if (get_entity_owner(ent) == get_glob_type()) break;
1313     if ((env) && is_class_type(get_entity_owner(ent))) {
1314       /* The node */
1315       dump_entity_node(ent);
1316       /* The edges */
1317       print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1318       for(i = 0; i < get_entity_n_overwrites(ent); i++)
1319       {
1320       print_ent_ent_edge(F,get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1321       }
1322     }
1323   } break; /* case k_entity */
1324   case k_type:
1325     {
1326       type *tp = (type *)tore;
1327       if (tp == get_glob_type()) break;
1328       switch (get_type_tpop_code(tp)) {
1329         case tpo_class: {
1330           print_type_node(tp);
1331           /* and now the edges */
1332           for (i=0; i < get_class_n_supertypes(tp); i++)
1333           {
1334                   print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1335           }
1336         } break;
1337         default: break;
1338       } /* switch type */
1339     }
1340     break; /* case k_type */
1341   default:
1342     {
1343       printf(" *** irdump,  dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1344     } break;
1345   } /* switch kind_or_entity */
1346 }
1347
1348 /*******************************************************************/
1349 /* dump analysis information that is expressed in graph terms.     */
1350 /*******************************************************************/
1351
1352 /* dump out edges */
1353 static void
1354 dump_out_edge (ir_node *n, void* env) {
1355   int i;
1356   for (i = 0; i < get_irn_n_outs(n); i++) {
1357     assert(get_irn_out(n, i));
1358     fprintf (F, "edge: {sourcename: \"");
1359     PRINT_NODEID(n);
1360     fprintf (F, "\" targetname: \"");
1361     PRINT_NODEID(get_irn_out(n, i));
1362     fprintf (F, "\" color: red linestyle: dashed");
1363     fprintf (F, "}\n");
1364   }
1365 }
1366
1367 static INLINE void
1368 dump_loop_label(ir_loop *loop) {
1369   fprintf (F, "loop %d, %d sons, %d nodes",
1370            get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1371 }
1372
1373 static INLINE void dump_loop_info(ir_loop *loop) {
1374   fprintf (F, " info1: \"");
1375   fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
1376 #if DEBUG_libfirm   /* GL @@@ debug analyses */
1377   fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
1378 #endif
1379   fprintf (F, "\"");
1380 }
1381
1382 static INLINE void
1383 dump_loop_node(ir_loop *loop) {
1384   fprintf (F, "node: {title: \"");
1385   PRINT_LOOPID(loop);
1386   fprintf (F, "\" label: \"");
1387   dump_loop_label(loop);
1388   fprintf (F, "\" ");
1389   dump_loop_info(loop);
1390   fprintf (F, "}\n");
1391
1392 }
1393
1394 static INLINE void
1395 dump_loop_node_edge (ir_loop *loop, int i) {
1396   assert(loop);
1397   fprintf (F, "edge: {sourcename: \"");
1398   PRINT_LOOPID(loop);
1399   fprintf (F, "\" targetname: \"");
1400   PRINT_NODEID(get_loop_node(loop, i));
1401   fprintf (F, "\" color: green");
1402   fprintf (F, "}\n");
1403 }
1404
1405 static INLINE void
1406 dump_loop_son_edge (ir_loop *loop, int i) {
1407   assert(loop);
1408   fprintf (F, "edge: {sourcename: \"");
1409   PRINT_LOOPID(loop);
1410   fprintf (F, "\" targetname: \"");
1411   PRINT_LOOPID(get_loop_son(loop, i));
1412   fprintf (F, "\" color: darkgreen label: \"%d\"}\n",
1413            get_loop_element_pos(loop, get_loop_son(loop, i)));
1414 }
1415
1416 static
1417 void dump_loops (ir_loop *loop) {
1418   int i;
1419   /* dump this loop node */
1420   dump_loop_node(loop);
1421
1422   /* dump edges to nodes in loop -- only if it is a real loop */
1423   if (get_loop_depth(loop) != 0) {
1424     for (i = 0; i < get_loop_n_nodes(loop); i++) {
1425       dump_loop_node_edge(loop, i);
1426     }
1427   }
1428   for (i = 0; i < get_loop_n_sons(loop); i++) {
1429     dump_loops(get_loop_son(loop, i));
1430     dump_loop_son_edge(loop, i);
1431   }
1432 }
1433
1434 static INLINE
1435 void dump_loop_nodes_into_graph(ir_graph *irg) {
1436   ir_graph *rem = current_ir_graph;
1437   current_ir_graph = irg;
1438
1439   if (get_irg_loop(irg)) dump_loops(get_irg_loop(irg));
1440
1441   current_ir_graph = rem;
1442 }
1443
1444
1445 /************************************************************************/
1446 /* open and close vcg file                                              */
1447 /************************************************************************/
1448
1449 static INLINE void
1450 dump_vcg_header(const char *name, const char *orientation) {
1451   char *label;
1452
1453   if (edge_label) {
1454     label = "yes";
1455   } else {
1456     label = "no";
1457   }
1458
1459   if (!orientation) orientation = "bottom_to_top";
1460
1461   /* print header */
1462   fprintf (F,
1463            "graph: { title: \"ir graph of %s\"\n"
1464            "display_edge_labels: %s\n"
1465            "layoutalgorithm: mindepth\n"
1466            "manhattan_edges: yes\n"
1467            "port_sharing: no\n"
1468            "orientation: %s\n"
1469            "classname 1: \"Data\"\n"
1470            "classname 2: \"Block\"\n"
1471            "classname 3: \"Entity type\"\n"
1472            "classname 4: \"Entity owner\"\n"
1473            "classname 5: \"Method Param\"\n"
1474            "classname 6: \"Method Res\"\n"
1475            "classname 7: \"Super\"\n"
1476            "classname 8: \"Union\"\n"
1477            "classname 9: \"Points-to\"\n"
1478            "classname 10: \"Array Element Type\"\n"
1479            "classname 11: \"Overwrites\"\n"
1480            "classname 12: \"Member\"\n",
1481            name, label, orientation);
1482
1483   fprintf (F, "\n");            /* a separator */
1484 }
1485
1486 static void vcg_open (ir_graph *irg, char * suffix1, char *suffix2) {
1487   const char *nm = get_irg_dump_name(irg);
1488   int len = strlen(nm);
1489   char *fname;  /* filename to put the vcg information in */
1490
1491   if (!suffix1) suffix1 = "";
1492   if (!suffix2) suffix2 = "";
1493
1494   /** open file for vcg graph */
1495   fname = malloc (len + strlen(suffix1) + strlen(suffix2) + 5);
1496   strncpy (fname, nm, len);      /* copy the filename */
1497   fname[len] = '\0';
1498   strcat (fname, suffix1);  /* append file suffix */
1499   strcat (fname, suffix2);  /* append file suffix */
1500   strcat (fname, ".vcg");   /* append the .vcg suffix */
1501   F = fopen (fname, "w");   /* open file for writing */
1502   if (!F) {
1503     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
1504   }
1505   free(fname);
1506 }
1507
1508 static void vcg_open_name (const char *name, char *suffix) {
1509   char *fname;  /* filename to put the vcg information in */
1510
1511   if (!suffix) suffix = "";
1512
1513   /** open file for vcg graph */
1514   fname = malloc (strlen(name) + 5 + strlen(suffix));
1515   strcpy (fname, name);    /* copy the filename */
1516   strcat (fname, suffix);
1517   strcat (fname, ".vcg");  /* append the .vcg suffix */
1518   F = fopen (fname, "w");  /* open file for writing */
1519   if (!F) {
1520     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
1521   }
1522   free(fname);
1523 }
1524
1525 static INLINE void dump_vcg_footer (void) {
1526   fprintf (F, "}\n");
1527 }
1528
1529 static void
1530 vcg_close (void) {
1531   dump_vcg_footer();    /* print footer */
1532   fclose (F);           /* close vcg file */
1533 }
1534
1535 /************************************************************************/
1536 /************************************************************************/
1537 /* Routines that dump all or parts of the firm representation to a file */
1538 /************************************************************************/
1539 /************************************************************************/
1540
1541 /************************************************************************/
1542 /* Dump ir graphs, differnt formats and additional information.         */
1543 /************************************************************************/
1544
1545 /** Routine to dump a graph, blocks as conventional nodes.
1546  */
1547 void
1548 dump_ir_graph (ir_graph *irg)
1549 {
1550   ir_graph *rem;
1551   char *suffix;
1552   rem = current_ir_graph;
1553   current_ir_graph = irg;
1554
1555   if (interprocedural_view) suffix = "-pure-ip";
1556   else                      suffix = "-pure";
1557   vcg_open (irg, dump_file_suffix, suffix);
1558   dump_vcg_header(get_irg_dump_name(irg), NULL);
1559
1560   /* walk over the graph */
1561   /* dump_whole_node must be called in post visiting predecessors */
1562   irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1563
1564   /* dump the out edges in a separate walk */
1565   if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1566     irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1567   }
1568
1569   vcg_close();
1570
1571   current_ir_graph = rem;
1572 }
1573
1574
1575 void
1576 dump_ir_block_graph (ir_graph *irg)
1577 {
1578   int i;
1579   char *suffix;
1580
1581   if (interprocedural_view) suffix = "-ip";
1582   else                      suffix = "";
1583   vcg_open (irg, dump_file_suffix, suffix);
1584   dump_vcg_header(get_irg_dump_name(irg), NULL);
1585
1586   construct_block_lists(irg);
1587
1588   for (i = 0; i < get_irp_n_irgs(); i++) {
1589     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1590     if (arr) {
1591       dump_graph(get_irp_irg(i));
1592       DEL_ARR_F(arr);
1593     }
1594   }
1595
1596   vcg_close();
1597 }
1598
1599 /** dumps a graph with type information
1600  */
1601 void
1602 dump_ir_graph_w_types (ir_graph *irg)
1603 {
1604   ir_graph *rem = current_ir_graph;
1605   char *suffix;
1606   current_ir_graph = irg;
1607
1608   if (interprocedural_view) suffix = "-pure-wtypes-ip";
1609   else                      suffix = "-pure-wtypes";
1610   vcg_open (irg, dump_file_suffix, suffix);
1611   dump_vcg_header(get_irg_dump_name(irg), NULL);
1612
1613   /* dump common ir graph */
1614   irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1615   /* dump type info */
1616   type_walk_irg(irg, dump_type_info, NULL, NULL);
1617   inc_irg_visited(get_const_code_irg());
1618   /* dump edges from graph to type info */
1619   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1620
1621   vcg_close();
1622   current_ir_graph = rem;
1623 }
1624
1625 void
1626 dump_ir_block_graph_w_types (ir_graph *irg)
1627 {
1628   int i;
1629   char *suffix;
1630   ir_graph *rem = current_ir_graph;
1631
1632   if (interprocedural_view) suffix = "-wtypes-ip";
1633   else                      suffix = "-wtypes";
1634   vcg_open (irg, dump_file_suffix, suffix);
1635   dump_vcg_header(get_irg_dump_name(irg), NULL);
1636
1637   /* dump common blocked ir graph */
1638   construct_block_lists(irg);
1639
1640   for (i = 0; i < get_irp_n_irgs(); i++) {
1641     ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1642     if (arr) {
1643       dump_graph(get_irp_irg(i));
1644       DEL_ARR_F(arr);
1645     }
1646   }
1647
1648   /* dump type info */
1649   current_ir_graph = irg;
1650   type_walk_irg(irg, dump_type_info, NULL, NULL);
1651   inc_irg_visited(get_const_code_irg());
1652
1653   /* dump edges from graph to type info */
1654   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1655
1656   current_ir_graph = rem;
1657   vcg_close();
1658 }
1659
1660 /***********************************************************************/
1661 /* The following routines dump a control flow graph.                   */
1662 /***********************************************************************/
1663
1664 static void
1665 dump_block_to_cfg (ir_node *block, void *env) {
1666   int i;
1667   ir_node *pred;
1668
1669   if (is_Block(block)) {
1670     /* This is a block. Dump a node for the block. */
1671     fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1672     fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1673     PRINT_NODEID(block);
1674     fprintf (F, "\" ");
1675     if (dump_dominator_information_flag)
1676       fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1677     fprintf (F, "}\n");
1678     /* Dump the edges */
1679     for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1680       if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1681         pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1682         fprintf (F, "edge: { sourcename: \"");
1683         PRINT_NODEID(block);
1684         fprintf (F, "\" targetname: \"");
1685         PRINT_NODEID(pred);
1686         fprintf (F, "\"}\n");
1687       }
1688
1689     /* Dump dominator edge */
1690     if (dump_dominator_information_flag && get_Block_idom(block)) {
1691       pred = get_Block_idom(block);
1692       fprintf (F, "edge: { sourcename: \"");
1693       PRINT_NODEID(block);
1694       fprintf (F, "\" targetname: \"");
1695       PRINT_NODEID(pred);
1696       fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1697     }
1698   }
1699 }
1700
1701 void
1702 dump_cfg (ir_graph *irg)
1703 {
1704   ir_graph *rem = current_ir_graph;
1705   int ddif = dump_dominator_information_flag;
1706   int ipv = interprocedural_view;
1707   current_ir_graph = irg;
1708
1709   vcg_open (irg, dump_file_suffix, "-cfg");
1710   dump_vcg_header(get_irg_dump_name(irg), NULL);
1711
1712   if (interprocedural_view) {
1713     printf("Warning: dumping cfg not in interprocedural view!\n");
1714     interprocedural_view = 0;
1715   }
1716
1717   if (get_irg_dom_state(irg) != dom_consistent)
1718     dump_dominator_information_flag = 0;
1719
1720   /* walk over the blocks in the graph */
1721   irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1722   dump_node (get_irg_bad(irg));
1723
1724   dump_dominator_information_flag = ddif;
1725   interprocedural_view = ipv;
1726   vcg_close();
1727   current_ir_graph = rem;
1728 }
1729
1730
1731
1732 /* Dump all irgs in interprocedural view to a single file. */
1733 void dump_all_cg_block_graph(void) {
1734   int i;
1735   int rem_view = interprocedural_view;
1736   interprocedural_view = 1;
1737
1738   vcg_open_name ("All_graphs", dump_file_suffix);
1739   dump_vcg_header("All_graphs", NULL);
1740
1741   /* collect nodes in all irgs reachable in call graph*/
1742   for (i = 0; i < get_irp_n_irgs(); i++)
1743     ird_set_irg_link(get_irp_irg(i), NULL);
1744
1745   cg_walk(clear_link, collect_node, NULL);
1746
1747   /* dump all graphs */
1748   for (i = 0; i < get_irp_n_irgs(); i++) {
1749     current_ir_graph = get_irp_irg(i);
1750     assert(ird_get_irg_link(current_ir_graph));
1751     dump_graph(current_ir_graph);
1752     DEL_ARR_F(ird_get_irg_link(current_ir_graph));
1753   }
1754
1755   vcg_close();
1756   interprocedural_view = rem_view;
1757 }
1758
1759 /***********************************************************************/
1760 /* the following routines dumps type information without any ir nodes. */
1761 /***********************************************************************/
1762
1763 void
1764 dump_type_graph (ir_graph *irg)
1765 {
1766   ir_graph *rem;
1767   rem = current_ir_graph;
1768   current_ir_graph = irg;
1769
1770   vcg_open (irg, dump_file_suffix, "-type");
1771   dump_vcg_header(get_irg_dump_name(irg), NULL);
1772
1773   /* walk over the blocks in the graph */
1774   type_walk_irg(irg, dump_type_info, NULL, NULL);
1775   /* The walker for the const code can be called several times for the
1776      same (sub) experssion.  So that no nodes are dumped several times
1777      we decrease the visited flag of the corresponding graph after each
1778      walk.  So now increase it finally. */
1779   inc_irg_visited(get_const_code_irg());
1780
1781   vcg_close();
1782   current_ir_graph = rem;
1783 }
1784
1785 void
1786 dump_all_types (void)
1787 {
1788   vcg_open_name ("All_types", dump_file_suffix);
1789   dump_vcg_header("All_types", NULL);
1790   type_walk(dump_type_info, NULL, NULL);
1791   inc_irg_visited(get_const_code_irg());
1792   vcg_close();
1793 }
1794
1795 void
1796 dump_class_hierarchy (bool entities)
1797 {
1798   vcg_open_name ("class_hierarchy", dump_file_suffix);
1799   dump_vcg_header("class_hierarchy", NULL);
1800   if (entities)
1801     type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1802   else
1803     type_walk(dump_class_hierarchy_node, NULL, NULL);
1804   vcg_close();
1805 }
1806
1807 /***********************************************************************/
1808 /* dumps all graphs with the graph-dumper passed. Possible dumpers:    */
1809 /*  dump_ir_graph                                                      */
1810 /*  dump_ir_block_graph                                                */
1811 /*  dump_cfg                                                           */
1812 /*  dump_type_graph                                                    */
1813 /*  dump_ir_graph_w_types                                              */
1814 /***********************************************************************/
1815
1816 void dump_all_ir_graphs (dump_graph_func *dmp_grph) {
1817   int i;
1818   for (i=0; i < get_irp_n_irgs(); i++) {
1819     dmp_grph(get_irp_irg(i));
1820   }
1821 }
1822
1823
1824 /**********************************************************************************
1825  * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes  *
1826  * packed together in one subgraph                                                *
1827  **********************************************************************************/
1828
1829
1830
1831 void dump_loops_standalone (ir_loop *loop) {
1832   int i, loop_node_started = 0, son_number = 0, first;
1833   loop_element le;
1834
1835   /* Dump a new loop node. */
1836   dump_loop_node(loop);
1837
1838   /* Dump the loop elements. */
1839   for(i = 0; i < get_loop_n_elements(loop); i++)
1840     {
1841       le = get_loop_element(loop, i);
1842
1843       ir_loop *son = le.son;
1844       if (get_kind(son) == k_ir_loop)
1845         {
1846           /* We are a loop son -> Recurse */
1847
1848           if(loop_node_started) /* Close the "firm-nodes" node first if we started one. */
1849             {
1850               fprintf(F, "\" }\n");
1851               fprintf (F, "edge: {sourcename: \"");
1852               PRINT_LOOPID(loop);
1853               fprintf (F, "\" targetname: \"");
1854               PRINT_LOOPID(loop);
1855               fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
1856               loop_node_started = 0;
1857             }
1858           dump_loop_son_edge(loop, son_number++);
1859           dump_loops_standalone(son);
1860         }
1861       else
1862         {
1863           /* We are a loop node -> Collect firm nodes */
1864
1865           ir_node *n = le.node;
1866
1867           if (!loop_node_started)
1868             {
1869               /* Start a new node which contains all firm nodes of the current loop */
1870               fprintf (F, "node: { title: \"");
1871               PRINT_LOOPID(loop);
1872               fprintf (F, "-%d-nodes\" color: lightyellow label: \"", i);
1873               loop_node_started = 1;
1874               first = i;
1875             }
1876           else
1877             fprintf(F, "\n");
1878
1879           dump_node_opcode(n);
1880           dump_node_mode (n);
1881           dump_node_typeinfo(n);
1882           fprintf (F, " ");
1883           dump_node_nodeattr(n);
1884           fprintf (F, " %ld", get_irn_node_nr(n));
1885
1886         }
1887     }
1888
1889   if(loop_node_started)
1890     {
1891       fprintf(F, "\" }\n");
1892       fprintf (F, "edge: {sourcename: \"");
1893       PRINT_LOOPID(loop);
1894       fprintf (F, "\" targetname: \"");
1895       PRINT_LOOPID(loop);
1896       fprintf (F, "-%d-nodes\" label:\"%d...%d\"}\n", first, first, i-1);
1897       loop_node_started = 0;
1898     }
1899 }
1900
1901 void dump_loop_tree(ir_graph *irg, char *suffix)
1902 {
1903   ir_graph *rem = current_ir_graph;
1904   int el_rem = edge_label;
1905   edge_label = 1;
1906
1907   current_ir_graph = irg;
1908
1909   vcg_open(irg, suffix, "-looptree");
1910   dump_vcg_header(get_irg_dump_name(irg), "top_to_bottom");
1911
1912   if (get_irg_loop(irg)) dump_loops_standalone(get_irg_loop(irg));
1913
1914   vcg_close();
1915
1916   edge_label = el_rem;
1917   current_ir_graph = rem;
1918 }
1919
1920
1921 /*******************************************************************************/
1922 /* Dumps the firm nodes in the loop tree to a graph along with the loop nodes. */
1923 /*******************************************************************************/
1924
1925 void collect_nodeloop(ir_loop *loop, eset *loopnodes) {
1926   int i, son_number = 0, node_number = 0;
1927
1928   if (dump_loop_information_flag) dump_loop_node(loop);
1929
1930   for (i = 0; i < get_loop_n_elements(loop); i++) {
1931     loop_element le = get_loop_element(loop, i);
1932     if (*(le.kind) == k_ir_loop) {
1933       if (dump_loop_information_flag) dump_loop_son_edge(loop, son_number++);
1934       /* Recur */
1935       collect_nodeloop(le.son, loopnodes);
1936     } else {
1937       if (dump_loop_information_flag) dump_loop_node_edge(loop, node_number++);
1938       eset_insert(loopnodes, le.node);
1939     }
1940   }
1941 }
1942
1943 void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, eset *extnodes) {
1944   int i, j, start;
1945
1946   for(i = 0; i < get_loop_n_elements(loop); i++) {
1947     loop_element le = get_loop_element(loop, i);
1948     if (*(le.kind) == k_ir_loop) {
1949       /* Recur */
1950       collect_nodeloop_external_nodes(le.son, loopnodes, extnodes);
1951     } else {
1952       if (is_Block(le.node)) start = 0; else start = -1;
1953       for (j = start; j < get_irn_arity(le.node); j++) {
1954         ir_node *pred = get_irn_n(le.node, j);
1955         if (!eset_contains(loopnodes, pred)) {
1956           eset_insert(extnodes, pred);
1957           if (!is_Block(pred)) {
1958             pred = get_nodes_block(pred);
1959             if (!eset_contains(loopnodes, pred)) eset_insert(extnodes, pred);
1960           }
1961         }
1962       }
1963     }
1964   }
1965 }
1966
1967 void dump_loop (ir_loop *l, char *suffix) {
1968   char name[50];
1969   eset *loopnodes = eset_create();
1970   eset *extnodes = eset_create();
1971   ir_node *n, *b;
1972
1973   sprintf(name, "loop_%d", get_loop_loop_nr(l));
1974   vcg_open_name (name, suffix);
1975   dump_vcg_header(name, NULL);
1976
1977   /* collect all nodes to dump */
1978   collect_nodeloop(l, loopnodes);
1979   collect_nodeloop_external_nodes(l, loopnodes, extnodes);
1980
1981   /* build block lists */
1982   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
1983     set_irn_link(n, NULL);
1984   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
1985     set_irn_link(n, NULL);
1986   for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes))
1987     if (!is_Block(n)) {
1988       b = get_nodes_block(n);
1989       set_irn_link(n, get_irn_link(b));
1990       set_irn_link(b, n);
1991     }
1992   for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes))
1993     if (!is_Block(n)) {
1994       b = get_nodes_block(n);
1995       set_irn_link(n, get_irn_link(b));
1996       set_irn_link(b, n);
1997     }
1998
1999   for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes))
2000     if (is_Block(b)) {
2001       fprintf(F, "graph: { title: \"");
2002       PRINT_NODEID(b);
2003       fprintf(F, "\"  label: \"");
2004       dump_node_opcode(b);
2005       fprintf (F, " %ld", get_irn_node_nr(b));
2006       fprintf(F, "\" status:clustered color:yellow\n");
2007
2008       /* dump the blocks edges */
2009       dump_ir_data_edges(b);
2010
2011       /* dump the nodes that go into the block */
2012       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2013         if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue";
2014         dump_node(n);
2015         overrule_nodecolor = NULL;
2016         if (!eset_contains(extnodes, n)) dump_ir_data_edges(n);
2017       }
2018
2019       /* Close the vcg information for the block */
2020       fprintf(F, "}\n");
2021       dump_const_node_local(b);
2022       fprintf(F, "\n");
2023     }
2024   for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes))
2025     if (is_Block(b)) {
2026       fprintf(F, "graph: { title: \"");
2027       PRINT_NODEID(b);
2028       fprintf(F, "\"  label: \"");
2029       dump_node_opcode(b);
2030       fprintf (F, " %ld", get_irn_node_nr(b));
2031       fprintf(F, "\" status:clustered color:lightblue\n");
2032
2033       /* dump the nodes that go into the block */
2034       for (n = get_irn_link(b); n; n = get_irn_link(n)) {
2035         if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue";
2036         dump_node(n);
2037         overrule_nodecolor = NULL;
2038         if (eset_contains(loopnodes, n)) dump_ir_data_edges(n);
2039       }
2040
2041       /* Close the vcg information for the block */
2042       fprintf(F, "}\n");
2043       dump_const_node_local(b);
2044       fprintf(F, "\n");
2045     }
2046
2047   eset_destroy(loopnodes);
2048   eset_destroy(extnodes);
2049   vcg_close();
2050 }