BugFix r19562: get_nodes_block(skip_Proj(get_irn_n(n,i))) is subtile
[libfirm] / ir / ir / irdump.c
index a3873d1..3536085 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -39,8 +39,8 @@
 
 #include "list.h"
 
-#include "irnode.h"
-#include "irgraph.h"
+#include "irnode_t.h"
+#include "irgraph_t.h"
 #include "irprog_t.h"
 #include "entity_t.h"
 #include "irop.h"
@@ -75,7 +75,7 @@ typedef unsigned long SeqNo;
 extern SeqNo get_Block_seqno(ir_node *n);
 #endif
 
-/** Dump only irgs with names that start with this string */
+/** Dump only irgs with names that start with this prefix. */
 static ident *dump_file_filter_id = NULL;
 
 #define ERROR_TXT       "<ERROR>"
@@ -98,10 +98,14 @@ static int dump_ld_name = 1;
 static int dump_out_edge_flag = 0;
 static int dump_loop_information_flag = 0;
 static int dump_backedge_information_flag = 1;
+/** An option to dump const-like nodes locally. */
 static int dump_const_local = 1;
+/** An option to dump the node index number. */
 static int dump_node_idx_labels = 0;
 /** An option to dump all graph anchors */
 static int dump_anchors = 0;
+/** An option to dump the macro block edges. */
+static int dump_macro_block_edges = 0;
 
 int dump_dominator_information_flag = 0;
 int opt_dump_analysed_type_info = 1;
@@ -155,10 +159,10 @@ void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook) {
        dump_edge_vcgattr_hook = hook;
 }
 
-/* Returns 0 if dump_out_edge_flag or dump_loop_information_flag
+/** Returns 0 if dump_out_edge_flag or dump_loop_information_flag
  * are set, else returns dump_const_local_flag.
  */
-int get_opt_dump_const_local(void) {
+static int get_opt_dump_const_local(void) {
        if (dump_out_edge_flag || dump_loop_information_flag || (dump_new_edges_flag && edges_activated(current_ir_graph)))
                return 0;
        return dump_const_local;
@@ -246,11 +250,15 @@ void dump_all_anchors(int flag) {
        dump_anchors = flag;
 }
 
+void dump_macroblock_edges(int flag) {
+       dump_macro_block_edges = flag;
+}
+
 /* -------------- some extended helper functions ----------------- */
 
 /**
- * returns the name of a mode or <ERROR> if mode is NOT a mode object.
- * in the later case, sets bad
+ * returns the name of a mode or ERROR_TXT if mode is NOT a mode object.
+ * in the later case, sets bad.
  */
 const char *get_mode_name_ex(ir_mode *mode, int *bad) {
        if (is_mode(mode))
@@ -629,13 +637,13 @@ static ir_node **construct_block_lists(ir_graph *irg) {
 #ifdef INTERPROCEDURAL_VIEW
        int      rem_view  = get_interprocedural_view();
 #endif
-       int      walk_flag = using_visited(irg);
+       int      walk_flag = using_irn_visited(irg);
        ir_graph *rem      = current_ir_graph;
 
        current_ir_graph = irg;
 
        if(walk_flag)
-               clear_using_visited(current_ir_graph);
+               clear_using_irn_visited(current_ir_graph);
 
        for (i = get_irp_n_irgs() - 1; i >= 0; --i)
                ird_set_irg_link(get_irp_irg(i), NULL);
@@ -657,7 +665,7 @@ static ir_node **construct_block_lists(ir_graph *irg) {
 #endif
 
        if(walk_flag)
-               set_using_visited(current_ir_graph);
+               set_using_irn_visited(current_ir_graph);
 
        current_ir_graph = rem;
        return ird_get_irg_link(irg);
@@ -794,8 +802,8 @@ int dump_node_opcode(FILE *F, ir_node *n)
                ir_entity *ent = NULL;
                if (get_irn_op(addr) == op_Sel)
                        ent = get_Sel_entity(addr);
-               else if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind(addr) == symconst_addr_ent))
-                       ent = get_SymConst_entity(addr);
+               else if (is_Global(addr))
+                       ent = get_Global_entity(addr);
                fprintf(F, "%s", get_irn_opname(n));
                if (ent) fprintf(F, " %s", get_entity_name(ent));
                break;
@@ -819,7 +827,10 @@ int dump_node_opcode(FILE *F, ir_node *n)
                fprintf(F, "%s", get_irn_opname(n));
                break;
        case iro_Div:
-               fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Div_resmode(n), &bad));
+               fprintf(F, "%s", get_irn_opname(n));
+               if (is_Div_remainderless(n))
+                       fprintf(F, "RL");
+               fprintf(F, "[%s]", get_mode_name_ex(get_Div_resmode(n), &bad));
                break;
        case iro_Mod:
                fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Mod_resmode(n), &bad));
@@ -911,7 +922,6 @@ static const pns_lookup_t start_lut[] = {
 #define X(a)    { pn_Start_##a, #a }
        X(X_initial_exec),
        X(P_frame_base),
-       X(P_globals),
        X(P_tls),
        X(T_args),
        X(P_value_arg_base)
@@ -1551,14 +1561,17 @@ static void print_edge_vcgattr(FILE *F, ir_node *from, int to) {
 
 /** dump edges to our inputs */
 static void dump_ir_data_edges(FILE *F, ir_node *n)  {
-       int i;
+       int i, num;
        unsigned long visited = get_irn_visited(n);
 
-       if ((get_irn_op(n) == op_End) && (!dump_keepalive))
+       if (!dump_keepalive && is_End(n)) {
+               /* the End node has only keep-alive edges */
                return;
+       }
 
        /* dump the dependency edges. */
-       for (i = 0; i < get_irn_deps(n); ++i) {
+       num = get_irn_deps(n);
+       for (i = 0; i < num; ++i) {
                ir_node *dep = get_irn_dep(n, i);
 
                if (dep) {
@@ -1577,8 +1590,9 @@ static void dump_ir_data_edges(FILE *F, ir_node *n)  {
                }
        }
 
-       for (i = 0; i < get_irn_arity(n); i++) {
-               ir_node * pred = get_irn_n(n, i);
+       num = get_irn_arity(n);
+       for (i = 0; i < num; i++) {
+               ir_node *pred = get_irn_n(n, i);
                assert(pred);
 
                if ((get_interprocedural_view() && get_irn_visited(pred) < visited))
@@ -1599,6 +1613,16 @@ static void dump_ir_data_edges(FILE *F, ir_node *n)  {
                print_edge_vcgattr(F, n, i);
                fprintf(F, "}\n");
        }
+
+       if (dump_macro_block_edges && is_Block(n)) {
+               ir_node *mb = get_Block_MacroBlock(n);
+               fprintf(F, "edge: {sourcename: \"");
+               PRINT_NODEID(n);
+               fprintf(F, "\" targetname: \"");
+               PRINT_NODEID(mb);
+               fprintf(F, "\" label: \"mb\" " MACROBLOCK_EDGE_ATTR);
+               fprintf(F, "}\n");
+       }
 }
 
 /**
@@ -1626,19 +1650,15 @@ dump_ir_edges(FILE *F, ir_node *n) {
 }
 
 
-/** Dumps a node and its edges but not the block edge
- */
-static void
-dump_node_wo_blockedge(ir_node *n, void *env) {
+/** Dumps a node and its edges but not the block edge  */
+static void dump_node_wo_blockedge(ir_node *n, void *env) {
        FILE *F = env;
        dump_node(F, n);
        dump_ir_data_edges(F, n);
 }
 
-/** Dumps a node and its edges.
- */
-static void
-dump_whole_node(ir_node *n, void *env) {
+/** Dumps a node and its edges. */
+static void dump_whole_node(ir_node *n, void *env) {
        FILE *F = env;
        dump_node_wo_blockedge(n, env);
        if (!node_floats(n))
@@ -1647,8 +1667,8 @@ dump_whole_node(ir_node *n, void *env) {
                dump_ir_edges(F, n);
 }
 
-static void
-dump_const_node(ir_node *n, void *env) {
+/** Dumps a const-like node. */
+static void dump_const_node(ir_node *n, void *env) {
        if (is_Block(n)) return;
        dump_node_wo_blockedge(n, env);
 }
@@ -2269,25 +2289,21 @@ void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) {
 /**
  * dumps the VCG header
  */
-void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
+void dump_vcg_header(FILE *F, const char *name, const char *layout, const char *orientation) {
        int   i;
        char *label;
 
        init_colors();
 
-       if (edge_label) {
-               label = "yes";
-       } else {
-               label = "no";
-       }
-
+       label = edge_label ? "yes" : "no";
+       if (! layout)     layout = "Compilergraph";
        if (!orientation) orientation = "bottom_to_top";
 
        /* print header */
        fprintf(F,
                "graph: { title: \"ir graph of %s\"\n"
                "display_edge_labels: %s\n"
-               "layoutalgorithm: mindepth\n"
+               "layoutalgorithm: mindepth //$ \"%s\"\n"
                "manhattan_edges: yes\n"
                "port_sharing: no\n"
                "orientation: %s\n"
@@ -2312,13 +2328,14 @@ void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
                "classname 19: \"Postdominators\"\n"
                "classname 20: \"Keep Alive\"\n"
                "classname 21: \"Out Edges\"\n"
+               "classname 22: \"Macro Block Edges\"\n"
                "infoname 1: \"Attribute\"\n"
                "infoname 2: \"Verification errors\"\n"
                "infoname 3: \"Debug info\"\n",
-               name, label, orientation);
+               name, label, layout, orientation);
 
        for (i = 0; i < ird_color_count; ++i) {
-               if(color_rgb[i] != NULL) {
+               if (color_rgb[i] != NULL) {
                        fprintf(F, "colorentry %s: %s\n", color_names[i], color_rgb[i]);
                }
        }
@@ -2417,18 +2434,10 @@ FILE *vcg_open_name(const char *name, const char *suffix) {
 /**
  * Dumps the vcg file footer
  */
-static void dump_vcg_footer(FILE *F) {
+void dump_vcg_footer(FILE *F) {
        fprintf(F, "}\n");
 }
 
-/**
- * close the vcg file
- */
-void vcg_close(FILE *F) {
-       dump_vcg_footer(F);    /* print footer */
-       fclose (F);           /* close vcg file */
-}
-
 /************************************************************************/
 /************************************************************************/
 /* Routines that dump all or parts of the firm representation to a file */
@@ -2439,237 +2448,227 @@ void vcg_close(FILE *F) {
 /* Dump ir graphs, different formats and additional information.        */
 /************************************************************************/
 
-/** Routine to dump a graph, blocks as conventional nodes.  */
-void
-dump_ir_graph(ir_graph *irg, const char *suffix )
+typedef void (*do_dump_graph_func) (ir_graph *irg, FILE *out);
+
+static void do_dump(ir_graph *irg, const char *suffix, const char *suffix_ip,
+                    const char *suffix_nonip, do_dump_graph_func dump_func)
 {
-       FILE *f;
-       ir_graph *rem;
-       char *suffix1;
+       FILE       *out;
+       ir_graph   *rem;
+       const char *suffix1;
 
        if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
                return;
 
-       if (dump_backedge_information_flag && get_irg_loopinfo_state(irg) != loopinfo_consistent) {
-               construct_backedges(irg);
-       }
-
        rem = current_ir_graph;
        current_ir_graph = irg;
-       if (get_interprocedural_view()) suffix1 = "-pure-ip";
-       else                            suffix1 = "-pure";
-       f = vcg_open(irg, suffix, suffix1);
-       if (f != NULL) {
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+       if (get_interprocedural_view())
+               suffix1 = suffix_ip;
+       else
+               suffix1 = suffix_nonip;
+       current_ir_graph = rem;
 
-               /* call the dump graph hook */
-               if (dump_ir_graph_hook)
-                       if (dump_ir_graph_hook(f, irg)) {
-                               current_ir_graph = rem;
-                               return;
-                       }
+       out = vcg_open(irg, suffix, suffix1);
+       if (out != NULL) {
+               dump_func(irg, out);
+               fclose(out);
+       }
+}
 
-                       /* walk over the graph */
-                       /* dump_whole_node must be called in post visiting predecessors */
-                       ird_walk_graph(irg, NULL, dump_whole_node, f);
+void dump_ir_graph_file(ir_graph *irg, FILE *out)
+{
+       if (dump_backedge_information_flag
+                       && get_irg_loopinfo_state(irg) != loopinfo_consistent) {
+               construct_backedges(irg);
+       }
 
-                       /* dump the out edges in a separate walk */
-                       if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
-                               irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, f);
-                       }
+       dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL);
+
+       /* call the dump graph hook */
+       if (dump_ir_graph_hook) {
+               if (dump_ir_graph_hook(out, irg)) {
+                       return;
+               }
+       }
 
-                       vcg_close(f);
+       /* walk over the graph */
+       /* dump_whole_node must be called in post visiting predecessors */
+       ird_walk_graph(irg, NULL, dump_whole_node, out);
+
+       /* dump the out edges in a separate walk */
+       if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) {
+               irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, out);
        }
-       current_ir_graph = rem;
+
+       dump_vcg_footer(out);
 }
 
-/* Dump a firm graph without explicit block nodes. */
-void dump_ir_block_graph(ir_graph *irg, const char *suffix)
+/** Routine to dump a graph, blocks as conventional nodes.  */
+void dump_ir_graph(ir_graph *irg, const char *suffix )
 {
-       FILE *f;
-       int i;
-       char *suffix1;
-
-       if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
-               return;
+       do_dump(irg, suffix, "-pure-ip", "-pure", dump_ir_graph_file);
+}
 
-       if (get_interprocedural_view()) suffix1 = "-ip";
-       else                            suffix1 = "";
-       f = vcg_open(irg, suffix, suffix1);
+void dump_ir_block_graph_file(ir_graph *irg, FILE *out)
+{
+       int i;
 
-       if (f != NULL) {
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+       dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL);
 
-               construct_block_lists(irg);
+       construct_block_lists(irg);
 
-               /*
-                * If we are in the interprocedural view, we dump not
-                * only the requested irg but also all irgs that can be reached
-                * from irg.
-                */
-               for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
-                       ir_graph *g = get_irp_irg(i);
-                       ir_node **arr = ird_get_irg_link(g);
-                       if (arr) {
-                               dump_graph_from_list(f, g);
-                               DEL_ARR_F(arr);
-                       }
+       /*
+        * If we are in the interprocedural view, we dump not
+        * only the requested irg but also all irgs that can be reached
+        * from irg.
+        */
+       for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
+               ir_graph *g = get_irp_irg(i);
+               ir_node **arr = ird_get_irg_link(g);
+               if (arr) {
+                       dump_graph_from_list(out, g);
+                       DEL_ARR_F(arr);
                }
-
-               vcg_close(f);
        }
+
+       dump_vcg_footer(out);
 }
 
-/* Dump a firm graph without explicit block nodes but grouped in extended blocks. */
-void dump_ir_extblock_graph(ir_graph *irg, const char *suffix)
+/* Dump a firm graph without explicit block nodes. */
+void dump_ir_block_graph(ir_graph *irg, const char *suffix)
 {
-       FILE *F;
-       int i;
-       char *suffix1;
-       ir_entity *ent;
+       do_dump(irg, suffix, "-ip", "", dump_ir_block_graph_file);
+}
 
-       if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
-               return;
+void dump_ir_extblock_graph_file(ir_graph *irg, FILE *F)
+{
+       int        i;
+       ir_entity *ent = get_irg_entity(irg);
 
        if (get_irg_extblk_state(irg) != extblk_valid)
                compute_extbb(irg);
 
-       if (get_interprocedural_view()) suffix1 = "-ip";
-       else                            suffix1 = "";
-
-       ent = get_irg_entity(irg);
-
-       F = vcg_open(irg, suffix, suffix1);
-       if (F != NULL) {
-               dump_vcg_header(F, get_irg_dump_name(irg), NULL);
+       dump_vcg_header(F, get_irg_dump_name(irg), NULL, NULL);
 
-               construct_extblock_lists(irg);
+       construct_extblock_lists(irg);
 
-               fprintf(F, "graph: { title: \"");
-               PRINT_IRGID(irg);
-               fprintf(F, "\" label: \"%s\" status:clustered color: white \n",
-                       get_ent_dump_name(ent));
+       fprintf(F, "graph: { title: \"");
+       PRINT_IRGID(irg);
+       fprintf(F, "\" label: \"%s\" status:clustered color: white \n",
+               get_ent_dump_name(ent));
 
-               dump_graph_info(F, irg);
-               print_dbg_info(F, get_entity_dbg_info(ent));
+       dump_graph_info(F, irg);
+       print_dbg_info(F, get_entity_dbg_info(ent));
 
-               for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
-                       ir_graph *irg     = get_irp_irg(i);
-                       list_tuple *lists = ird_get_irg_link(irg);
-
-                       if (lists) {
-                               /* dump the extended blocks first */
-                               if (ARR_LEN(lists->extbb_list)) {
-                                       ird_set_irg_link(irg, lists->extbb_list);
-                                       dump_extblock_graph(F, irg);
-                               }
+       for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
+               ir_graph *irg     = get_irp_irg(i);
+               list_tuple *lists = ird_get_irg_link(irg);
 
-                               /* we may have blocks without extended blocks, bad for instance */
-                               if (ARR_LEN(lists->blk_list)) {
-                                       ird_set_irg_link(irg, lists->blk_list);
-                                       dump_block_graph(F, irg);
-                               }
+               if (lists) {
+                       /* dump the extended blocks first */
+                       if (ARR_LEN(lists->extbb_list)) {
+                               ird_set_irg_link(irg, lists->extbb_list);
+                               dump_extblock_graph(F, irg);
+                       }
 
-                               DEL_ARR_F(lists->extbb_list);
-                               DEL_ARR_F(lists->blk_list);
-                               xfree(lists);
+                       /* we may have blocks without extended blocks, bad for instance */
+                       if (ARR_LEN(lists->blk_list)) {
+                               ird_set_irg_link(irg, lists->blk_list);
+                               dump_block_graph(F, irg);
                        }
+
+                       DEL_ARR_F(lists->extbb_list);
+                       DEL_ARR_F(lists->blk_list);
+                       xfree(lists);
                }
+       }
 
-               /* Close the vcg information for the irg */
-               fprintf(F, "}\n\n");
+       /* Close the vcg information for the irg */
+       fprintf(F, "}\n\n");
 
-               vcg_close(F);
-               free_extbb(irg);
-       }
+       dump_vcg_footer(F);
+       free_extbb(irg);
 }
 
-/* dumps a graph with type information */
-void
-dump_ir_graph_w_types(ir_graph *irg, const char *suffix)
+/* Dump a firm graph without explicit block nodes but grouped in extended blocks. */
+void dump_ir_extblock_graph(ir_graph *irg, const char *suffix)
 {
-       FILE *f;
-       char *suffix1;
-
-       /* if a filter is set, dump only the irg's that match the filter */
-       if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
-               return;
+       do_dump(irg, suffix, "-ip", "", dump_ir_extblock_graph_file);
+}
 
-       if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
-       else                            suffix1 = "-pure-wtypes";
-       f = vcg_open(irg,suffix, suffix1);
-       if (f != NULL) {
-               ir_graph *rem = current_ir_graph;
-               int rem_dump_const_local;
+void dump_ir_graph_w_types_file(ir_graph *irg, FILE *out)
+{
+       ir_graph *rem = current_ir_graph;
+       int       rem_dump_const_local;
 
-               current_ir_graph = irg;
-               rem_dump_const_local = dump_const_local;
-               /* dumping types does not work with local nodes */
-               dump_const_local = 0;
+       rem                  = current_ir_graph;
+       current_ir_graph     = irg;
+       rem_dump_const_local = dump_const_local;
+       /* dumping types does not work with local nodes */
+       dump_const_local = 0;
 
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+       dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL);
 
-               /* dump common ir graph */
-               irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
-               /* dump type info */
-               type_walk_irg(irg, dump_type_info, NULL, f);
-               inc_irg_visited(get_const_code_irg());
-               /* dump edges from graph to type info */
-               irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
+       /* dump common ir graph */
+       irg_walk(get_irg_end(irg), NULL, dump_whole_node, out);
+       /* dump type info */
+       type_walk_irg(irg, dump_type_info, NULL, out);
+       inc_irg_visited(get_const_code_irg());
+       /* dump edges from graph to type info */
+       irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, out);
 
-               vcg_close(f);
-               dump_const_local = rem_dump_const_local;
-               current_ir_graph = rem;
-       }
+       dump_vcg_footer(out);
+       dump_const_local = rem_dump_const_local;
+       current_ir_graph = rem;
 }
 
-void
-dump_ir_block_graph_w_types(ir_graph *irg, const char *suffix)
+/* dumps a graph with type information */
+void dump_ir_graph_w_types(ir_graph *irg, const char *suffix)
 {
-       FILE *f;
-       int i;
-       char *suffix1;
-
-       /* if a filter is set, dump only the irg's that match the filter */
-       if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
-               return;
+       do_dump(irg, suffix, "-pure-wtypes-ip", "-pure-wtypes",
+               dump_ir_graph_w_types_file);
+}
 
-       if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
-       else                            suffix1 = "-wtypes";
-       f = vcg_open(irg, suffix, suffix1);
-       if (f != NULL) {
-               ir_graph *rem = current_ir_graph;
-               int rem_dump_const_local;
+void dump_ir_block_graph_w_types_file(ir_graph *irg, FILE *out)
+{
+       int       i;
+       int       rem_dump_const_local;
+       ir_graph *rem = current_ir_graph;
 
-               rem_dump_const_local = dump_const_local;
-               /* dumping types does not work with local nodes */
-               dump_const_local = 0;
+       rem_dump_const_local = dump_const_local;
+       /* dumping types does not work with local nodes */
+       dump_const_local = 0;
 
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+       dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL);
 
-               /* dump common blocked ir graph */
-               construct_block_lists(irg);
+       /* dump common blocked ir graph */
+       construct_block_lists(irg);
 
-               for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
-                       ir_node **arr = ird_get_irg_link(get_irp_irg(i));
-                       if (arr) {
-                               dump_graph_from_list(f, get_irp_irg(i));
-                               DEL_ARR_F(arr);
-                       }
+       for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
+               ir_node **arr = ird_get_irg_link(get_irp_irg(i));
+               if (arr) {
+                       dump_graph_from_list(out, get_irp_irg(i));
+                       DEL_ARR_F(arr);
                }
+       }
 
-               /* dump type info */
-               current_ir_graph = irg;
-               type_walk_irg(irg, dump_type_info, NULL, f);
-               inc_irg_visited(get_const_code_irg());
+       /* dump type info */
+       current_ir_graph = irg;
+       type_walk_irg(irg, dump_type_info, NULL, out);
+       inc_irg_visited(get_const_code_irg());
 
-               /* dump edges from graph to type info */
-               irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
+       /* dump edges from graph to type info */
+       irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, out);
 
-               vcg_close(f);
-               dump_const_local = rem_dump_const_local;
-               current_ir_graph = rem;
-       }
+       dump_vcg_footer(out);
+       dump_const_local = rem_dump_const_local;
+       current_ir_graph = rem;
+}
+
+void dump_ir_block_graph_w_types(ir_graph *irg, const char *suffix)
+{
+       do_dump(irg, suffix, "-wtypes-ip", "-wtypes",
+               dump_ir_block_graph_w_types_file);
 }
 
 /*---------------------------------------------------------------------*/
@@ -2746,8 +2745,7 @@ dump_block_to_cfg(ir_node *block, void *env) {
        }
 }
 
-void
-dump_cfg(ir_graph *irg, const char *suffix)
+void dump_cfg(ir_graph *irg, const char *suffix)
 {
        FILE *f;
        /* if a filter is set, dump only the irg's that match the filter */
@@ -2762,7 +2760,7 @@ dump_cfg(ir_graph *irg, const char *suffix)
 #endif
 
                current_ir_graph = irg;
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+               dump_vcg_header(f, get_irg_dump_name(irg), NULL, NULL);
 
 #ifdef INTERPROCEDURAL_VIEW
                if (ipv) {
@@ -2778,7 +2776,8 @@ dump_cfg(ir_graph *irg, const char *suffix)
 #ifdef INTERPROCEDURAL_VIEW
                set_interprocedural_view(ipv);
 #endif
-               vcg_close(f);
+               dump_vcg_footer(f);
+               fclose(f);
                current_ir_graph = rem;
        }
 }
@@ -2810,9 +2809,10 @@ void dump_subgraph(ir_node *root, int depth, const char *suffix) {
        F = vcg_open(get_irn_irg(root), suffix, buf);
        if (F != NULL) {
                pset *mark_set = pset_new_ptr(1);
-               dump_vcg_header(F, get_irg_dump_name(get_irn_irg(root)), NULL);
+               dump_vcg_header(F, get_irg_dump_name(get_irn_irg(root)), NULL, NULL);
                descend_and_dump(F, root, depth, mark_set);
-               vcg_close(F);
+               dump_vcg_footer(F);
+               fclose(F);
                del_pset(mark_set);
        }
 }
@@ -2852,7 +2852,8 @@ void dump_callgraph(const char *suffix) {
                }
 
                edge_label = rem;
-               vcg_close(F);
+               dump_vcg_footer(F);
+               fclose(F);
        }
 }
 
@@ -2881,7 +2882,8 @@ void dump_all_cg_block_graph(const char *suffix) {
                        DEL_ARR_F(ird_get_irg_link(current_ir_graph));
                }
 
-               vcg_close(f);
+               dump_vcg_footer(f);
+               fclose(f);
                set_interprocedural_view(rem_view);
        }
 }
@@ -2904,7 +2906,7 @@ dump_type_graph(ir_graph *irg, const char *suffix)
                ir_graph *rem = current_ir_graph;
                current_ir_graph = irg;
 
-               dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+               dump_vcg_header(f, get_irg_dump_name(irg), "Hierarchic", NULL);
 
                /* walk over the blocks in the graph */
                type_walk_irg(irg, dump_type_info, NULL, f);
@@ -2914,7 +2916,8 @@ dump_type_graph(ir_graph *irg, const char *suffix)
                   walk.  So now increase it finally. */
                inc_irg_visited(get_const_code_irg());
 
-               vcg_close(f);
+               dump_vcg_footer(f);
+               fclose(f);
                current_ir_graph = rem;
        }
 }
@@ -2924,10 +2927,12 @@ dump_all_types(const char *suffix)
 {
        FILE *f = vcg_open_name("All_types", suffix);
        if (f) {
-               dump_vcg_header(f, "All_types", NULL);
+               dump_vcg_header(f, "All_types", "Hierarchic", NULL);
                type_walk(dump_type_info, NULL, f);
                inc_irg_visited(get_const_code_irg());
-               vcg_close(f);
+
+               dump_vcg_footer(f);
+               fclose(f);
        }
 }
 
@@ -2940,9 +2945,11 @@ dump_class_hierarchy(int entities, const char *suffix)
                h_env_t env;
                env.f        = f;
                env.dump_ent = entities;
-               dump_vcg_header(f, "class_hierarchy", NULL);
+               dump_vcg_header(f, "class_hierarchy", "Hierarchic", NULL);
                type_walk(dump_class_hierarchy_node, NULL, &env);
-               vcg_close(f);
+
+               dump_vcg_footer(f);
+               fclose(f);
        }
 }
 
@@ -2976,15 +2983,14 @@ void dump_loops_standalone(FILE *F, ir_loop *loop) {
        dump_loop_node(F, loop);
 
        /* Dump the loop elements. */
-
-       for(i = 0; i < get_loop_n_elements(loop); i++) {
+       for (i = 0; i < get_loop_n_elements(loop); i++) {
                le = get_loop_element(loop, i);
                son = le.son;
                if (get_kind(son) == k_ir_loop) {
 
                        /* We are a loop son -> Recurse */
 
-                       if(loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
+                       if (loop_node_started) { /* Close the "firm-nodes" node first if we started one. */
                                fprintf(F, "\" }\n");
                                fprintf(F, "edge: {sourcename: \"");
                                PRINT_LOOPID(loop);
@@ -3019,7 +3025,7 @@ void dump_loops_standalone(FILE *F, ir_loop *loop) {
                        assert(get_kind(son) == k_ir_graph);
 
                        /* We are a loop node -> Collect firm graphs */
-                       n = (ir_graph *)le.node;
+                       n = le.irg;
                        if (!loop_node_started) {
                                /* Start a new node which contains all firm nodes of the current loop */
                                fprintf(F, "node: { title: \"");
@@ -3060,11 +3066,13 @@ void dump_loop_tree(ir_graph *irg, const char *suffix)
                current_ir_graph = irg;
                edge_label = 1;
 
-               dump_vcg_header(f, get_irg_dump_name(irg), "top_to_bottom");
+               dump_vcg_header(f, get_irg_dump_name(irg), "Tree", "top_to_bottom");
 
-               if (get_irg_loop(irg)) dump_loops_standalone(f, get_irg_loop(irg));
+               if (get_irg_loop(irg))
+                       dump_loops_standalone(f, get_irg_loop(irg));
 
-               vcg_close(f);
+               dump_vcg_footer(f);
+               fclose(f);
 
                edge_label = el_rem;
                current_ir_graph = rem;
@@ -3074,9 +3082,10 @@ void dump_loop_tree(ir_graph *irg, const char *suffix)
 void dump_callgraph_loop_tree(const char *suffix) {
        FILE *F;
        F = vcg_open_name("Callgraph_looptree", suffix);
-       dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
+       dump_vcg_header(F, "callgraph looptree", "Tree", "top_to_bottom");
        dump_loops_standalone(F, irp->outermost_cg_loop);
-       vcg_close(F);
+       dump_vcg_footer(F);
+       fclose(F);
 }
 
 
@@ -3137,7 +3146,7 @@ void dump_loop(ir_loop *l, const char *suffix) {
                eset *extnodes = eset_create();
                ir_node *n, *b;
 
-               dump_vcg_header(F, name, NULL);
+               dump_vcg_header(F, name, NULL, NULL);
 
                /* collect all nodes to dump */
                collect_nodeloop(F, l, loopnodes);
@@ -3216,6 +3225,8 @@ void dump_loop(ir_loop *l, const char *suffix) {
                }
                eset_destroy(loopnodes);
                eset_destroy(extnodes);
-               vcg_close(F);
+
+               dump_vcg_footer(F);
+               fclose(F);
        }
 }