remove support for schedule preparation steps (both are unmaintained and broken)
authorMatthias Braun <matze@braunis.de>
Wed, 2 Mar 2011 13:46:26 +0000 (14:46 +0100)
committerMatthias Braun <matze@braunis.de>
Fri, 4 Mar 2011 13:17:12 +0000 (14:17 +0100)
ir/be/be_types.h
ir/be/belistsched.c
ir/be/bemain.c
ir/be/bemodule.c
ir/be/beschedmris.c [deleted file]
ir/be/beschedmris.h [deleted file]
ir/be/beschedrss.c [deleted file]
ir/be/beschedrss.h [deleted file]

index 8b9f424..a49b467 100644 (file)
@@ -67,11 +67,6 @@ typedef struct be_stack_layout_t        be_stack_layout_t;
 
 typedef struct be_dom_front_info_t      be_dom_front_info_t;
 
-typedef struct list_sched_selector_t    list_sched_selector_t;
-
-typedef struct ilp_sched_selector_t     ilp_sched_selector_t;
-typedef struct ilp_sched_selector_if_t  ilp_sched_selector_if_t;
-
 typedef struct be_execution_unit_type_t be_execution_unit_type_t;
 typedef struct be_execution_unit_t      be_execution_unit_t;
 typedef struct be_machine_t             be_machine_t;
index 5318bd2..8b1a3a7 100644 (file)
@@ -53,8 +53,6 @@
 #include "beutil.h"
 #include "belive_t.h"
 #include "belistsched.h"
-#include "beschedmris.h"
-#include "beschedrss.h"
 #include "bearch.h"
 #include "bestat.h"
 #include "beirg.h"
@@ -82,12 +80,10 @@ enum {
 
 typedef struct list_sched_options_t {
        int select;  /**< the node selector */
-       int prep;    /**< schedule preparation */
 } list_sched_options_t;
 
 static list_sched_options_t list_sched_options = {
        BE_SCHED_SELECT_NORMAL,   /* mueller heuristic selector */
-       BE_SCHED_PREP_NONE,       /* no scheduling preparation */
 };
 
 /* schedule selector options. */
@@ -102,24 +98,11 @@ static const lc_opt_enum_int_items_t sched_select_items[] = {
        { NULL,       0 }
 };
 
-/* schedule preparation options. */
-static const lc_opt_enum_int_items_t sched_prep_items[] = {
-       { "none", BE_SCHED_PREP_NONE },
-       { "mris", BE_SCHED_PREP_MRIS },
-       { "rss",  BE_SCHED_PREP_RSS  },
-       { NULL,   0 }
-};
-
 static lc_opt_enum_int_var_t sched_select_var = {
        &list_sched_options.select, sched_select_items
 };
 
-static lc_opt_enum_int_var_t sched_prep_var = {
-       &list_sched_options.prep, sched_prep_items
-};
-
 static const lc_opt_table_entry_t list_sched_option_table[] = {
-       LC_OPT_ENT_ENUM_PTR("prep",   "schedule preparation",   &sched_prep_var),
        LC_OPT_ENT_ENUM_PTR("select", "node selector",          &sched_select_var),
        LC_OPT_LAST
 };
@@ -523,7 +506,6 @@ void list_sched(ir_graph *irg)
 {
        int num_nodes;
        sched_env_t env;
-       mris_env_t *mris = NULL;
        const list_sched_selector_t *selector;
 
        /* Select a scheduler based on backend options */
@@ -549,17 +531,6 @@ void list_sched(ir_graph *irg)
        edges_activate(irg);
 #endif
 
-       switch (list_sched_options.prep) {
-               case BE_SCHED_PREP_MRIS:
-                       mris = be_sched_mris_preprocess(irg);
-                       break;
-               case BE_SCHED_PREP_RSS:
-                       rss_schedule_preparation(irg);
-                       break;
-               default:
-                       break;
-       }
-
        num_nodes = get_irg_last_idx(irg);
 
        /* initialize environment for list scheduler */
@@ -578,9 +549,6 @@ void list_sched(ir_graph *irg)
        if (env.selector->finish_graph)
                env.selector->finish_graph(env.selector_env);
 
-       if (list_sched_options.prep == BE_SCHED_PREP_MRIS)
-               be_sched_mris_free(mris);
-
        DEL_ARR_F(env.sched_info);
 }
 
index 1ad8993..316d0cb 100644 (file)
@@ -68,7 +68,6 @@
 #include "bessadestr.h"
 #include "beabi.h"
 #include "belower.h"
-#include "beschedmris.h"
 #include "bestat.h"
 #include "beverify.h"
 #include "be_dbgout.h"
index 7ab51c7..d273755 100644 (file)
@@ -38,7 +38,6 @@ void be_init_blocksched(void);
 void be_init_spill(void);
 void be_init_spilloptions(void);
 void be_init_listsched(void);
-void be_init_schedrss(void);
 void be_init_chordal(void);
 void be_init_pbqp_coloring(void);
 void be_init_chordal_main(void);
@@ -99,7 +98,6 @@ void be_init_modules(void)
        be_init_spilloptions();
        be_init_dbgout();
        be_init_listsched();
-       be_init_schedrss();
        be_init_chordal_main();
        be_init_chordal_common();
        be_init_chordal();
diff --git a/ir/be/beschedmris.c b/ir/be/beschedmris.c
deleted file mode 100644 (file)
index f5eafdd..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief       Implements a list scheduler for the MRIS algorithm.
- * @author      Sebastian Hack
- * @date        04.04.2006
- * @version     $Id$
- *
- * Implements a list scheduler for the MRIS algorithm in:
- * Govindarajan, Yang, Amaral, Zhang, Gao
- * Minimum Register Instruction Sequencing to Reduce Register Spills
- * in out-of-order issue superscalar architectures
- */
-#include "config.h"
-
-#include <limits.h>
-
-#include "obst.h"
-#include "debug.h"
-
-#include "irgraph_t.h"
-#include "irnode_t.h"
-#include "iredges_t.h"
-#include "ircons_t.h"
-#include "irphase_t.h"
-#include "irdump_t.h"
-#include "irgwalk.h"
-#include "irtools.h"
-#include "irbitset.h"
-#include "irnodeset.h"
-#include "heights.h"
-
-#include "benode.h"
-#include "besched.h"
-#include "beschedmris.h"
-#include "beirg.h"
-#include "belistsched.h"
-
-struct mris_env_t {
-       ir_phase          ph;
-       ir_heights_t      *heights;
-       ir_graph          *irg;
-       ir_node           *bl;
-       int               visited;
-       struct list_head  lineage_head;
-       struct obstack    obst;
-       DEBUG_ONLY(firm_dbg_module_t *dbg;)
-};
-
-typedef struct mris_irn_t {
-       int visited;
-       ir_node *lineage_start;
-       ir_node *lineage_next;
-       ir_node *lineage_end;
-       struct list_head lineage_list;
-} mris_irn_t;
-
-#define to_appear(env, irn) (to_appear_in_schedule(irn) && get_nodes_block(irn) == env->bl)
-
-#define get_mris_irn(env, irn)   ((mris_irn_t *) phase_get_or_set_irn_data(&env->ph, irn))
-#define foreach_lineage(env, pos, tmp) list_for_each_entry_safe(mris_irn_t, pos, tmp, &(env)->lineage_head, lineage_list)
-
-static void *mris_irn_data_init(ir_phase *ph, const ir_node *irn)
-{
-       mris_irn_t *mi = (mris_irn_t*)phase_alloc(ph, sizeof(mi[0]));
-       (void) irn;
-       memset(mi, 0, sizeof(mi[0]));
-       INIT_LIST_HEAD(&mi->lineage_list);
-       return mi;
-}
-
-#define valid_node(env, dep) (to_appear(env, dep) && !be_is_Keep(dep))
-
-static void grow_all_descendands(mris_env_t *env, ir_node *irn, bitset_t *visited)
-{
-       const ir_edge_t *edge;
-
-       // assert(get_irn_mode(irn) != mode_T);
-
-       foreach_out_edge(irn, edge) {
-               ir_node *desc = get_edge_src_irn(edge);
-               if (valid_node(env, desc) && !bitset_contains_irn(visited, desc)) {
-                       obstack_ptr_grow(&env->obst, desc);
-                       bitset_add_irn(visited, desc);
-               }
-       }
-
-       foreach_out_edge_kind(irn, edge, EDGE_KIND_DEP) {
-               ir_node *desc = get_edge_src_irn(edge);
-               if (valid_node(env, desc) && !bitset_contains_irn(visited, desc)) {
-                       obstack_ptr_grow(&env->obst, desc);
-                       bitset_add_irn(visited, desc);
-               }
-       }
-}
-
-static ir_node **all_descendants(mris_env_t *env, ir_node *irn)
-{
-       bitset_t *visited = bitset_irg_malloc(env->irg);
-
-       grow_all_descendands(env, irn, visited);
-
-#if 0
-       if (get_irn_mode(irn) == mode_T) {
-               const ir_edge_t *edge;
-               foreach_out_edge(irn, edge) {
-                       ir_node *desc = get_edge_src_irn(edge);
-                       assert(is_Proj(desc) && get_irn_mode(desc) != mode_T);
-                       grow_all_descendands(env, desc, visited);
-               }
-       }
-
-       else
-               grow_all_descendands(env, irn, visited);
-#endif
-       bitset_free(visited);
-       obstack_ptr_grow(&env->obst, NULL);
-       return (ir_node**)obstack_finish(&env->obst);
-}
-
-static ir_node *put_lowest_in_front(mris_env_t *env, ir_node **in)
-{
-       int lowest_index       = 0;
-       unsigned lowest_height = INT_MAX;
-       int i;
-
-       for (i = 0; in[i]; ++i) {
-               unsigned height = get_irn_height(env->heights, in[i]);
-               if (height < lowest_height) {
-                       lowest_height = height;
-                       lowest_index  = i;
-               }
-       }
-
-       if (i > 0) {
-               ir_node *tmp     = in[0];
-               in[0]            = in[lowest_index];
-               in[lowest_index] = tmp;
-       }
-
-       return in[0];
-}
-
-static inline ir_node *skip_Projs(ir_node *irn)
-{
-       return is_Proj(irn) ? skip_Projs(get_Proj_pred(irn)) : irn;
-}
-
-static void lineage_formation(mris_env_t *env)
-{
-       DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg);
-       ir_nodeset_t                  nodes;
-       const ir_edge_t              *edge;
-
-       ir_nodeset_init(&nodes);
-
-       foreach_out_edge(env->bl, edge) {
-               ir_node *irn = get_edge_src_irn(edge);
-               if (to_appear(env, irn))
-                       ir_nodeset_insert(&nodes, irn);
-       }
-
-       while (ir_nodeset_size(&nodes) > 0) {
-               mris_irn_t *mi;
-               ir_node    *irn;
-               ir_node    *highest_node = NULL;
-               ir_node    *lowest_desc  = NULL;
-               ir_node    *start;
-               mris_irn_t *start_mi;
-               ir_nodeset_iterator_t iter;
-
-               ir_node **in;
-               int recompute_height  = 0;
-               unsigned  curr_height = 0;
-
-               /* search the highest node which is not yet in a lineage. */
-               foreach_ir_nodeset(&nodes, irn, iter) {
-                       unsigned height = get_irn_height(env->heights, irn);
-                       if (height > curr_height) {
-                               highest_node = irn;
-                               curr_height  = height;
-                       }
-               }
-
-               assert(highest_node);
-               DBG((dbg, LEVEL_2, "highest node is %+F height %d\n", highest_node, get_irn_height(env->heights, highest_node)));
-
-               start = highest_node;
-               mi = start_mi = get_mris_irn(env, highest_node);
-
-               /* start a lineage beginning with highest_node. */
-               mi->lineage_start = highest_node;
-               mi->lineage_next  = NULL;
-               mi->lineage_end   = NULL;
-               list_add(&mi->lineage_list, &env->lineage_head);
-               ir_nodeset_remove(&nodes, highest_node);
-
-               /*
-                       put all descendants in an array.
-                       we also move the lowest descendant in front, so that the other nodes
-                       are easily accessible as an array, too.
-               */
-               in          = all_descendants(env, highest_node);
-               lowest_desc = put_lowest_in_front(env, in);
-
-               /* as long as the current highest node has still descendants */
-               while (lowest_desc) {
-                       mris_irn_t *lowest_mi  = get_mris_irn(env, lowest_desc);
-                       mris_irn_t *highest_mi = get_mris_irn(env, highest_node);
-
-                       int n_desc;
-
-                       DBG((dbg, LEVEL_2, "\tlowest descendant %+F height %d\n", lowest_desc, get_irn_height(env->heights, lowest_desc)));
-
-                       /* count the number of all descendants which are not the lowest descendant */
-                       for (n_desc = 0; in[n_desc]; ++n_desc) {
-                       }
-
-                       /*
-                       we insert a CopyKeep node to express the artificial dependencies from the lowest
-                       descendant to all other descendants.
-                       */
-                       if (n_desc > 1 && !be_is_Keep(lowest_desc)) {
-                               ir_node *op;
-                               int i, n;
-
-                               for (i = 0, n = get_irn_ins_or_deps(lowest_desc); i < n; ++i) {
-                                       op = get_irn_in_or_dep(lowest_desc, i);
-                                       if (op == highest_node)
-                                               break;
-                               }
-
-                               assert(i < n && "could not find operand");
-
-                               //replace_tuple_by_repr_proj(env, &in[1]);
-                               if (!is_Proj(lowest_desc))
-                                       add_irn_dep(lowest_desc, in[1]);
-                       }
-                       obstack_free(&env->obst, in);
-
-                       /* if the current lowest node is not yet in a lineage, add it to the current one. */
-                       if (!lowest_mi->lineage_start) {
-                               /* mark the current lowest node as the last one in the lineage. */
-                               highest_mi->lineage_next = lowest_desc;
-                               start_mi->lineage_end    = lowest_desc;
-
-                               lowest_mi->lineage_start = start;
-                               ir_nodeset_remove(&nodes, lowest_desc);
-                       }
-
-                       /* else we cannot extend this lineage, so break. */
-                       else
-                               break;
-
-                       highest_node = lowest_desc;
-                       highest_mi   = lowest_mi;
-
-                       /* recompute the descendants array and the new lowest descendant. */
-                       in          = all_descendants(env, highest_node);
-                       lowest_desc = put_lowest_in_front(env, in);
-               }
-
-               /* recompute the heights if desired. */
-               if (recompute_height)
-                       heights_recompute(env->heights);
-       }
-
-       ir_nodeset_destroy(&nodes);
-}
-
-static int fuse_two_lineages(mris_env_t *env, mris_irn_t *u, mris_irn_t *v)
-{
-       mris_irn_t *mi;
-       ir_node *irn, *last;
-       ir_node *u_end   = u->lineage_end;
-       ir_node *v_start = v->lineage_start;
-       ir_node *start   = skip_Projs(v_start);
-
-       if (be_is_Keep(start))
-               return 0;
-
-       /* set lineage end of nodes in u to end of v. */
-       irn = last = u->lineage_start;
-       mi         = get_mris_irn(env, irn);
-       while (irn && irn != u_end) {
-               mi = get_mris_irn(env, irn);
-               mi->lineage_end = v->lineage_end;
-               last = irn;
-               irn = mi->lineage_next;
-       }
-
-       /* insert a CopyKeep to make lineage v dependent on u. */
-       if (get_irn_ins_or_deps(start) == 0)
-               return 0;
-
-       if (get_irn_mode(last) == mode_T) {
-               const ir_edge_t *edge = get_irn_out_edge_first(last);
-               last = get_edge_src_irn(edge);
-       }
-
-       /* irn now points to the last node in lineage u; mi has the info for the node _before_ the terminator of the lineage. */
-       mi->lineage_next       = v_start;
-
-       /* add a dependency from the first node in v's lineage to the last in u's */
-       add_irn_dep(u_end, v_start);
-
-       /* set lineage start of nodes in v to start of u. */
-       irn = v->lineage_start;
-       while (irn && irn != v->lineage_end) {
-               mris_irn_t *mi = get_mris_irn(env, irn);
-               mi->lineage_start = u->lineage_start;
-               irn = mi->lineage_next;
-       }
-
-       heights_recompute(env->heights);
-
-       mi = get_mris_irn(env, v_start);
-       list_del(&mi->lineage_list);
-
-       return 1;
-}
-
-static void fuse_lineages(mris_env_t *env)
-{
-       mris_irn_t *u, *v, *tmp1, *tmp2;
-
-again:
-       foreach_lineage(env, u, tmp1) {
-               foreach_lineage(env, v, tmp2) {
-                       if (u != v && u->lineage_start && v->lineage_start && u->lineage_end && v->lineage_end
-                               && get_nodes_block(u->lineage_start) == get_nodes_block(v->lineage_start)) {
-                               int uv = heights_reachable_in_block(env->heights, u->lineage_start, v->lineage_end);
-                               int vu = heights_reachable_in_block(env->heights, v->lineage_start, u->lineage_end);
-
-                               if (uv && !vu) {
-                                       if (fuse_two_lineages(env, u, v))
-                                               goto again;
-                               }
-                       }
-               }
-       }
-}
-
-static mris_env_t *dump_env = NULL;
-
-static void block_walker(ir_node *bl, void *data)
-{
-       mris_env_t *env = (mris_env_t*)data;
-       env->bl = bl;
-       lineage_formation(env);
-       fuse_lineages(env);
-}
-
-static void mris_edge_hook(FILE *F, ir_node *irn)
-{
-       mris_irn_t *mi = get_mris_irn(dump_env, irn);
-
-       if (mi->lineage_next) {
-               fprintf(F, "edge:{sourcename:\"");
-               PRINT_NODEID(mi->lineage_next);
-               fprintf(F, "\" targetname:\"");
-               PRINT_NODEID(irn);
-               fprintf(F, "\" color:lilac}\n");
-       }
-}
-
-void dump_ir_block_graph_mris(mris_env_t *env, const char *suffix)
-{
-       dump_node_edge_func old = get_dump_node_edge_hook();
-
-       set_dump_node_edge_hook(mris_edge_hook);
-       dump_env = env;
-       dump_ir_graph(env->irg, suffix);
-       set_dump_node_edge_hook(old);
-}
-
-mris_env_t *be_sched_mris_preprocess(ir_graph *irg)
-{
-       mris_env_t *env = XMALLOC(mris_env_t);
-
-       phase_init(&env->ph, irg, mris_irn_data_init);
-       env->irg      = irg;
-       env->visited  = 0;
-       env->heights  = heights_new(irg);
-       INIT_LIST_HEAD(&env->lineage_head);
-       FIRM_DBG_REGISTER(env->dbg, "firm.be.sched.mris");
-       obstack_init(&env->obst);
-       irg_walk_graph(irg, firm_clear_link, NULL, NULL);
-       irg_block_walk_graph(irg, block_walker, NULL, env);
-       obstack_free(&env->obst, NULL);
-       // dump_ir_block_graph_mris(env, "-mris");
-       return env;
-}
-
-void be_sched_mris_free(mris_env_t *env)
-{
-       phase_deinit(&env->ph);
-       heights_free(env->heights);
-       free(env);
-}
diff --git a/ir/be/beschedmris.h b/ir/be/beschedmris.h
deleted file mode 100644 (file)
index 19ba007..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief       Implements a list scheduler for the MRIS algorithm.
- * @author      Sebastian Hack
- * @date        04.04.2006
- * @version     $Id$
- *
- * Implements a list scheduler for the MRIS algorithm in:
- * Govindarajan, Yang, Amaral, Zhang, Gao
- * Minimum Register Instruction Sequencing to Reduce Register Spills
- * in out-of-order issue superscalar architectures
- */
-#ifndef FIRM_BE_BESCHEDMRIS_H
-#define FIRM_BE_BESCHEDMRIS_H
-
-#include "beirg.h"
-
-typedef struct mris_env_t mris_env_t;
-
-/**
- * Preprocess the irg with the MRIS algorithm.
- * @param irg  The graph
- * @return     Private data to be kept.
- */
-mris_env_t *be_sched_mris_preprocess(ir_graph *irg);
-
-/**
- * Cleanup the MRIS preprocessing.
- * @param env The private data as returned by be_sched_mris_preprocess().
- */
-void be_sched_mris_free(mris_env_t *env);
-
-/**
- * Dump IR graph with lineages.
- */
-void dump_ir_block_graph_mris(mris_env_t *env, const char *suffix);
-
-#endif
diff --git a/ir/be/beschedrss.c b/ir/be/beschedrss.c
deleted file mode 100644 (file)
index f29df44..0000000
+++ /dev/null
@@ -1,2212 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief       Implementation of a register saturating list scheduler.
- * @author      Christian Wuerdig
- * @date        29.08.2006
- * @version     $Id$
- *
- * Implementation of a register saturating list scheduler
- * as described in: Sid-Ahmed-Ali Touati
- * Register Saturation in Superscalar and VLIW Codes
- */
-#include "config.h"
-
-#include "beschedrss.h"
-
-#include <limits.h>
-
-#include "obst.h"
-#include "debug.h"
-
-#include "irgraph_t.h"
-#include "irnode_t.h"
-#include "iredges_t.h"
-#include "ircons_t.h"
-#include "irphase_t.h"
-#include "irgwalk.h"
-#include "irdump.h"
-#include "irtools.h"
-#include "irbitset.h"
-#include "irprintf.h"
-#include "irnodeset.h"
-#include "bipartite.h"
-#include "hungarian.h"
-#include "plist.h"
-#include "array_t.h"
-
-#include "heights.h"
-
-#include "beabi.h"
-#include "bemodule.h"
-#include "benode.h"
-#include "besched.h"
-#include "beirg.h"
-#include "belive.h"
-
-#include "lc_opts.h"
-#include "lc_opts_enum.h"
-
-
-#define ARR_LEN_SAFE(arr) ((arr) != NULL ? ARR_LEN((arr)) : 0)
-
-#define HASH_RSS_EDGE(edge) ((get_irn_node_nr((edge)->src) << 16) | (get_irn_node_nr((edge)->tgt) & 0xFFFF))
-#define BSEARCH_IRN_ARR(val, arr) \
-       bsearch(&(val), (arr), ARR_LEN_SAFE((arr)), sizeof((arr)[0]), cmp_irn_idx)
-
-#define BLOCK_IDX_MAP(rss, irn) bsearch_for_index(get_irn_idx((irn)), (rss)->idx_map, ARR_LEN_SAFE((rss)->idx_map), 1)
-
-/* the rss options */
-typedef struct rss_opts_t {
-       int dump_flags;
-} rss_opts_t;
-
-/* Represents a child with associated costs */
-typedef struct child {
-       ir_node *irn;
-       float   cost;
-} child_t;
-
-/* We need edges for several purposes. */
-typedef struct rss_edge {
-       ir_node *src;
-       ir_node *tgt;
-       void    *next;
-} rss_edge_t;
-
-/* Represents a connected bipartite component. */
-typedef struct cbc {
-       ir_nodeset_t parents;       /**< = S  a set of value producers */
-       ir_nodeset_t children;      /**< = T  a set of value consumers */
-       pset    *kill_edges;    /**< = E  a set of edges (t in T, s in S) such as each s in S gets killed by at least one t in T */
-       int     nr;             /**< a deterministic index for set insertion (used as hash) */
-} cbc_t;
-
-/* Represents a disjoint value DAG. */
-typedef struct dvg {
-       ir_nodeset_t nodes;
-       pset    *edges;
-} dvg_t;
-
-/* Represents a chain of nodes. */
-typedef struct chain {
-       plist_t *elements;   /**< List of chain elements */
-       int     nr;          /**< a deterministic index for set insertion (used as hash) */
-} chain_t;
-
-typedef struct rss_irn {
-       plist_t  *consumer_list;    /**< List of consumers */
-       const ir_node **consumer;   /**< Sorted consumer array (needed for faster access) */
-
-       plist_t  *parent_list;      /**< List of parents */
-       plist_t  *pkiller_list;     /**< List of potential killers */
-
-       plist_t  *descendant_list;  /**< List of descendants */
-       const ir_node **descendants;      /**< Sorted descendant array (needed for faster access) */
-
-       const ir_node  *killer;     /**< The selected unique killer */
-       const ir_node  *irn;        /**< The corresponding firm node to this rss_irn */
-
-       chain_t  *chain;            /**< The chain, this node is associated to */
-
-       unsigned desc_walk;         /**< visited flag for collecting descendants */
-       unsigned kill_count;        /**< number of nodes killed by this one */
-
-       unsigned live_out : 1;      /**< irn has consumers outside of it's block */
-       unsigned visited  : 1;      /**< visited flag for bipartite decomposition */
-       unsigned havecons : 1;      /**< visited flag collect consumer */
-       unsigned handled  : 1;      /**< flag indicating whether or not the list structures have been build */
-       unsigned dumped   : 1;      /**< flag indication whether or not this node was dumped */
-} rss_irn_t;
-
-/* Represents a serialization edge with associated costs. */
-typedef struct serialization {
-       rss_irn_t  *u;       /* the top node */
-       rss_irn_t  *v;       /* the node about to be serialized after u */
-       rss_edge_t *edge;    /* the edge selected for the serialization */
-       int        omega1;   /* estimated: available regs - RS reduction */
-       int        omega2;   /* increase in critical path length */
-       int        new_killer;
-} serialization_t;
-
-typedef struct rss {
-       ir_phase          ph;              /**< Phase to hold some data */
-       ir_heights_t     *h;              /**< The current height object */
-       ir_graph         *irg;            /**< The irg to preprocess */
-       plist_t          *nodes;          /**< The list of interesting nodes */
-       const arch_env_t *arch_env;       /**< The architecture environment */
-       be_abi_irg_t     *abi;            /**< The abi for this irg */
-       pset             *cbc_set;        /**< A set of connected bipartite components */
-       ir_node          *block;          /**< The current block in progress. */
-       int              *idx_map;        /**< Mapping irn indices to per block indices */
-       unsigned         max_height;      /**< maximum height in the current block */
-       rss_opts_t       *opts;           /**< The options */
-       be_lv_t          *liveness;       /**< The liveness information for this irg */
-       ir_nodeset_t      live_block;     /**< Values alive at end of block */
-       const arch_register_class_t *cls; /**< The current register class */
-       DEBUG_ONLY(firm_dbg_module_t *dbg);
-} rss_t;
-
-static inline rss_irn_t *get_rss_irn(rss_t *env, const ir_node *node)
-{
-       return (rss_irn_t*)phase_get_or_set_irn_data(&env->ph, node);
-}
-
-/**
- * We need some special nodes:
- * a source and a sink for all live-in and live-out values of a block
- */
-enum {
-       iro_rss_Source,
-       iro_rss_Sink,
-       iro_rss_last
-};
-
-/** The opcode of the rss_Source node once allocated. */
-static ir_op *op_rss_Source;
-/** The opcode of the rss_Sink node once allocated. */
-static ir_op *op_rss_Sink;
-
-/** The rss_Source node of the current graph. */
-static ir_node *_source = NULL;
-/** The rss_Sink node of the current graph. */
-static ir_node *_sink   = NULL;
-
-#define is_Source(irn) ((irn) == _source)
-#define is_Sink(irn)   ((irn) == _sink)
-
-enum {
-       RSS_DUMP_NONE  = 0,
-       RSS_DUMP_CBC   = 1 << 0,
-       RSS_DUMP_PKG   = 1 << 1,
-       RSS_DUMP_KILL  = 1 << 2,
-       RSS_DUMP_DVG   = 1 << 3,
-       RSS_DUMP_MAXAC = 1 << 4,
-       RSS_DUMP_ALL   = (RSS_DUMP_MAXAC << 1) - 1,
-};
-
-static rss_opts_t rss_options = {
-       RSS_DUMP_NONE,
-};
-
-static const lc_opt_enum_int_items_t dump_items[] = {
-       { "none",  RSS_DUMP_NONE  },
-       { "cbc",   RSS_DUMP_CBC   },
-       { "pkg",   RSS_DUMP_PKG   },
-       { "kill",  RSS_DUMP_KILL  },
-       { "dvg",   RSS_DUMP_DVG   },
-       { "maxac", RSS_DUMP_MAXAC },
-       { "all",   RSS_DUMP_ALL   },
-       { NULL, 0 }
-};
-
-static lc_opt_enum_int_var_t dump_var = {
-       &rss_options.dump_flags, dump_items
-};
-
-static const lc_opt_table_entry_t rss_option_table[] = {
-       LC_OPT_ENT_ENUM_MASK("dump", "dump phases", &dump_var),
-       LC_OPT_LAST
-};
-
-/******************************************************************************
- *  _          _                    __                  _   _
- * | |        | |                  / _|                | | (_)
- * | |__   ___| |_ __   ___ _ __  | |_ _   _ _ __   ___| |_ _  ___  _ __  ___
- * | '_ \ / _ \ | '_ \ / _ \ '__| |  _| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
- * | | | |  __/ | |_) |  __/ |    | | | |_| | | | | (__| |_| | (_) | | | \__ \
- * |_| |_|\___|_| .__/ \___|_|    |_|  \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
- *            | |
- *            |_|
- ******************************************************************************/
-
-/**
- * Acquire opcodes if needed and create source and sink nodes.
- */
-static void init_rss_special_nodes(ir_graph *irg)
-{
-       ir_node *block;
-
-       if (op_rss_Source == NULL) {
-               int iro_rss_base = get_next_ir_opcodes(iro_rss_last);
-               op_rss_Source = new_ir_op(iro_rss_base + iro_rss_Source, "rss_Source", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
-               op_rss_Sink   = new_ir_op(iro_rss_base + iro_rss_Sink,   "rss_Sink",   op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
-       }
-       block   = get_irg_start_block(irg);
-       _source = new_ir_node(NULL, irg, block, op_rss_Source, mode_ANY, 0, NULL);
-       _sink   = new_ir_node(NULL, irg, block, op_rss_Sink, mode_ANY, 0, NULL);
-}
-
-static int cmp_int(const void *a, const void *b)
-{
-       const int *i1 = (const int*)a;
-       const int *i2 = (const int*)b;
-
-       return QSORT_CMP(*i1, *i2);
-}
-
-static int cmp_child_costs(const void *a, const void *b)
-{
-       const child_t *c1 = (const child_t*)a;
-       const child_t *c2 = (const child_t*)b;
-
-       return QSORT_CMP(c1->cost, c2->cost);
-}
-
-static int cmp_irn_idx(const void *a, const void *b)
-{
-       const ir_node *n1 = *(ir_node **)a;
-       const ir_node *n2 = *(ir_node **)b;
-
-       return QSORT_CMP(get_irn_idx(n1), get_irn_idx(n2));
-}
-
-static int cmp_rss_edges(const void *a, const void *b)
-{
-       const rss_edge_t *e1 = (const rss_edge_t*)a;
-       const rss_edge_t *e2 = (const rss_edge_t*)b;
-
-       return (e1->src != e2->src) || (e1->tgt != e2->tgt);
-}
-
-static int bsearch_for_index(int key, int *arr, size_t len, int force)
-{
-       int left = 0;
-       int right = len;
-
-       while (right >= left) {
-               int idx = (left + right) / 2;
-
-               if (key < arr[idx])
-                       right = idx - 1;
-               else if (key > arr[idx])
-                       left = idx + 1;
-               else
-                       return idx;
-       }
-
-       if (force)
-               assert(0 && "Something is wrong, key not found.");
-       return -1;
-}
-
-static const ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack *obst)
-{
-       plist_element_t *el;
-       int             i   = 0;
-       int             len = plist_count(irn_list);
-       const ir_node   **arr = (const ir_node**)NEW_ARR_D(ir_node*, obst, len);
-
-       /* copy the list into the array */
-       foreach_plist(irn_list, el) {
-               arr[i++] = (ir_node*)plist_element_get_value(el);
-       }
-
-       /* sort the array by node index */
-       /* HACK cast for MSVC */
-       qsort((void*)arr, len, sizeof(arr[0]), cmp_irn_idx);
-
-       return arr;
-}
-
-/*****************************************************
- *      _      _                       _
- *     | |    | |                     (_)
- *   __| | ___| |__  _   _  __ _  __ _ _ _ __   __ _
- *  / _` |/ _ \ '_ \| | | |/ _` |/ _` | | '_ \ / _` |
- * | (_| |  __/ |_) | |_| | (_| | (_| | | | | | (_| |
- *  \__,_|\___|_.__/ \__,_|\__, |\__, |_|_| |_|\__, |
- *                          __/ | __/ |         __/ |
- *                         |___/ |___/         |___/
- *
- *****************************************************/
-
-#ifdef DEBUG_libfirm
-static void dump_nodeset(ir_nodeset_t *ns, const char *prefix)
-{
-       ir_nodeset_iterator_t iter;
-       ir_node *irn;
-
-       ir_nodeset_iterator_init(&iter, ns);
-       while ( (irn = ir_nodeset_iterator_next(&iter)) != NULL ) {
-               ir_fprintf(stderr, "%s%+F\n", prefix, irn);
-       }
-}
-#endif
-
-static void build_file_name(rss_t *rss, const char *suffix, size_t suf_len, char *buf, size_t len)
-{
-       const char *irg_name;
-
-       memset(buf, 0, len);
-       irg_name = get_entity_name(get_irg_entity(rss->irg));
-       snprintf(buf, len - suf_len, "%s-%s-block-%ld",
-               irg_name, arch_register_class_name(rss->cls), get_irn_node_nr(rss->block));
-       strcat(buf, suffix);
-}
-
-/* Dumps all collected bipartite components of current irg as vcg. */
-static void debug_vcg_dump_bipartite(rss_t *rss)
-{
-       cbc_t *cbc;
-       FILE  *f;
-       char  file_name[256];
-       static const char suffix[] = "-RSS-CBC.vcg";
-
-       build_file_name(rss, suffix, sizeof(suffix), file_name, sizeof(file_name));
-       f = fopen(file_name, "w");
-
-       ir_fprintf(f, "graph: { title: \"connected bipartite component graph of %+F\"\n", rss->irg);
-       fprintf(f, "display_edge_labels: no\n");
-       fprintf(f, "layoutalgorithm: mindepth\n");
-       fprintf(f, "manhattan_edges: yes\n\n");
-
-       foreach_pset(rss->cbc_set, cbc_t*, cbc) {
-               ir_nodeset_iterator_t iter;
-               ir_node    *n;
-               rss_edge_t *ke;
-
-               fprintf(f, "graph: { titel: \"cbc %d\" label: \"cbc %d\" status:clustered color:yellow\n", cbc->nr, cbc->nr);
-               foreach_ir_nodeset(&cbc->parents, n, iter) {
-                       ir_fprintf(f, "node: { title: \"n%d_%d\" label: \"%+F\" }\n", get_irn_node_nr(n), cbc->nr, n);
-               }
-               foreach_ir_nodeset(&cbc->children, n, iter) {
-                       ir_fprintf(f, "node: { title: \"n%d_%d\" label: \"%+F\" }\n", get_irn_node_nr(n), cbc->nr, n);
-               }
-               foreach_pset(cbc->kill_edges, rss_edge_t*, ke) {
-                       ir_fprintf(f, "edge: { sourcename: \"n%d_%d\" targetname: \"n%d_%d\" }\n",
-                               get_irn_node_nr(ke->src), cbc->nr, get_irn_node_nr(ke->tgt), cbc->nr);
-               }
-               fprintf(f, "}\n\n");
-       }
-       fprintf(f, "}\n");
-       fclose(f);
-}
-
-/* Dump the computed killing function as vcg. */
-static void debug_vcg_dump_kill(rss_t *rss)
-{
-       FILE            *f;
-       char            file_name[256];
-       plist_element_t *el;
-       static const char suffix[] = "-RSS-KILL.vcg";
-
-       build_file_name(rss, suffix, sizeof(suffix), file_name, sizeof(file_name));
-       f = fopen(file_name, "w");
-
-       ir_fprintf(f, "graph: { title: \"computed kill graph of %+F, block %d\"\n", rss->irg, get_irn_node_nr(rss->block));
-       fprintf(f, "display_edge_labels: no\n");
-       fprintf(f, "layoutalgorithm: mindepth\n");
-       fprintf(f, "manhattan_edges: yes\n\n");
-
-       {
-               /* reset dump_flag */
-               ir_node *irn;
-               foreach_phase_irn(&rss->ph, irn) {
-                       rss_irn_t *node = get_rss_irn(rss, irn);
-                       node->dumped = 0;
-               }
-       }
-
-       /* dump all nodes and their killers */
-       foreach_plist(rss->nodes, el) {
-               ir_node   *irn     = (ir_node  *)plist_element_get_value(el);
-               rss_irn_t *rirn    = get_rss_irn(rss, irn);
-               rss_irn_t *pk_rirn = get_rss_irn(rss, rirn->killer);
-
-               if (! rirn->dumped) {
-                       ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(irn), irn);
-                       rirn->dumped = 1;
-               }
-
-               if (! pk_rirn->dumped) {
-                       ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(rirn->killer), rirn->killer);
-                       pk_rirn->dumped = 1;
-               }
-
-               ir_fprintf(f, "edge: { sourcename: \"n%d\" targetname: \"n%d\" }\n",
-                       get_irn_node_nr(rirn->killer), get_irn_node_nr(irn));
-       }
-
-       fprintf(f, "}\n");
-       fclose(f);
-}
-
-/* Dumps the potential killing DAG (PKG) as vcg. */
-static void debug_vcg_dump_pkg(rss_t *rss, ir_nodeset_t *max_ac, int iteration)
-{
-       FILE              *f;
-       char              file_name[256];
-       char              suffix[32];
-       static const char suffix1[] = "-RSS-PKG.vcg";
-       static const char suffix2[] = "-RSS-PKG-MAXAC.vcg";
-       plist_element_t   *el;
-
-       if (! max_ac) {
-               snprintf(suffix, sizeof(suffix), "%s", suffix1);
-       }
-       else {
-               snprintf(suffix, sizeof(suffix), "-%02d%s", iteration, suffix2);
-       }
-
-       build_file_name(rss, suffix, strlen(suffix) + 1, file_name, sizeof(file_name));
-       f = fopen(file_name, "w");
-
-       ir_fprintf(f, "graph: { title: \"potential killing DAG of %+F, block %d\"\n", rss->irg, get_irn_node_nr(rss->block));
-       fprintf(f, "display_edge_labels: no\n");
-       fprintf(f, "layoutalgorithm: mindepth\n");
-       fprintf(f, "manhattan_edges: yes\n\n");
-
-       {
-               /* reset dump_flag */
-               ir_node *irn;
-               foreach_phase_irn(&rss->ph, irn) {
-                       rss_irn_t *node = get_rss_irn(rss, irn);
-                       node->dumped = 0;
-               }
-       }
-
-       foreach_plist(rss->nodes, el) {
-               ir_node    *irn  = (ir_node   *)plist_element_get_value(el);
-               rss_irn_t  *rirn = get_rss_irn(rss, irn);
-               const char *c1   = "";
-               plist_element_t *k_el;
-
-               /* dump selected saturating values in yellow */
-               if (max_ac && ir_nodeset_contains(max_ac, irn))
-                       c1 = "color:yellow";
-
-               if (! rirn->dumped) {
-                       if (rirn->chain)
-                               ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F   c%d\" %s }\n", get_irn_node_nr(irn), irn, rirn->chain->nr, c1);
-                       else
-                               ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" %s }\n", get_irn_node_nr(irn), irn, c1);
-                       rirn->dumped = 1;
-               }
-
-               foreach_plist(rirn->pkiller_list, k_el) {
-                       ir_node    *pkiller = (ir_node   *)plist_element_get_value(k_el);
-                       rss_irn_t  *pk_rirn = get_rss_irn(rss, pkiller);
-                       const char *c2      = "";
-
-                       if (max_ac && ir_nodeset_contains(max_ac, pkiller))
-                               c2 = "color:yellow";
-
-                       if (! pk_rirn->dumped) {
-                               if (pk_rirn->chain)
-                                       ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F   c%d\" %s }\n", get_irn_node_nr(pkiller), pkiller, pk_rirn->chain->nr, c2);
-                               else
-                                       ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" %s }\n", get_irn_node_nr(pkiller), pkiller, c2);
-                               pk_rirn->dumped = 1;
-                       }
-                       ir_fprintf(f, "edge: { sourcename: \"n%d\" targetname: \"n%d\" }\n",
-                               get_irn_node_nr(pkiller), get_irn_node_nr(irn));
-               }
-       }
-       fprintf(f, "}\n");
-       fclose(f);
-}
-
-/* Dumps the disjoint value DAG (DVG) as vcg. */
-static void debug_vcg_dump_dvg(rss_t *rss, dvg_t *dvg)
-{
-       static const char suffix[] = "-RSS-DVG.vcg";
-       FILE       *f;
-       char       file_name[256];
-       ir_nodeset_iterator_t iter;
-       ir_node    *irn;
-       rss_edge_t *edge;
-
-       build_file_name(rss, suffix, sizeof(suffix), file_name, sizeof(file_name));
-       f = fopen(file_name, "w");
-
-       ir_fprintf(f, "graph: { title: \"disjoint value DAG of %+F, block %d\"\n", rss->irg, get_irn_node_nr(rss->block));
-       fprintf(f, "display_edge_labels: no\n");
-       fprintf(f, "layoutalgorithm: mindepth\n");
-       fprintf(f, "manhattan_edges: yes\n\n");
-
-       /* dump all nodes */
-       foreach_ir_nodeset(&dvg->nodes, irn, iter) {
-               ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(irn), irn);
-       }
-
-       /* dump all edges */
-       foreach_pset(dvg->edges, rss_edge_t*, edge) {
-               ir_fprintf(f, "edge: { sourcename: \"n%d\" targetname: \"n%d\" }\n",
-                       get_irn_node_nr(edge->src), get_irn_node_nr(edge->tgt));
-       }
-
-       fprintf(f, "}\n");
-       fclose(f);
-}
-
-#if 0
-/* Dumps the PKG(DVG). */
-static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg)
-{
-       static const char suffix[] = "-RSS-DVG-PKG.vcg";
-       FILE       *f;
-       char       file_name[256];
-       ir_nodeset_iterator_t iter;
-       ir_node    *irn;
-
-       build_file_name(rss, suffix, sizeof(suffix), file_name, sizeof(file_name));
-       f = fopen(file_name, "w");
-
-       ir_fprintf(f, "graph: { title: \"PKG of disjoint value DAG of %+F, block %d\"\n", rss->irg, get_irn_node_nr(rss->block));
-       fprintf(f, "display_edge_labels: no\n");
-       fprintf(f, "layoutalgorithm: mindepth\n");
-       fprintf(f, "manhattan_edges: yes\n\n");
-
-       /* dump all nodes */
-       foreach_ir_nodeset(&dvg->nodes, irn, iter) {
-               ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(irn), irn);
-       }
-
-       /* dump all edges */
-       foreach_ir_nodeset(&dvg->nodes, irn, iter) {
-               rss_irn_t       *node = get_rss_irn(rss, irn);
-               plist_element_t *el;
-
-               foreach_plist(node->dvg_pkiller_list, el) {
-                       ir_fprintf(f, "edge: { sourcename: \"n%d\" targetname: \"n%d\" }\n",
-                               get_irn_node_nr(plist_element_get_value(el)), get_irn_node_nr(irn));
-               }
-       }
-
-       fprintf(f, "}\n");
-       fclose(f);
-}
-#endif /* if 0 */
-
-/**
- * In case there is no rss information for irn, initialize it.
- */
-static void *init_rss_irn(ir_phase *ph, const ir_node *irn)
-{
-       rss_irn_t *res = (rss_irn_t*)phase_alloc(ph, sizeof(res[0]));
-
-       res->descendant_list = plist_obstack_new(phase_obst(ph));
-       res->descendants     = NULL;
-
-       res->consumer_list   = plist_obstack_new(phase_obst(ph));
-       res->consumer        = NULL;
-
-       res->pkiller_list    = plist_obstack_new(phase_obst(ph));
-
-       res->parent_list     = plist_obstack_new(phase_obst(ph));
-
-       res->killer          = NULL;
-       res->irn             = irn;
-       res->chain           = NULL;
-
-       res->kill_count      = 0;
-       res->desc_walk       = 0;
-       res->live_out        = 0;
-       res->visited         = 0;
-       res->handled         = 0;
-       res->dumped          = 0;
-       res->havecons        = 0;
-
-       return res;
-}
-
-/**
- * Collect all nodes data dependent on current node.
- */
-static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int *got_sink, unsigned cur_desc_walk)
-{
-       const ir_edge_t *edge;
-       rss_irn_t       *cur_node = get_rss_irn(rss, irn);
-       ir_node         *block    = rss->block;
-       ir_edge_kind_t  ekind[2]  = { EDGE_KIND_NORMAL, EDGE_KIND_DEP };
-       int             i;
-
-       if (cur_node->desc_walk >= cur_desc_walk)
-               return;
-       cur_node->desc_walk = cur_desc_walk;
-
-       /* Stop at Barriers */
-       if (be_is_Barrier(irn))
-               return;
-
-       /* loop over normal and dependency edges */
-       for (i = 0; i < 2; ++i) {
-               foreach_out_edge_kind(irn, edge, ekind[i]) {
-                       ir_node *user = get_edge_src_irn(edge);
-
-                       /* skip ignore nodes as they do not really contribute to register pressure */
-                       if (arch_irn_is_ignore(user))
-                               continue;
-
-                       /*
-                               (a) mode_X means Jump            -> out_edge
-                               (b) Phi as user of a normal node -> out-edge
-                       */
-                       if (get_irn_mode(user) == mode_X || is_Phi(user)) {
-                               if (! *got_sink)
-                                       goto force_sink;
-                               else
-                                       continue;
-                       }
-
-                       if (is_Proj(user)) {
-                               //if (arch_get_irn_reg_class_out(user) == rss->cls)
-                                       collect_descendants(rss, rirn, user, got_sink, cur_desc_walk);
-                       }
-                       else {
-                               /* check if user lives in block and is not a control flow node */
-                               if (get_nodes_block(user) == block) {
-                                       if (! plist_has_value(rirn->descendant_list, user)) {
-                                               plist_insert_back(rirn->descendant_list, user);
-                                               DBG((rss->dbg, LEVEL_2, "\t\tdescendant %+F\n", user));
-                                       }
-                                       collect_descendants(rss, rirn, user, got_sink, cur_desc_walk);
-                               }
-                               else if (! *got_sink) {
-force_sink:
-                                       /* user lives out of block: add sink as descendant if not already done */
-                                       plist_insert_back(rirn->descendant_list, _sink);
-                                       *got_sink = 1;
-                                       DBG((rss->dbg, LEVEL_2, "\t\tdescendant %+F\n", _sink));
-                               }
-                       }
-               }
-       }
-}
-
-/**
- * Handles a single consumer.
- */
-static void collect_single_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *consumer, int *got_sink)
-{
-       ir_node *block = rss->block;
-
-       assert(! is_Proj(consumer) && "Cannot handle Projs");
-
-       if (! is_Phi(consumer) && ! is_Block(consumer) && get_nodes_block(consumer) == block) {
-               if (!arch_irn_is_ignore(consumer) &&
-                               !plist_has_value(rss_irn->consumer_list, consumer)) {
-                       plist_insert_back(rss_irn->consumer_list, consumer);
-                       DBG((rss->dbg, LEVEL_2, "\t\tconsumer %+F\n", consumer));
-               }
-       }
-       else {
-               rss_irn->live_out = 1;
-               DBG((rss->dbg, LEVEL_2, "\t\tlive out %+F", consumer));
-               if (! *got_sink) {
-                       plist_insert_back(rss_irn->consumer_list, _sink);
-                       *got_sink = 1;
-                       DB((rss->dbg, LEVEL_2, ", %+F added instead", _sink));
-               }
-               DB((rss->dbg, LEVEL_2, "\n"));
-       }
-}
-
-/**
- * Collect all nodes consuming the value(s) produced by current node.
- */
-static void collect_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *irn, int *got_sink)
-{
-       const ir_edge_t *edge;
-       int             i;
-       ir_edge_kind_t  ekind[2]  = { EDGE_KIND_NORMAL, EDGE_KIND_DEP };
-       rss_irn_t       *cur_node = get_rss_irn(rss, irn);
-
-       if (cur_node->havecons)
-               return;
-       cur_node->havecons = 1;
-
-       for (i = 0; i < 2; ++i) {
-               foreach_out_edge_kind(irn, edge, ekind[i]) {
-                       ir_node *consumer = get_edge_src_irn(edge);
-
-                       if (is_Proj(consumer)) {
-                               //if (arch_get_irn_reg_class_out(consumer) == rss->cls)
-                                       collect_consumer(rss, rss_irn, consumer, got_sink);
-                       }
-                       else
-                               collect_single_consumer(rss, rss_irn, consumer, got_sink);
-               }
-       }
-}
-
-/**
- * Collects all consumer and descendant of a irn.
- */
-static void collect_node_info(rss_t *rss, ir_node *irn)
-{
-       static unsigned cur_desc_walk = 0;
-       rss_irn_t       *rss_irn      = get_rss_irn(rss, irn);
-       int             got_sink;
-
-       assert(! is_Proj(irn) && "Cannot handle Projs.");
-
-       /* check if node info is already available */
-       if (rss_irn->handled)
-               return;
-
-       DBG((rss->dbg, LEVEL_1, "\tcomputing consumers of %+F:\n", irn));
-
-       /* collect all consumer */
-       got_sink = 0;
-       collect_consumer(rss, rss_irn, irn, &got_sink);
-
-       /* build sorted consumer array */
-       rss_irn->consumer = build_sorted_array_from_list(rss_irn->consumer_list, phase_obst(&rss->ph));
-
-       DBG((rss->dbg, LEVEL_1, "\tcompute descendants of %+F:\n", irn));
-
-       /* collect descendants */
-       got_sink = 0;
-       collect_descendants(rss, rss_irn, irn, &got_sink, ++cur_desc_walk);
-
-       /* build sorted descendant array */
-       rss_irn->descendants = build_sorted_array_from_list(rss_irn->descendant_list, phase_obst(&rss->ph));
-
-       rss_irn->handled = 1;
-}
-
-/**
- * Checks if v is a potential killer of u.
- * v is in pkill(u) iff descendants(v) cut consumer(u) is v
- *
- * @param rss   The rss object
- * @param v      The node to check for killer
- * @param u      The potentially killed value
- * @return 1 if v is in pkill(u), 0 otherwise
- */
-static int is_potential_killer(rss_t *rss, rss_irn_t *v, rss_irn_t *u)
-{
-       plist_t *list;
-       const ir_node **arr;
-       plist_element_t *el;
-       (void) rss;
-
-       /* as we loop over the list: loop over the shorter one */
-       if (plist_count(v->descendant_list) > plist_count(u->consumer_list)) {
-               list = u->consumer_list;
-               arr  = v->descendants;
-       }
-       else {
-               list = v->descendant_list;
-               arr  = u->consumer;
-       }
-
-       /* for each list element: try to find element in array */
-       foreach_plist(list, el) {
-               ir_node *irn   = (ir_node*)plist_element_get_value(el);
-               ir_node *match = (ir_node*)BSEARCH_IRN_ARR(irn, arr);
-
-               if (match && match != irn)
-                       return 0;
-       }
-
-       return 1;
-}
-
-/**
- * Update descendants, consumer and pkiller list for the given irn.
- */
-static void update_node_info(rss_t *rss, ir_node *irn, ir_node *pk_irn)
-{
-       rss_irn_t *node    = get_rss_irn(rss, irn);
-       rss_irn_t *pkiller = get_rss_irn(rss, pk_irn);
-
-       /* add consumer and rebuild the consumer array */
-       if (! plist_has_value(node->consumer_list, pk_irn)) {
-               plist_insert_back(node->consumer_list, pk_irn);
-               node->consumer = build_sorted_array_from_list(node->consumer_list, phase_obst(&rss->ph));
-       }
-
-       /* add pk_irn as descendant, add it's descendants to irn's and rebuild array */
-       if (! plist_has_value(node->descendant_list, pk_irn)) {
-               plist_element_t *el;
-
-               plist_insert_back(node->descendant_list, pk_irn);
-
-               foreach_plist(pkiller->descendant_list, el) {
-                       ir_node *desc = (ir_node*)plist_element_get_value(el);
-
-                       if (! plist_has_value(node->descendant_list, desc))
-                               plist_insert_back(node->descendant_list, desc);
-               }
-
-               node->descendants = build_sorted_array_from_list(node->descendant_list, phase_obst(&rss->ph));
-       }
-
-}
-
-/**
- * Compute the potential killing set PK.
- */
-static void compute_pkill_set(rss_t *rss)
-{
-       plist_element_t *u_el, *v_el;
-
-       foreach_plist(rss->nodes, u_el) {
-               ir_node   *u_irn = (ir_node*)plist_element_get_value(u_el);
-               rss_irn_t *u     = get_rss_irn(rss, u_irn);
-
-               DBG((rss->dbg, LEVEL_1, "\tcomputing potential killers of %+F:\n", u_irn));
-
-               /* check each consumer if it is a potential killer  */
-               foreach_plist(u->consumer_list, v_el) {
-                       ir_node   *v_irn = (ir_node*)plist_element_get_value(v_el);
-                       rss_irn_t *v     = get_rss_irn(rss, v_irn);
-
-                       /* check, if v is a potential killer of u */
-                       if (is_potential_killer(rss, v, u)) {
-                               if (! plist_has_value(u->pkiller_list, v_irn))
-                                       plist_insert_back(u->pkiller_list, v_irn);
-                               v->kill_count++;
-                               DBG((rss->dbg, LEVEL_2, "\t\tpotential killer %+F\n", v_irn));
-                       }
-               }
-
-               u->killer = _sink;
-       }
-
-       if (rss->opts->dump_flags & RSS_DUMP_PKG)
-               debug_vcg_dump_pkg(rss, NULL, 0);
-}
-
-/**
- * Build set of killing edges (from values to their potential killers)
- */
-static void build_kill_edges(rss_t *rss, pset *epk)
-{
-       plist_element_t *el, *k_el;
-
-       foreach_plist(rss->nodes, el) {
-               ir_node    *irn = (ir_node*)plist_element_get_value(el);
-               rss_irn_t *rirn = get_rss_irn(rss, irn);
-
-               DBG((rss->dbg, LEVEL_3, "\t\tbuilding kill edges for %+F:\n", irn));
-
-               foreach_plist(rirn->pkiller_list, k_el) {
-                       ir_node    *pkiller = (ir_node*)plist_element_get_value(k_el);
-                       rss_edge_t *ke      = OALLOC(phase_obst(&rss->ph), rss_edge_t);
-
-                       ke->src  = irn;
-                       ke->tgt  = pkiller;
-                       ke->next = NULL;
-
-                       DBG((rss->dbg, LEVEL_3, "\t\t\ttarget %+F\n", pkiller));
-
-                       pset_insert(epk, ke, HASH_RSS_EDGE(ke));
-               }
-       }
-}
-
-#ifdef DEBUG_libfirm
-/* print the given cbc for debugging purpose */
-static void debug_print_cbc(firm_dbg_module_t *mod, cbc_t *cbc)
-{
-       ir_nodeset_iterator_t iter;
-       ir_node    *n;
-       rss_edge_t *ke;
-
-       DBG((mod, LEVEL_3, "\t\tS = set of parents:\n"));
-       foreach_ir_nodeset(&cbc->parents, n, iter) {
-               DBG((mod, LEVEL_3, "\t\t\t%+F\n", n));
-       }
-       DBG((mod, LEVEL_3, "\t\tT = set of children:\n"));
-       foreach_ir_nodeset(&cbc->children, n, iter) {
-               DBG((mod, LEVEL_3, "\t\t\t%+F\n", n));
-       }
-       DBG((mod, LEVEL_3, "\t\tE = Edges from producers to consumers\n"));
-       foreach_pset(cbc->kill_edges, rss_edge_t*, ke) {
-               DBG((mod, LEVEL_3, "\t\t\t%+F -> %+F\n", ke->src, ke->tgt));
-       }
-}
-#endif
-
-/**
- * Construct the bipartite decomposition.
- * Sid-Ahmed-Ali Touati, Phd Thesis
- * Register Pressure in Instruction Level Parallelism, p. 71
- */
-static void compute_bipartite_decomposition(rss_t *rss)
-{
-       pset *epk    = new_pset(cmp_rss_edges, 10);
-       int  cur_num = 0;
-
-       plist_element_t *el;
-
-       DBG((rss->dbg, LEVEL_1, "\tcomputing bipartite decomposition:\n"));
-
-       build_kill_edges(rss, epk);
-
-       foreach_plist(rss->nodes, el) {
-               ir_node   *u_irn   = (ir_node*)plist_element_get_value(el);
-               rss_irn_t *u       = get_rss_irn(rss, u_irn);
-               int       p_change = 1;
-               int       c_change = 1;
-               int       vrfy_ok  = 1;
-
-               cbc_t           *cbc;
-               plist_element_t *el2;
-               rss_edge_t      *k_edge;
-               rss_edge_t      *kedge_root = NULL;
-               ir_node         *t_irn, *s_irn;
-               ir_nodeset_iterator_t iter;
-
-               if (u->visited || u_irn == _sink)
-                       continue;
-
-               DBG((rss->dbg, LEVEL_2, "\t\t%+F choosen:\n", u_irn));
-
-               cbc     = OALLOC(phase_obst(&rss->ph), cbc_t);
-               cbc->nr = cur_num++;
-
-               /* initialize S_cb */
-               ir_nodeset_init_size(&cbc->parents, 5);
-               ir_nodeset_insert(&cbc->parents, u_irn);
-               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents (init)\n", u_irn));
-
-               /* E_cb = empty */
-               cbc->kill_edges = new_pset(cmp_rss_edges, 5);
-
-               /* each parent gets killed by at least one value from children */
-
-               /* T_cb = PK_successors(u) */
-               ir_nodeset_init_size(&cbc->children, 5);
-               foreach_plist(u->pkiller_list, el2) {
-                       ir_nodeset_insert(&cbc->children, (ir_node*)plist_element_get_value(el2));
-                       DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children (init)\n", plist_element_get_value(el2)));
-               }
-
-               /*
-                       Now: insert the parents of all children into the parent set
-                       and insert the children of all parents into the children set
-                       until the sets don't change any more
-               */
-               while (p_change || c_change) {
-                       ir_nodeset_iterator_t iter;
-                       p_change = c_change = 0;
-
-                       /* accumulate parents */
-                       foreach_ir_nodeset(&cbc->children, t_irn, iter) {
-                               foreach_pset(epk, rss_edge_t*, k_edge) {
-                                       ir_node *val = k_edge->src;
-
-                                       if (k_edge->tgt == t_irn && ! ir_nodeset_contains(&cbc->parents, val)) {
-                                               ir_nodeset_insert(&cbc->parents, val);
-                                               p_change = 1;
-                                               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents (killed by %+F)\n", val, t_irn));
-                                       }
-                               }
-                       }
-
-                       /* accumulate children */
-                       foreach_ir_nodeset(&cbc->parents, s_irn, iter) {
-                               foreach_pset(epk, rss_edge_t*, k_edge) {
-                                       ir_node *val = k_edge->tgt;
-
-                                       if (k_edge->src == s_irn  && ! ir_nodeset_contains(&cbc->children, val)) {
-                                               ir_nodeset_insert(&cbc->children, val);
-                                               c_change = 1;
-                                               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children (kills %+F)\n", val, s_irn));
-                                       }
-                               }
-                       }
-               }
-
-               /* mark all parent values as visited */
-               foreach_ir_nodeset(&cbc->parents, s_irn, iter) {
-                       rss_irn_t *s = get_rss_irn(rss, s_irn);
-                       s->visited = 1;
-                       /* assure bipartite property */
-#if 0
-                       if (ir_nodeset_contains(&cbc->children, s_irn)) {
-                               ir_nodeset_remove(&cbc->children, s_irn);
-                               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F removed from to children\n", s_irn));
-                       }
-#endif
-               }
-
-               /* update edges */
-               foreach_pset(epk, rss_edge_t*, k_edge) {
-                       if (ir_nodeset_contains(&cbc->parents, k_edge->src) &&
-                           ir_nodeset_contains(&cbc->children, k_edge->tgt)) {
-                               pset_insert(cbc->kill_edges, k_edge, HASH_RSS_EDGE(k_edge));
-                               /*
-                                       Link all k_edges which are about to be removed together.
-                                       Beware: pset_remove kills the iterator.
-                               */
-                               k_edge->next = kedge_root;
-                               kedge_root   = k_edge;
-                       }
-               }
-
-               /* remove all linked k_edges */
-               for (; kedge_root; kedge_root = (rss_edge_t*)kedge_root->next) {
-                       pset_remove(epk, kedge_root, HASH_RSS_EDGE(kedge_root));
-               }
-
-               /* verify the cbc */
-               foreach_ir_nodeset(&cbc->parents, s_irn, iter) {
-                       int is_killed = 0;
-
-                       foreach_pset(cbc->kill_edges, rss_edge_t*, k_edge) {
-                               if (k_edge->src == s_irn) {
-                                       is_killed = 1;
-                                       pset_break(cbc->kill_edges);
-                                       break;
-                               }
-                       }
-
-                       if (! is_killed) {
-                               vrfy_ok = 0;
-                               ir_fprintf(stderr, "Warning: parent %+F is not killed in current cbc\n", s_irn);
-                       }
-               }
-               assert(vrfy_ok && "Verification of CBC failed");
-
-               /* add the connected bipartite component */
-               if (ir_nodeset_size(&cbc->parents) > 0 &&
-                   ir_nodeset_size(&cbc->children) > 0 &&
-                       pset_count(cbc->kill_edges) > 0)
-                       pset_insert(rss->cbc_set, cbc, (unsigned)cbc->nr);
-               DBG((rss->dbg, LEVEL_2, "\tbipartite component %d inserted:\n", cbc->nr));
-               DEBUG_ONLY(
-                       if (firm_dbg_get_mask(rss->dbg) & LEVEL_2)
-                               debug_print_cbc(rss->dbg, cbc);
-               );
-       }
-
-       if (rss->opts->dump_flags & RSS_DUMP_CBC)
-               debug_vcg_dump_bipartite(rss);
-
-       del_pset(epk);
-}
-
-/**
- * Select the child with the maximum cost.
- */
-static child_t *select_child_max_cost(rss_t *rss, ir_nodeset_t *x, ir_nodeset_t *y, child_t *t, cbc_t *cbc)
-{
-       ir_node *child;
-       ir_nodeset_iterator_t iter;
-       float   max_cost = -1.0f;
-
-       DBG((rss->dbg, LEVEL_2, "\t\tcomputing children costs:\n"));
-
-       foreach_ir_nodeset(&cbc->children, child, iter) {
-               rss_irn_t  *r_child             = get_rss_irn(rss, child);
-               int         num_unkilled_parents = 0;
-               int         num_descendants;
-               rss_edge_t *k_edge;
-               float       cost;
-
-               /* get the number of unkilled parents */
-               foreach_pset(cbc->kill_edges, rss_edge_t*, k_edge) {
-                       if (k_edge->tgt == child && ir_nodeset_contains(x, k_edge->src))
-                               ++num_unkilled_parents;
-               }
-
-               cost = (float)num_unkilled_parents;
-
-               num_descendants = plist_count(r_child->descendant_list) + ir_nodeset_size(y);
-
-               if (num_descendants > 0)
-                       cost /= (float)num_descendants;
-
-               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F, #desc %d, cost %.3f\n", child, num_descendants, cost));
-
-               if (cost > max_cost) {
-                       t->irn   = child;
-                       t->cost  = cost;
-                       max_cost = cost;
-               }
-       }
-
-       return t;
-}
-
-/**
- * Remove all parents from x which are killed by t_irn.
- */
-static void remove_covered_parents(rss_t *rss, ir_nodeset_t *x, ir_node *t_irn, cbc_t *cbc)
-{
-       rss_irn_t  *t = get_rss_irn(rss, t_irn);
-       rss_edge_t *k_edge;
-
-       DBG((rss->dbg, LEVEL_2, "\t\tremoving parents covered by %+F:\n", t_irn));
-
-       foreach_pset(cbc->kill_edges, rss_edge_t*, k_edge) {
-               if (k_edge->tgt == t_irn && ir_nodeset_contains(x, k_edge->src)) {
-                       ir_nodeset_remove(x, k_edge->src);
-                       plist_insert_back(t->parent_list, k_edge->src);
-                       DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", k_edge->src));
-               }
-       }
-}
-
-static void update_cumulated_descendent_values(rss_t *rss, ir_nodeset_t *y, ir_node *t_irn)
-{
-       rss_irn_t *t = get_rss_irn(rss, t_irn);
-       plist_element_t *el;
-
-       DBG((rss->dbg, LEVEL_2, "\t\tupdating cumulated descendant value of %+F:\n", t_irn));
-
-       foreach_plist(t->descendant_list, el) {
-               ir_nodeset_insert(y, (ir_node*)plist_element_get_value(el));
-               DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", plist_element_get_value(el)));
-       }
-}
-
-/**
- * Greedy-k: a heuristics for the MMA problem
- */
-static void compute_killing_function(rss_t *rss)
-{
-       cbc_t *cbc;
-       struct obstack obst;
-
-       obstack_init(&obst);
-
-       rss->cbc_set = pset_new_ptr(5);
-       compute_bipartite_decomposition(rss);
-
-       /* for all bipartite components do: */
-       foreach_pset(rss->cbc_set, cbc_t*, cbc) {
-               ir_node *p;
-               ir_nodeset_t x;
-               ir_nodeset_t y;
-               ir_nodeset_iterator_t iter;
-               child_t **sks    = NEW_ARR_F(child_t *, 20);
-               size_t  cur_len  =  0;
-               size_t  cur_size = 20;
-               size_t  i;
-
-               ir_nodeset_init_size(&x, 10);
-               ir_nodeset_init_size(&y, 10);
-
-               DBG((rss->dbg, LEVEL_1, "\tcomputing SKS for cbc %d:\n", cbc->nr));
-               DBG((rss->dbg, LEVEL_2, "\t\tinitializing parents X:\n"));
-
-               /* X = S_cb (all parents are initially uncovered) */
-               foreach_ir_nodeset(&cbc->parents, p, iter) {
-                       ir_nodeset_insert(&x, p);
-                       DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", p));
-               }
-
-               /* while X not empty */
-               while (ir_nodeset_size(&x) > 0) {
-                       child_t *t = OALLOCZ(&obst, child_t);
-
-                       t = select_child_max_cost(rss, &x, &y, t, cbc);
-
-                       if (cur_len >= cur_size) {
-                               cur_size *= 2;
-                               ARR_EXTO(child_t *, sks, cur_size);
-                       }
-
-                       DBG((rss->dbg, LEVEL_2, "\t\tinsert child %+F (%.3f) into SKS at pos %d\n", t->irn, t->cost, cur_len));
-
-                       sks[cur_len++] = t;
-                       remove_covered_parents(rss, &x, t->irn, cbc);
-                       update_cumulated_descendent_values(rss, &y, t->irn);
-               }
-
-               ARR_SHRINKLEN(sks, cur_len);
-
-               /* sort SKS in increasing cost order */
-               qsort(sks, cur_len, sizeof(sks[0]), cmp_child_costs);
-
-               DBG((rss->dbg, LEVEL_2, "\tprocessing SKS for cbc %d:\n", cbc->nr));
-
-               /* build killing function */
-               for (i = cur_len; i != 0;) { /* loop over sks in decreasing cost order */
-                       child_t         *t = sks[--i];
-                       rss_irn_t       *rt = get_rss_irn(rss, t->irn);
-                       plist_element_t *p_el;
-
-                       DBG((rss->dbg, LEVEL_3, "\t\t\tkiller %+F (%.3f):\n", t->irn, t->cost));
-
-                       /* kill all unkilled parents of t */
-                       foreach_plist(rt->parent_list, p_el) {
-                               ir_node    *par = (ir_node*)plist_element_get_value(p_el);
-                               rss_irn_t *rpar = get_rss_irn(rss, par);
-
-                               if (is_Sink(rpar->killer)) {
-                                       rpar->killer = t->irn;
-                                       DBG((rss->dbg, LEVEL_2, "\t\tkill %+F\n", rpar->irn));
-                               }
-                               else {
-                                       DBG((rss->dbg, LEVEL_3, "\t\t\tkeeping %+F as killer for %+F\n", rpar->killer, rpar->irn));
-                               }
-                       }
-               }
-
-               ir_nodeset_destroy(&x);
-               ir_nodeset_destroy(&y);
-               DEL_ARR_F(sks);
-       }
-
-       if (rss->opts->dump_flags & RSS_DUMP_KILL)
-               debug_vcg_dump_kill(rss);
-
-       del_pset(rss->cbc_set);
-       obstack_free(&obst, NULL);
-}
-
-/**
- * Adds the edge src -> tgt to the dvg. Checks if reverse edge is already there (asserts).
- */
-static inline void add_dvg_edge(rss_t *rss, dvg_t *dvg, const ir_node *src, const ir_node *tgt, int have_source)
-{
-       rss_edge_t *dvg_edge;
-       rss_edge_t key;
-
-       if (! have_source)
-               ir_nodeset_insert(&dvg->nodes, (ir_node *) src);
-       else
-               assert(ir_nodeset_contains(&dvg->nodes, src) && "Wrong assumption");
-
-       ir_nodeset_insert(&dvg->nodes, (ir_node *) tgt);
-
-       key.src = (ir_node *) tgt;
-       key.tgt = (ir_node *) src;
-       assert(pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key)) == NULL && "DVG must be acyclic!");
-
-       key.src = (ir_node *) src;
-       key.tgt = (ir_node *) tgt;
-       if (NULL != pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) {
-               /* add the edge to the DVG */
-               dvg_edge = OALLOC(phase_obst(&rss->ph), rss_edge_t);
-
-               dvg_edge->src  = (ir_node *) src;
-               dvg_edge->tgt  = (ir_node *) tgt;
-               dvg_edge->next = NULL;
-
-               DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", src, tgt));
-               pset_insert(dvg->edges, dvg_edge, HASH_RSS_EDGE(dvg_edge));
-       }
-}
-
-/**
- * Computes the disjoint value DAG (DVG).
- * BEWARE: It is not made explicitly clear in the Touati paper,
- *         but the DVG is meant to be build from the KILLING DAG
- */
-static void compute_dvg(rss_t *rss, dvg_t *dvg)
-{
-       plist_element_t *el;
-
-       DBG((rss->dbg, LEVEL_1, "\tcomputing DVG:\n"));
-
-       foreach_plist(rss->nodes, el) {
-               ir_node    *u_irn    = (ir_node*)plist_element_get_value(el);
-               rss_irn_t  *u        = get_rss_irn(rss, u_irn);
-               rss_irn_t  *u_killer = get_rss_irn(rss, u->killer);
-               int        i;
-
-               /* TODO: omit nodes only having sink as pkiller and killing no one */
-
-               /* add an edge to killer */
-               add_dvg_edge(rss, dvg, u_irn, u->killer, 0);
-
-               if (is_Sink(u->killer))
-                       continue;
-
-               /* We add an edge to every killer, from where we could be reached. */
-               for (i = ARR_LEN_SAFE(u_killer->descendants) - 1; i >= 0; --i) {
-                       add_dvg_edge(rss, dvg, u_irn, u_killer->descendants[i], 1);
-               }
-
-#if 0
-
-               foreach_plist(rss->nodes, el2) {
-                       ir_node *v_irn = plist_element_get_value(el2);
-
-                       /*
-                               There is an edge (u, v) in the DVG iff v is a descendant of the killer(u).
-                       */
-                       if (BSEARCH_IRN_ARR(v_irn, u_kill->descendants)) {
-                               rss_edge_t *dvg_edge = OALLOC(phase_obst(&rss->ph), rss_edge_t);
-                               rss_edge_t key;
-
-                               /* insert the user into the DVG and append it to the user list of u */
-                               ir_nodeset_insert(&dvg->nodes, v_irn);
-                               if (! plist_has_value(u->dvg_user_list, v_irn))
-                                       plist_insert_back(u->dvg_user_list, v_irn);
-
-                               dvg_edge->src  = u_irn;
-                               dvg_edge->tgt  = v_irn;
-                               dvg_edge->next = NULL;
-
-                               key.src = v_irn;
-                               key.tgt = u_irn;
-
-                               assert(pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key)) == NULL && "DVG must be acyclic!");
-
-                               /* add the edge to the DVG */
-                               DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", u_irn, v_irn));
-                               pset_insert(dvg->edges, dvg_edge, HASH_RSS_EDGE(dvg_edge));
-                       }
-               }
-#endif /* if 0 */
-       }
-
-       if (rss->opts->dump_flags & RSS_DUMP_DVG)
-               debug_vcg_dump_dvg(rss, dvg);
-}
-
-/**
- * Updates the dvg structure when a serialization edge from src -> tgt is added.
- */
-static void update_dvg(rss_t *rss, dvg_t *dvg, rss_irn_t *src, rss_irn_t *tgt)
-{
-       int i, j, idx;
-       rss_edge_t *edge;
-       rss_edge_t **arr = ALLOCAN(rss_edge_t*, pset_count(dvg->edges));
-
-       /*
-               Add an edge from serialization target to serialization src:
-               src cannot be alive with target
-       */
-       add_dvg_edge(rss, dvg, tgt->irn, src->irn, 0);
-
-       /* Add edges to src's descendants as well, they also getting serialized. */
-       for (i = ARR_LEN_SAFE(src->descendants) - 1; i >= 0; --i) {
-               add_dvg_edge(rss, dvg, tgt->irn, src->descendants[i], 1);
-       }
-
-       /* We also have to add edges from targets predecessors in dvg */
-       idx = 0;
-       /* We cannot insert elements into set over which we iterate ... */
-       foreach_pset(dvg->edges, rss_edge_t*, edge) {
-               if (edge->tgt == tgt->irn) {
-                       arr[idx++] = edge;
-               }
-       }
-
-       for (i = 0; i < idx; ++i) {
-               edge = arr[i];
-               add_dvg_edge(rss, dvg, edge->src, src->irn, 1);
-               for (j = ARR_LEN_SAFE(src->descendants) - 1; j >= 0; --j) {
-                       add_dvg_edge(rss, dvg, edge->src, src->descendants[j], 1);
-               }
-       }
-}
-
-#if 0
-/**
- * Accumulate all descendants for root into list.
- */
-static void accumulate_dvg_descendant_values(rss_t *rss, rss_irn_t *root, plist_t *list)
-{
-       if (plist_count(root->dvg_user_list) > 0) {
-               plist_element_t *el;
-
-               foreach_plist(root->dvg_user_list, el) {
-                       ir_node   *v_irn = plist_element_get_value(el);
-                       rss_irn_t *v     = get_rss_irn(rss, v_irn);
-
-                       /* add v as descendant */
-                       if (! plist_has_value(list, v_irn)) {
-                               plist_insert_back(list, v_irn);
-                               DBG((rss->dbg, DEBUG_DVG, "\t\t\tadd DVG descendant %+F\n", v_irn));
-                       }
-
-                       /* accumulate v's descendants */
-                       accumulate_dvg_descendant_values(rss, v, list);
-               }
-       }
-}
-
-/**
- * Builds the list of potential killers for each node
- * in the given DVG.
- * Needs the descendant list for all user as sorted array.
- */
-static void build_dvg_pkiller_list(rss_t *rss, dvg_t *dvg)
-{
-       ir_nodeset_iterator_t iter;
-       ir_node *irn;
-
-       foreach_nodeset(&dvg->nodes, irn, iter) {
-               rss_irn_t       *node = get_rss_irn(rss, irn);
-               plist_element_t *el, *el2;
-
-               DBG((rss->dbg, DEBUG_DVG, "\t\tbuilding pkiller list for %+F\n", irn));
-
-               /* check each user */
-               foreach_plist(node->dvg_user_list, el) {
-                       ir_node *u_irn = plist_element_get_value(el);
-
-                       /* is the current user u_irn not a descendant of any other user -> pkiller */
-                       foreach_plist(node->dvg_user_list, el2) {
-                               ir_node   *v_irn = plist_element_get_value(el2);
-                               rss_irn_t *v     = get_rss_irn(rss, v_irn);
-
-                               if (el != el2                             &&
-                                       ! BSEARCH_IRN_ARR(u_irn, v->dvg_desc) &&
-                                       ! plist_has_value(node->dvg_pkiller_list, u_irn))
-                               {
-                                       plist_insert_back(node->dvg_pkiller_list, u_irn);
-                                       DBG((rss->dbg, DEBUG_DVG, "\t\t\tadd DVG pkiller %+F\n", u_irn));
-                               }
-                       }
-               }
-
-               node->dvg_pkiller = build_sorted_array_from_list(node->dvg_pkiller_list, phase_obst(&rss->ph));
-       }
-
-       DEBUG_ONLY(
-               if (firm_dbg_get_mask(rss->dbg) & DEBUG_DVG)
-                       debug_vcg_dump_dvg_pkiller(rss, dvg);
-       );
-}
-
-#endif /* if 0 */
-
-/**
- * Compute the maximal antichain of the current DVG.
- * This is a reimplementation of the MAXIMAL_ANTI_CHAIN function
- * from the DDG library 1.1 (DAG.cpp).
- */
-static ir_nodeset_t *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration)
-{
-       unsigned    n               = ir_nodeset_size(&dvg->nodes);
-       unsigned    *assignment     = ALLOCAN(unsigned, n);
-       unsigned    *assignment_rev = ALLOCAN(unsigned, n);
-       int         *idx_map        = ALLOCAN(int, n);
-       hungarian_problem_t *bp;
-       ir_nodeset_t *values, *temp;
-       ir_nodeset_iterator_t iter;
-       ir_node     *u_irn;
-       unsigned    i, j;
-       unsigned    cost;
-       int         cur_chain, res;
-       rss_edge_t  *dvg_edge;
-
-#define MAP_IDX(irn) bsearch_for_index(get_irn_idx(irn), idx_map,  n,  1)
-
-       if (pset_count(dvg->edges) == 0)
-               return NULL;
-
-       bp = hungarian_new(n, n, HUNGARIAN_MATCH_NORMAL);
-
-       /*
-               At first, we build an index map for the nodes in the DVG,
-               because we cannot use the irn idx therefore as the resulting
-               bipartite data structure would have around 1.2GB.
-               So we limit the size to the number of nodes we have in the DVG
-               and build a sorted index map for their irn indices.
-       */
-       i = 0;
-       foreach_ir_nodeset(&dvg->nodes, u_irn, iter) {
-               idx_map[i++] = get_irn_idx(u_irn);
-       }
-       qsort(idx_map, n, sizeof(idx_map[0]), cmp_int);
-
-       foreach_pset(dvg->edges, rss_edge_t*, dvg_edge) {
-               int idx_u = MAP_IDX(dvg_edge->src);
-               int idx_v = MAP_IDX(dvg_edge->tgt);
-
-               /* add the entry to the bipartite data structure */
-               hungarian_add(bp, idx_u, idx_v, 1);
-               DBG((rss->dbg, LEVEL_3, "\t\t\tadd %d (%+F) -> %d (%+F)\n",
-                       idx_u, dvg_edge->src, idx_v, dvg_edge->tgt));
-       }
-#if 0
-       /*
-               Add a bipartite entry for each pair of nodes (u, v), where exists a
-               path in the DVG from u to v, ie. connect all descendants(v) to v.
-               desc_dvg(v) = accumulated descendants of all z in dvg_user_list(v)
-       */
-       foreach_ir_nodeset(&dvg->nodes, u_irn, iter) {
-               rss_irn_t *u        = get_rss_irn(rss, u_irn);
-               int       idx_u_irn = MAP_IDX(u_irn);
-
-               DBG((rss->dbg, DEBUG_DVG, "\t\tcomputing DVG descendants of %+F:\n", u_irn));
-
-               //plist_clear(u->dvg_desc_list);
-               //accumulate_dvg_descendant_values(rss, u, u->dvg_desc_list);
-
-               /*
-                       FIXME: The array is build on the phase obstack and we cannot free the data.
-                       So the array get as many times allocated as this function is called.
-               */
-
-               /* build the sorted array for faster searches */
-               //u->dvg_desc = build_sorted_array_from_list(u->dvg_desc_list, phase_obst(&rss->ph));
-
-               DBG((rss->dbg, DEBUG_MAX_AC, "\t\tadding bipartite entries of %+F:\n", u_irn));
-
-               /* add the bipartite entries for all descendants */
-               for (i = ARR_LEN_SAFE(u->dvg_desc) - 1; i >= 0; --i) {
-                       rss_irn_t *desc    = get_rss_irn(rss, u->dvg_desc[i]);
-                       int       idx_desc = MAP_IDX(u->dvg_desc[i]);
-
-                       /* add the entry to the bipartite data structure */
-                       hungarian_add(bp, idx_u_irn, idx_desc, 1);
-                       DBG((rss->dbg, DEBUG_MAX_AC, "\t\t\tadd %d (%+F) -> %d (%+F)\n",
-                               idx_u_irn, u_irn, idx_desc, u->dvg_desc[i]));
-
-                       need_matching = 1;
-               }
-       }
-#endif
-
-       /* We want maximum cardinality matching */
-       hungarian_prepare_cost_matrix(bp, HUNGARIAN_MODE_MAXIMIZE_UTIL);
-
-#if 0
-       DBG((rss->dbg, DEBUG_DVG, "\t\tcomputing DVG pkiller:\n"));
-       /* beware: the following function needs the dvg_desc array */
-       build_dvg_pkiller_list(rss, dvg);
-#endif
-
-       DBG((rss->dbg, LEVEL_2, "\t\tcomputing bipartite matching\n"));
-       /*
-               The maximum cardinality bipartite matching gives us the minimal
-               chain partition, which corresponds to the maximum anti chains.
-       */
-       res = hungarian_solve(bp, assignment, &cost, 1);
-       assert(res == 0 && "Bipartite matching failed!");
-
-       hungarian_free(bp);
-       memset(assignment_rev, -1, n * sizeof(assignment_rev[0]));
-
-       /* build the reverse assignment, ie. foreach i -> j, add j -> i */
-       for (i = 0; i < n; ++i) {
-               if (assignment[i] != (unsigned)-1) {
-                       unsigned j = assignment[i];
-                       assignment_rev[j] = i;
-               }
-       }
-
-       DBG((rss->dbg, LEVEL_2, "\t\tgot assignment with cost %u\n", cost));
-       DBG((rss->dbg, LEVEL_3, "\t\t\tassignment   ---   reverse assignment\n"));
-       for (i = 0; i < n; ++i) {
-               DBG((rss->dbg, LEVEL_3, "\t\t\t%3u -> %3u         %3u -> %3u\n", i, assignment[i], i, assignment_rev[i]));
-       }
-
-       values    = XMALLOC(ir_nodeset_t);
-       ir_nodeset_init_size(values, 10);
-       cur_chain = 0;
-       /* Construction of the minimal chain partition */
-       for (j = 0; j < n; ++j) {
-               /* check nodes, which did not occur as target */
-               if (assignment_rev[j] == (unsigned)-1) {
-                       int       xj      = idx_map[j];
-                       ir_node   *xj_irn = get_idx_irn(rss->irg, xj);
-                       rss_irn_t *xj_rss = get_rss_irn(rss, xj_irn);
-                       chain_t   *c      = OALLOC(phase_obst(&rss->ph), chain_t);
-                       unsigned  source;
-
-                       /* there was no source for j -> we have a source of a new chain */
-                       ir_nodeset_insert(values, xj_irn);
-
-                       c->elements = plist_obstack_new(phase_obst(&rss->ph));
-                       c->nr       = cur_chain++;
-                       plist_insert_back(c->elements, xj_irn);
-
-                       xj_rss->chain = c;
-
-                       DBG((rss->dbg, LEVEL_2, "\t\tstarting chain %d:\n", c->nr));
-                       DBG((rss->dbg, LEVEL_2, "\t\t\t%+F (%u)", xj_irn, j));
-
-                       /* follow chain, having j as source */
-                       source = j;
-                       while (assignment[source] != (unsigned)-1) {
-                               int       target  = assignment[source];
-                               int       irn_idx = idx_map[target];
-                               ir_node   *irn    = get_idx_irn(rss->irg, irn_idx);
-                               rss_irn_t *node   = get_rss_irn(rss, irn);
-
-                               plist_insert_back(c->elements, irn);
-                               node->chain = c;
-
-                               DB((rss->dbg, LEVEL_2, " -> %+F (%d)", irn, target));
-
-                               /* new source = last target */
-                               source = target;
-                       }
-
-                       DB((rss->dbg, LEVEL_2, "\n"));
-               }
-       }
-
-       /*
-               Computing the maximal antichain: Select an element from each
-               chain such, such it is parallel with the others.
-       */
-       DBG((rss->dbg, LEVEL_1, "\t\tcomputing set of saturation values (MAX AC)\n"));
-       DBG((rss->dbg, LEVEL_3, "\t\tstarting with:\n"));
-
-       DEBUG_ONLY(
-               if (firm_dbg_get_mask(rss->dbg) & LEVEL_3)
-                       dump_nodeset(values, "\t\t\t");
-       )
-
-       temp = NULL;
-       do {
-               /*
-                       We need an explicit array for the values as
-                       we cannot iterate multiple times over the same
-                       set at the same time. :-(((((
-                       TODO Matze: now we can, so rewrite this...
-               */
-               unsigned n         = ir_nodeset_size(values);
-               unsigned i         = 0;
-               ir_node **val_arr = NEW_ARR_F(ir_node *, n);
-
-               foreach_ir_nodeset(values, u_irn, iter)
-                       val_arr[i++] = u_irn;
-
-               if (temp) {
-                       ir_nodeset_destroy(temp);
-                       free(temp);
-               }
-
-               temp = XMALLOC(ir_nodeset_t);
-               ir_nodeset_init_size(temp, 10);
-
-               /* Select all nodes from current value set, having another node in the set as descendant. */
-               for (i = 0; i < n; ++i) {
-                       rss_irn_t *u = get_rss_irn(rss, val_arr[i]);
-
-                       for (j = 0; j < n; ++j) {
-                               if (i != j) {
-                                       rss_edge_t key;
-
-                                       key.src = val_arr[i];
-                                       key.tgt = val_arr[j];
-
-                                       if (pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) {
-                                               /* v[j] is descendant of u -> remove u and break */
-                                               ir_nodeset_insert(temp, (ir_node *) u->irn);
-                                               ir_nodeset_remove(values, u->irn);
-
-                                               DBG((rss->dbg, LEVEL_3, "\t\t\tremoving %+F from values, adding it to temp\n", u->irn));
-
-                                               break;
-                                       }
-                               }
-                       }
-               }
-
-               /* Try to insert the chain predecessor of all selected u's */
-               foreach_ir_nodeset(temp, u_irn, iter) {
-                       rss_irn_t       *u  = get_rss_irn(rss, u_irn);
-                       chain_t         *c  = u->chain;
-                       plist_element_t *el = plist_find_value(c->elements, u_irn);
-
-                       assert(el && "Missing element in chain!");
-
-                       /* If u has predecessor in chain: insert the predecessor */
-                       if (el == plist_element_get_prev(el)) {
-                               ir_nodeset_insert(values, (ir_node*)plist_element_get_value(el));
-                               DBG((rss->dbg, LEVEL_3, "\t\t\tadding %+F to values\n", plist_element_get_value(el)));
-                       }
-               }
-
-
-               DEL_ARR_F(val_arr);
-       } while (ir_nodeset_size(temp) > 0);
-
-       DBG((rss->dbg, LEVEL_2, "\t\tfinal set:\n"));
-       DEBUG_ONLY(
-               if (firm_dbg_get_mask(rss->dbg) & LEVEL_2) {
-                       dump_nodeset(values, "\t\t\t");
-               }
-       );
-
-       if (rss->opts->dump_flags & RSS_DUMP_MAXAC)
-               debug_vcg_dump_pkg(rss, values, iteration);
-
-       if (temp != NULL) {
-               ir_nodeset_destroy(temp);
-               free(temp);
-       }
-
-       return values;
-
-#undef MAP_IDX
-}
-
-/**
- * Computes the best serialization between two nodes of sat_vals.
- */
-static serialization_t *compute_best_admissible_serialization(rss_t *rss, ir_nodeset_t *sat_vals, serialization_t *ser, int num_regs)
-{
-       int        n                    = ir_nodeset_size(sat_vals);
-       int        n_idx                = ARR_LEN_SAFE(rss->idx_map);
-       int        i                    = 0;
-       ir_node    **val_arr            = ALLOCAN(ir_node*, n);
-       bitset_t   *bs_sv               = bitset_alloca(n_idx);
-       bitset_t   *bs_vdesc            = bitset_alloca(n_idx);
-       bitset_t   *bs_tmp              = bitset_alloca(n_idx);
-       bitset_t   *bs_ukilldesc        = bitset_alloca(n_idx);
-       int        best_benefit         = INT_MAX;
-       int        best_omega2          = INT_MAX;
-       int        best_benefit_omega20 = INT_MAX;
-       int        has_omega1           = 0;
-       int        j, k;
-       ir_node    *irn;
-       ir_nodeset_iterator_t iter;
-       rss_edge_t min_benefit_edge = {NULL, NULL, NULL};
-       rss_edge_t min_omega20_edge = {NULL, NULL, NULL};
-       rss_irn_t  *ser_u_omega1 = NULL, *ser_v_omega1 = NULL;
-       rss_irn_t  *ser_u_omega20 = NULL, *ser_v_omega20 = NULL;
-
-       DBG((rss->dbg, LEVEL_1, "\tcomputing admissible serializations:\n"));
-
-       /*
-               We need an explicit array for the values as
-               we cannot iterate multiple times over the same
-               set at the same time. :-(((((
-       */
-
-       foreach_ir_nodeset(sat_vals, irn, iter) {
-               val_arr[i++] = irn;
-               bitset_set(bs_sv, BLOCK_IDX_MAP(rss, irn));
-       }
-
-       /*
-               We build all admissible serializations and remember the best found so far.
-               For u in sat_vals:
-                For v in sat_val:
-                  if v in pkiller(u): add edge from v to all other pkiller(u)
-                  else: for all vv in pkiller(u): add edge from v to vv if there exists no path from vv to v
-       */
-
-/*
-       A node is unserializable if:
-       - it has only one killer and this one is Sink
-    - it kills no other values
-       In this case there is no serialization which could
-       reduce the registerpressure
-*/
-#define IS_UNSERIALIZABLE_NODE(rss_node)                  \
-       (                                                     \
-               (                                                 \
-                       (plist_count(rss_node->pkiller_list) == 1) && \
-                       is_Sink(rss_node->killer)                  && \
-                       (rss_node->kill_count                == 0)    \
-               )                            ||                   \
-               be_is_Barrier(rss_node->irn) ||                   \
-               be_is_Keep(rss_node->irn)                         \
-       )
-
-       /* for all u in sat_vals */
-       for (i = 0; i < n; ++i) {
-               rss_irn_t       *u = get_rss_irn(rss, val_arr[i]);
-               plist_element_t *el;
-
-               /* ignore nodes where serialization does not help */
-               if (IS_UNSERIALIZABLE_NODE(u)) {
-                       DBG((rss->dbg, LEVEL_3, "\t\t\t%+F considered unserializable\n", u->irn));
-                       continue;
-               }
-
-               /* accumulate all descendants of all pkiller(u) */
-               bitset_clear_all(bs_ukilldesc);
-               foreach_plist(u->pkiller_list, el) {
-                       ir_node   *irn  = (ir_node*)plist_element_get_value(el);
-                       rss_irn_t *node = get_rss_irn(rss, irn);
-
-                       if (! is_Sink(irn))
-                               bitset_set(bs_ukilldesc, BLOCK_IDX_MAP(rss, irn));
-                       else
-                               continue;
-
-                       for (k = ARR_LEN_SAFE(node->descendants) - 1; k >= 0; --k) {
-                               if (! is_Sink(node->descendants[k]))
-                                       bitset_set(bs_ukilldesc, BLOCK_IDX_MAP(rss, node->descendants[k]));
-                       }
-               }
-
-               /* for all v in sat_vals */
-               for (j = 0; j < n; ++j) {
-                       ir_node   *v_irn   = val_arr[j];
-                       rss_irn_t *v       = get_rss_irn(rss, v_irn);
-                       unsigned  v_height = get_irn_height(rss->h, v_irn);
-                       int       omega1, omega2, is_pkiller;
-
-                       /* v cannot be serialized with itself
-                        * ignore nodes where serialization does not help */
-                       if (i == j || IS_UNSERIALIZABLE_NODE(v)) {
-#ifdef DEBUG_libfirm
-                               if (i != j)
-                                       DBG((rss->dbg, LEVEL_3, "\t\t\t%+F considered unserializable\n", v->irn));
-#endif
-                               continue;
-                       }
-
-                       /* get descendants of v */
-                       bitset_clear_all(bs_vdesc);
-                       bitset_set(bs_vdesc, BLOCK_IDX_MAP(rss, v_irn));
-                       for (k = ARR_LEN_SAFE(v->descendants) - 1; k >= 0; --k) {
-                               if (! is_Sink(v->descendants[k]))
-                                       bitset_set(bs_vdesc, BLOCK_IDX_MAP(rss, v->descendants[k]));
-                       }
-
-                       /* if v is in pkiller(u) */
-                       is_pkiller = plist_has_value(u->pkiller_list, v_irn);
-
-                       /* for all vv in pkiller(u) */
-                       foreach_plist(u->pkiller_list, el) {
-                               ir_node *vv_irn  = (ir_node*)plist_element_get_value(el);
-                               int     add_edge;
-
-                               if (is_Sink(vv_irn) || is_cfop(vv_irn))
-                                       continue;
-
-                               if (is_pkiller)
-                                       add_edge = vv_irn != v_irn && skip_Proj(vv_irn) != skip_Proj(v_irn);
-                               else
-                                       add_edge = ! heights_reachable_in_block(rss->h, skip_Proj(vv_irn), skip_Proj(v_irn));
-
-                               /*
-                                       As we add an edge from vv -> v, we have to make sure,
-                                       that there exists no path from v to vv.
-                               */
-
-                               if (add_edge) {
-                                       unsigned vv_height = get_irn_height(rss->h, vv_irn);
-                                       unsigned critical_path_cost;
-                                       unsigned mu1, mu2;
-
-                                       /*
-                                               mu1 = | descendants(v) cut sat_vals |
-                                               the number of saturating values which cannot
-                                               be simultaneously alive with u
-                                       */
-                                       bitset_copy(bs_tmp, bs_vdesc);
-                                       bitset_and(bs_tmp, bs_sv);
-                                       mu1 = bitset_popcount(bs_tmp);
-
-                                       /*
-                                               mu2 = | accum_desc_all_pkiller(u) without descendants(v) |
-                                       */
-                                       if (is_pkiller) {
-                                               bitset_copy(bs_tmp, bs_ukilldesc);
-                                               bitset_andnot(bs_tmp, bs_vdesc);
-                                               mu2 = bitset_popcount(bs_tmp);
-                                       }
-                                       else {
-                                               mu2 = 0;
-                                       }
-
-                                       /* omega1 = mu1 - mu2 */
-                                       omega1 = mu1 - mu2;
-
-                                       if (omega1 != 0)
-                                               has_omega1 = 1;
-
-                                       /* omega2 = increase of critical path */
-                                       critical_path_cost =
-                                               v_height                        /* longest path from v to sink */
-                                               + rss->max_height - vv_height   /* longest path from source to vv */
-                                               + 1;                            /* edge */
-
-                                       /*
-                                               If critical_path_cost > max_height -> the new edge
-                                               would increase the longest critical path by the difference.
-                                       */
-                                       omega2 = critical_path_cost > rss->max_height ? critical_path_cost - rss->max_height : 0;
-
-                                       /* this keeps track of the edge with the best benefit */
-                                       if (omega1 >= num_regs - n && omega1 < best_benefit) {
-                                               min_benefit_edge.src = v_irn;
-                                               min_benefit_edge.tgt = vv_irn;
-
-                                               ser_u_omega1 = u;
-                                               ser_v_omega1 = v;
-
-                                               best_benefit    = omega1;
-                                               ser->new_killer = is_pkiller;
-                                       }
-
-                                       /* this keeps track of the edge with the best omega1 costs where omega2 == 0 */
-                                       if (omega2 == 0 && omega1 >= num_regs - n && omega1 < best_benefit_omega20) {
-                                               min_omega20_edge.src = v_irn;
-                                               min_omega20_edge.tgt = vv_irn;
-
-                                               ser_u_omega20 = u;
-                                               ser_v_omega20 = v;
-
-                                               best_benefit_omega20 = omega1;
-                                               ser->new_killer      = is_pkiller;
-                                       }
-
-                                       best_omega2 = MIN(best_omega2, omega2);
-
-                                       DBG((rss->dbg, LEVEL_2, "\t\tfound %+F -> %+F (w1 %d, w2 %d)\n",
-                                               v_irn, vv_irn, omega1, omega2));
-                               } /* if add_edge */
-                       } /* for all vv in pkiller(u) */
-               } /* for all v in sat_vals */
-       } /* for all u in sat_vals */
-
-       if (! has_omega1)
-               return NULL;
-
-       if (best_omega2 == 0) {
-               ser->u         = ser_u_omega20;
-               ser->v         = ser_v_omega20;
-               ser->edge->src = min_omega20_edge.src;
-               ser->edge->tgt = min_omega20_edge.tgt;
-               ser->omega1    = best_benefit_omega20;
-               ser->omega2    = best_omega2;
-       }
-       else {
-               ser->u         = ser_u_omega1;
-               ser->v         = ser_v_omega1;
-               ser->edge->src = min_benefit_edge.src;
-               ser->edge->tgt = min_benefit_edge.tgt;
-               ser->omega1    = best_benefit;
-               ser->omega2    = best_omega2;
-       }
-
-       return ser;
-
-#undef IS_UNSERIALIZABLE_NODE
-}
-
-/**
- * Perform the value serialization heuristic and add all
- * computed serialization edges as dependencies to the irg.
- */
-static void perform_value_serialization_heuristic(rss_t *rss)
-{
-       unsigned available_regs, iteration;
-       dvg_t    dvg;
-       ir_nodeset_t *sat_vals;
-       pset *ser_set = new_pset(cmp_rss_edges, 20);
-
-       available_regs = be_get_n_allocatable_regs(rss->irg, rss->cls);
-
-       DBG((rss->dbg, LEVEL_1, "\n\t#available regs: %d\n\n", available_regs));
-
-       /*
-               At first we need to compute the disjoint value DAG (DVG = {V, E_dv}).
-               V    = set of all nodes we are currently interested in
-               E_dv = there is an edge from u to v iff v is a descendant of killer(u), forall u, v in V
-       */
-       ir_nodeset_init_size(&dvg.nodes, plist_count(rss->nodes));
-       dvg.edges = new_pset(cmp_rss_edges, plist_count(rss->nodes) * 5);
-       compute_dvg(rss, &dvg);
-
-       /*
-               Then we perform the heuristic serialization algorithm
-               on the DVG which gives us all necessary serialization
-               edges.
-       */
-       DBG((rss->dbg, LEVEL_1, "\tcomputing maximal antichain:\n"));
-       iteration = 0;
-       sat_vals  = compute_maximal_antichain(rss, &dvg, iteration++);
-       while (sat_vals && (ir_nodeset_size(sat_vals) > available_regs)) {
-               serialization_t *ser, best_ser;
-               rss_edge_t      *edge = OALLOC(phase_obst(&rss->ph), rss_edge_t);
-               ir_node         *dep_src, *dep_tgt;
-
-               best_ser.edge = edge;
-               ser = compute_best_admissible_serialization(rss, sat_vals, &best_ser, available_regs);
-
-               DBG((rss->dbg, LEVEL_1, "\tcurrent register saturation %d, target %d\n", ir_nodeset_size(sat_vals), available_regs));
-
-               if (! ser) {
-                       DBG((rss->dbg, LEVEL_1, "\tno RS improving serialization found, breaking at iteration %d\n", iteration));
-                       break;
-               }
-
-               /* Insert the serialization as dependency edge into the irg. */
-               DBG((rss->dbg, LEVEL_1, "\tserializing %+F -> %+F with edge %+F -> %+F and cost %d, %d\n",
-                       ser->u->irn, ser->v->irn, ser->edge->src, ser->edge->tgt, ser->omega1, ser->omega2));
-
-               if (pset_find(ser_set, ser->edge, HASH_RSS_EDGE(ser->edge)))
-                       ir_printf("WARNING: serialization %+F -> %+F computed twice!\n", ser->edge->src, ser->edge->tgt);
-
-
-               pset_insert(ser_set, ser->edge, HASH_RSS_EDGE(ser->edge));
-
-               /* update the dvg */
-               update_dvg(rss, &dvg, ser->v, ser->u);
-               update_dvg(rss, &dvg, get_rss_irn(rss, ser->edge->src), get_rss_irn(rss, ser->edge->tgt));
-               if (sat_vals != NULL) {
-                       ir_nodeset_destroy(sat_vals);
-                       free(sat_vals);
-               }
-
-               dep_src = skip_Proj(ser->edge->src);
-               dep_tgt = ser->edge->tgt;
-               add_irn_dep(dep_src, dep_tgt);
-
-               /* Update descendants, consumer and pkillers of the target */
-               update_node_info(rss, ser->edge->tgt, ser->edge->src);
-
-               /* TODO: try to find a cheaper way for updating height information */
-               rss->max_height = heights_recompute_block(rss->h, rss->block);
-
-               /* Recompute the antichain for next serialization */
-               DBG((rss->dbg, LEVEL_1, "\tre-computing maximal antichain:\n"));
-               sat_vals = compute_maximal_antichain(rss, &dvg, iteration++);
-       }
-
-       ir_nodeset_destroy(&dvg.nodes);
-       del_pset(dvg.edges);
-}
-
-/**
- * Do initial calculations for a block.
- */
-static void process_block(ir_node *block, void *env)
-{
-       rss_t *rss = (rss_t*)env;
-       int   i, n;
-       const ir_edge_t *edge;
-
-       phase_init(&rss->ph, rss->irg, init_rss_irn);
-
-       DBG((rss->dbg, LEVEL_1, "preprocessing block %+F\n", block));
-       rss->block = block;
-
-       /* build an index map for all nodes in the current block */
-       i            = 0;
-       n            = get_irn_n_edges(block);
-       NEW_ARR_A(int, rss->idx_map, n);
-       foreach_out_edge(block, edge) {
-               ir_node *irn      = get_edge_src_irn(edge);
-               rss->idx_map[i++] = get_irn_idx(irn);
-       }
-       qsort(rss->idx_map, n, sizeof(rss->idx_map[0]), cmp_int);
-       rss->max_height = heights_recompute_block(rss->h, block);
-
-       /* loop over all register classes */
-       for (i = rss->arch_env->n_register_classes - 1; i >= 0; --i) {
-               const arch_register_class_t *cls = &rss->arch_env->register_classes[i];
-
-               rss->cls = cls;
-               DBG((rss->dbg, LEVEL_1, "register class %s\n", arch_register_class_name(cls)));
-
-               /* Get all live value at end of Block having current register class */
-               ir_nodeset_init(&rss->live_block);
-               be_liveness_end_of_block(rss->liveness, rss->cls, rss->block, &rss->live_block);
-
-               /* reset the list of interesting nodes */
-               plist_clear(rss->nodes);
-               plist_insert_back(rss->nodes, _sink);
-
-               /* collect all nodes having a certain register class */
-               foreach_out_edge(block, edge) {
-                       ir_node *irn  = get_edge_src_irn(edge);
-                       ir_mode *mode = get_irn_mode(irn);
-
-                       /*
-                               We skip:
-                               - mode_T nodes (the projs are asked)
-                               - mode_X nodes (control flow nodes are always scheduled last)
-                               - Keeps (they are always immediately scheduled)
-                               - Phi (same as Keep)
-                       */
-                       if (mode == mode_T || mode == mode_X || is_Phi(irn))
-                               continue;
-
-                       /*
-                               In case of a proj, we skip
-                               - Barrier (they are a Barrier :)
-                               - Start
-                               - the Proj itself, as it's scheduled always with it's super node
-                       */
-                       if (is_Proj(irn)) {
-                               ir_node *pred = get_Proj_pred(irn);
-                               if (be_is_Barrier(pred) || be_is_Start(pred))
-                                       continue;
-                       }
-
-                       /* calculate the descendants and consumer for each node in the block */
-                       collect_node_info(rss, skip_Proj(irn));
-
-                       if (be_is_Keep(irn))
-                               continue;
-
-                       if (!arch_irn_is_ignore(irn) &&
-                                       arch_get_irn_reg_class_out(irn) == cls) {
-                               plist_insert_back(rss->nodes, skip_Proj(irn));
-                       }
-                       //}
-               }
-
-               /* compute the potential killing set PK(G) */
-               compute_pkill_set(rss);
-
-               /* compute the killing function k* */
-               compute_killing_function(rss);
-
-               /*
-                       Compute the heuristic value serialization and
-                       add the necessary dependencies to the irg.
-               */
-               perform_value_serialization_heuristic(rss);
-
-               ir_nodeset_destroy(&rss->live_block);
-       }
-
-       phase_deinit(&rss->ph);
-}
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_schedrss);
-void be_init_schedrss(void)
-{
-       lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
-       lc_opt_entry_t *sched_grp = lc_opt_get_grp(be_grp, "sched");
-       lc_opt_entry_t *rss_grp = lc_opt_get_grp(sched_grp, "rss");
-
-       lc_opt_add_table(rss_grp, rss_option_table);
-}
-
-/**
- * Preprocess the irg for scheduling.
- */
-void rss_schedule_preparation(ir_graph *irg)
-{
-       rss_t rss;
-
-       FIRM_DBG_REGISTER(rss.dbg, "firm.be.sched.rss");
-
-       //firm_dbg_set_mask(rss.dbg, LEVEL_1 | LEVEL_2 | LEVEL_3);
-
-       init_rss_special_nodes(irg);
-
-       rss.irg      = irg;
-       rss.arch_env = be_get_irg_arch_env(irg);
-       rss.abi      = be_get_irg_abi(irg);
-       rss.h        = heights_new(irg);
-       rss.nodes    = plist_new();
-       rss.opts     = &rss_options;
-       rss.liveness = be_liveness(irg);
-       be_liveness_assure_sets(rss.liveness);
-       irg_block_walk_graph(irg, NULL, process_block, &rss);
-       heights_free(rss.h);
-       plist_free(rss.nodes);
-       be_liveness_free(rss.liveness);
-
-       if (be_get_irg_options(irg)->dump_flags & DUMP_SCHED)
-               dump_ir_graph(irg, "rss");
-}
diff --git a/ir/be/beschedrss.h b/ir/be/beschedrss.h
deleted file mode 100644 (file)
index 3b4f632..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief       Implementation of a register saturating list scheduler.
- * @author      Christian Wuerdig
- * @date        06.09.2006
- * @version     $Id$
- *
- * Implementation of a register saturating list scheduler
- * as described in: Sid-Ahmed-Ali Touati
- * Register Saturation in Superscalar and VLIW Codes
- */
-#ifndef FIRM_BE_BESCHEDRSS_H
-#define FIRM_BE_BESCHEDRSS_H
-
-#include "beirg.h"
-
-/**
- * Perform RSS schedule preprocessing for the given irg.
- * @param irg   The graph
- */
-void rss_schedule_preparation(ir_graph *irg);
-
-#endif