X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeschedregpress.c;h=42e0abe9999b09810f369ebc3ba6d4ce7b125995;hb=6f068af98daa4725d60e5d23a8f98ec2841cfa44;hp=fa620dbe95e262693e677aa4fee1a6e126bf44bd;hpb=65a52a96e8ab7ed601d7f98c516d37c46b674b4a;p=libfirm diff --git a/ir/be/beschedregpress.c b/ir/be/beschedregpress.c index fa620dbe9..42e0abe99 100644 --- a/ir/be/beschedregpress.c +++ b/ir/be/beschedregpress.c @@ -35,24 +35,20 @@ #include "besched.h" #include "belistsched.h" #include "benode.h" +#include "bemodule.h" -typedef struct _usage_stats_t { +typedef struct usage_stats_t { ir_node *irn; - struct _usage_stats_t *next; + struct usage_stats_t *next; int max_hops; int uses_in_block; /**< Number of uses inside the current block. */ int already_consumed; /**< Number of insns using this value already 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,55 +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; -} - -static inline int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn) -{ - int res = -1; - - if (sel->to_appear_in_schedule) - res = sel->to_appear_in_schedule(block_env, irn); - - return res >= 0 ? res : (to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_CopyKeep(irn) || be_is_Start(irn)); + 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 (must_appear_in_schedule(env->main_env->vtab, env, irn)) { - int i, n; + int i, n; + if (is_Proj(irn) + || (arch_irn_get_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 (must_appear_in_schedule(env->main_env->vtab, env, 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++; } } @@ -228,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) @@ -264,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 (must_appear_in_schedule(env->main_env->vtab, env, op)) - sum += compute_max_hops(env, op); + if (is_Proj(op) + || (arch_irn_get_flags(op) & arch_irn_flags_not_scheduled)) + continue; + + sum += compute_max_hops(env, op); } sum += get_result_hops_sum(env, irn); @@ -273,14 +257,12 @@ 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); @@ -315,15 +297,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, /* to_appear_in_schedule */ - 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); +}