Use foreach_ir_nodeset() instead of reimplementing it.
[libfirm] / ir / be / beschedregpress.c
index 1d01534..c2f06b4 100644 (file)
@@ -22,7 +22,6 @@
  * @brief       Register pressure node selector.
  * @author      Sebastian Hack
  * @date        29.08.2006
- * @version     $Id$
  */
 #include "config.h"
 
 #include "iredges_t.h"
 #include "irgwalk.h"
 #include "irtools.h"
+#include "util.h"
 
 #include "besched.h"
 #include "belistsched.h"
 #include "benode.h"
+#include "bemodule.h"
 
 
 typedef struct usage_stats_t {
@@ -46,13 +47,8 @@ typedef struct usage_stats_t {
                                                        scheduled. */
 } usage_stats_t;
 
-typedef struct {
-       const list_sched_selector_t *vtab;
-} reg_pressure_main_env_t;
-
 typedef struct {
        struct obstack obst;
-       const reg_pressure_main_env_t *main_env;
        usage_stats_t *root;
        ir_nodeset_t already_scheduled;
 } reg_pressure_selector_env_t;
@@ -88,7 +84,7 @@ static int cmp_usage(const void *a, const void *b)
 
 static inline usage_stats_t *get_or_set_usage_stats(reg_pressure_selector_env_t *env, ir_node *irn)
 {
-       usage_stats_t *us = get_irn_link(irn);
+       usage_stats_t *us = (usage_stats_t*)get_irn_link(irn);
 
        if (!us) {
                us                   = OALLOC(&env->obst, usage_stats_t);
@@ -105,7 +101,7 @@ static inline usage_stats_t *get_or_set_usage_stats(reg_pressure_selector_env_t
 
 static inline usage_stats_t *get_usage_stats(ir_node *irn)
 {
-       usage_stats_t *us = get_irn_link(irn);
+       usage_stats_t *us = (usage_stats_t*)get_irn_link(irn);
        assert(us && "This node must have usage stats");
        return us;
 }
@@ -171,45 +167,40 @@ static int compute_max_hops(reg_pressure_selector_env_t *env, ir_node *irn)
        return res;
 }
 
-static void *reg_pressure_graph_init(const list_sched_selector_t *vtab, ir_graph *irg)
+static void *reg_pressure_graph_init(ir_graph *irg)
 {
-       reg_pressure_main_env_t *main_env = XMALLOC(reg_pressure_main_env_t);
-
-       main_env->vtab = vtab;
        irg_walk_graph(irg, firm_clear_link, NULL, NULL);
 
-       return main_env;
+       return NULL;
 }
 
 static void *reg_pressure_block_init(void *graph_env, ir_node *bl)
 {
        ir_node *irn;
        reg_pressure_selector_env_t *env = XMALLOC(reg_pressure_selector_env_t);
+       (void) graph_env;
 
        obstack_init(&env->obst);
        ir_nodeset_init(&env->already_scheduled);
        env->root              = NULL;
-       env->main_env          = graph_env;
 
        /*
        * Collect usage statistics.
        */
        sched_foreach(bl, irn) {
-               if (to_appear_in_schedule(irn)) {
-                       int i, n;
+               int i, n;
+               if (is_Proj(irn)
+                               || (arch_get_irn_flags(irn) & arch_irn_flags_not_scheduled))
+                       continue;
 
-                       for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
-                               //ir_node *op = get_irn_n(irn, i);
-                               if (to_appear_in_schedule(irn)) {
-                                       usage_stats_t *us = get_or_set_usage_stats(env, irn);
+               for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
+                       usage_stats_t *us = get_or_set_usage_stats(env, irn);
 #if 0 /* Liveness is not computed here! */
-                                       if (is_live_end(bl, op))
-                                               us->uses_in_block = 99999;
-                                       else
+                       if (is_live_end(bl, op))
+                               us->uses_in_block = 99999;
+                       else
 #endif
-                                               us->uses_in_block++;
-                               }
-                       }
+                               us->uses_in_block++;
                }
        }
 
@@ -218,7 +209,7 @@ static void *reg_pressure_block_init(void *graph_env, ir_node *bl)
 
 static void reg_pressure_block_free(void *block_env)
 {
-       reg_pressure_selector_env_t *env = block_env;
+       reg_pressure_selector_env_t *env = (reg_pressure_selector_env_t*)block_env;
        usage_stats_t *us;
 
        for (us = env->root; us; us = us->next)
@@ -254,8 +245,11 @@ static inline int reg_pr_costs(reg_pressure_selector_env_t *env, ir_node *irn)
        for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
                ir_node *op = get_irn_n(irn, i);
 
-               if (to_appear_in_schedule(op))
-                       sum += compute_max_hops(env, op);
+               if (is_Proj(op)
+                   || (arch_get_irn_flags(op) & arch_irn_flags_not_scheduled))
+                       continue;
+
+               sum += compute_max_hops(env, op);
        }
 
        sum += get_result_hops_sum(env, irn);
@@ -263,19 +257,16 @@ static inline int reg_pr_costs(reg_pressure_selector_env_t *env, ir_node *irn)
        return sum;
 }
 
-static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set,
-                                    ir_nodeset_t *live_set)
+static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set)
 {
        ir_nodeset_iterator_t iter;
-       reg_pressure_selector_env_t *env = block_env;
+       reg_pressure_selector_env_t *env = (reg_pressure_selector_env_t*)block_env;
        ir_node *irn, *res     = NULL;
        int curr_cost          = INT_MAX;
-       (void) live_set;
 
        assert(ir_nodeset_size(ready_set) > 0);
 
-       ir_nodeset_iterator_init(&iter, ready_set);
-       while ( (irn = ir_nodeset_iterator_next(&iter)) != NULL) {
+       foreach_ir_nodeset(ready_set, irn, iter) {
                /*
                Ignore branch instructions for the time being.
                They should only be scheduled if there is nothing else.
@@ -305,14 +296,22 @@ static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set,
        return res;
 }
 
-const list_sched_selector_t reg_pressure_selector = {
-       reg_pressure_graph_init,
-       reg_pressure_block_init,
-       reg_pressure_select,
-       NULL,                    /* node_ready */
-       NULL,                    /* node_selected */
-       NULL,                    /* exectime */
-       NULL,                    /* latency */
-       reg_pressure_block_free,
-       free
-};
+static void sched_reg_pressure(ir_graph *irg)
+{
+       static const list_sched_selector_t reg_pressure_selector = {
+               reg_pressure_graph_init,
+               reg_pressure_block_init,
+               reg_pressure_select,
+               NULL,                    /* node_ready */
+               NULL,                    /* node_selected */
+               reg_pressure_block_free,
+               free
+       };
+       be_list_sched_graph(irg, &reg_pressure_selector);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_regpress)
+void be_init_sched_regpress(void)
+{
+       be_register_scheduler("regpress", sched_reg_pressure);
+}