X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeschedregpress.c;h=e7d8eb6a6583e4fbed439ef5a34b89e6a812bc22;hb=5ce100386043a57a864379c8b6d8e6bb95a98596;hp=c7fe6a930110a712ad1d0c0475750e5ce55571ab;hpb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;p=libfirm diff --git a/ir/be/beschedregpress.c b/ir/be/beschedregpress.c index c7fe6a930..e7d8eb6a6 100644 --- a/ir/be/beschedregpress.c +++ b/ir/be/beschedregpress.c @@ -22,7 +22,6 @@ * @brief Register pressure node selector. * @author Sebastian Hack * @date 29.08.2006 - * @version $Id$ */ #include "config.h" @@ -31,10 +30,12 @@ #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,46 +47,13 @@ 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; -#if 0 -/* -* Ugly global variable for the compare function -* since qsort(3) does not pass an extra pointer. -*/ -static ir_node *curr_bl = NULL; - -static int cmp_usage(const void *a, const void *b) -{ - struct trivial_sched_env *env; - const ir_node *p = a; - const ir_node *q = b; - int res = 0; - - res = is_live_end(env->curr_bl, a) - is_live_end(env->curr_bl, b); - - /* - * One of them is live at the end of the block. - * Then, that one shall be scheduled at after the other - */ - if (res != 0) - return res; - - - return res; -} -#endif - static inline usage_stats_t *get_or_set_usage_stats(reg_pressure_selector_env_t *env, ir_node *irn) { usage_stats_t *us = (usage_stats_t*)get_irn_link(irn); @@ -156,8 +124,6 @@ static int compute_max_hops(reg_pressure_selector_env_t *env, ir_node *irn) ir_graph *irg = get_irn_irg(bl); int res = 0; - const ir_edge_t *edge; - foreach_out_edge(irn, edge) { ir_node *user = get_edge_src_irn(edge); unsigned visited_nr = get_irg_visited(irg) + 1; @@ -171,45 +137,29 @@ 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 = (reg_pressure_main_env_t*)graph_env; /* * Collect usage statistics. */ sched_foreach(bl, irn) { - if (to_appear_in_schedule(irn)) { - int i, n; - - 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); -#if 0 /* Liveness is not computed here! */ - if (is_live_end(bl, op)) - us->uses_in_block = 99999; - else -#endif - us->uses_in_block++; - } - } + for (int i = 0, n = get_irn_arity(irn); i < n; ++i) { + usage_stats_t *us = get_or_set_usage_stats(env, irn); + us->uses_in_block++; } } @@ -233,8 +183,6 @@ static int get_result_hops_sum(reg_pressure_selector_env_t *env, ir_node *irn) { int res = 0; if (get_irn_mode(irn) == mode_T) { - const ir_edge_t *edge; - foreach_out_edge(irn, edge) res += get_result_hops_sum(env, get_edge_src_irn(edge)); } @@ -254,8 +202,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 +214,15 @@ 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 = (reg_pressure_selector_env_t*)block_env; - ir_node *irn, *res = NULL; - int curr_cost = INT_MAX; - (void) live_set; + ir_node *res = NULL; + int curr_cost = INT_MAX; 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. @@ -295,9 +242,7 @@ static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set, */ if (!res) { - ir_nodeset_iterator_init(&iter, ready_set); - res = ir_nodeset_iterator_next(&iter); - + res = ir_nodeset_first(ready_set); assert(res && "There must be a node scheduled."); } @@ -305,14 +250,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, ®_pressure_selector); +} + +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_regpress) +void be_init_sched_regpress(void) +{ + be_register_scheduler("regpress", sched_reg_pressure); +}