X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbespillbelady.c;h=768ece1d25f56daa14d35a8aa873f5f4e5c33e0e;hb=f2c2e45eb4e677fef5bf6a8e418b2a22441172d5;hp=77ef39513385b34697125a88b3108a4e6b8154e2;hpb=f6aeac6a547a52beb3cb663c5e63c05c9c3728ea;p=libfirm diff --git a/ir/be/bespillbelady.c b/ir/be/bespillbelady.c index 77ef39513..768ece1d2 100644 --- a/ir/be/bespillbelady.c +++ b/ir/be/bespillbelady.c @@ -24,9 +24,7 @@ * @date 20.09.2005 * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include @@ -85,7 +83,6 @@ typedef struct _workset_t { } workset_t; static struct obstack obst; -static const arch_env_t *arch_env; static const arch_register_class_t *cls; static const be_lv_t *lv; static be_loopana_t *loop_ana; @@ -184,7 +181,7 @@ static void workset_insert(workset_t *workset, ir_node *val, bool spilled) loc_t *loc; int i; /* check for current regclass */ - assert(arch_irn_consider_in_reg_alloc(arch_env, cls, val)); + assert(arch_irn_consider_in_reg_alloc(cls, val)); /* check if val is already contained */ for (i = 0; i < workset->len; ++i) { @@ -217,7 +214,7 @@ static void workset_clear(workset_t *workset) /** * Removes the value @p val from the workset if present. */ -static INLINE void workset_remove(workset_t *workset, ir_node *val) +static inline void workset_remove(workset_t *workset, ir_node *val) { int i; for(i = 0; i < workset->len; ++i) { @@ -228,7 +225,7 @@ static INLINE void workset_remove(workset_t *workset, ir_node *val) } } -static INLINE const loc_t *workset_contains(const workset_t *ws, +static inline const loc_t *workset_contains(const workset_t *ws, const ir_node *val) { int i; @@ -279,15 +276,14 @@ static void *new_block_info(void) /** * @return The distance to the next use or 0 if irn has dont_spill flag set */ -static INLINE unsigned get_distance(ir_node *from, unsigned from_step, +static inline unsigned get_distance(ir_node *from, unsigned from_step, const ir_node *def, int skip_from_uses) { be_next_use_t use; - int flags = arch_irn_get_flags(arch_env, def); unsigned costs; unsigned time; - assert(! (flags & arch_irn_flags_ignore)); + assert(!arch_irn_is_ignore(def)); use = be_get_next_use(uses, from, from_step, def, skip_from_uses); time = use.time; @@ -295,7 +291,7 @@ static INLINE unsigned get_distance(ir_node *from, unsigned from_step, return USES_INFINITY; /* We have to keep nonspillable nodes in the workingset */ - if (flags & arch_irn_flags_dont_spill) + if (arch_irn_get_flags(def) & arch_irn_flags_dont_spill) return 0; /* give some bonus to rematerialisable nodes */ @@ -319,8 +315,8 @@ static INLINE unsigned get_distance(ir_node *from, unsigned from_step, */ static void displace(workset_t *new_vals, int is_usage) { - ir_node **to_insert = alloca(n_regs * sizeof(to_insert[0])); - bool *spilled = alloca(n_regs * sizeof(spilled[0])); + ir_node **to_insert = ALLOCAN(ir_node*, n_regs); + bool *spilled = ALLOCAN(bool, n_regs); ir_node *val; int i; int len; @@ -483,13 +479,13 @@ static loc_t to_take_or_not_to_take(ir_node* first, ir_node *node, loc.node = node; loc.spilled = false; - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, node)) { + if (!arch_irn_consider_in_reg_alloc(cls, node)) { loc.time = USES_INFINITY; return loc; } /* We have to keep nonspillable nodes in the workingset */ - if (arch_irn_get_flags(arch_env, node) & arch_irn_flags_dont_spill) { + if (arch_irn_get_flags(node) & arch_irn_flags_dont_spill) { loc.time = 0; DB((dbg, DBG_START, " %+F taken (dontspill node)\n", node, loc.time)); return loc; @@ -511,7 +507,7 @@ static loc_t to_take_or_not_to_take(ir_node* first, ir_node *node, DB((dbg, DBG_START, " %+F taken (%u, live in all preds)\n", node, loc.time)); return loc; - } else if(available == AVAILABLE_NOWHERE || available == AVAILABLE_PARTLY) { + } else if(available == AVAILABLE_NOWHERE) { DB((dbg, DBG_START, " %+F not taken (%u, live in no pred)\n", node, loc.time)); loc.time = USES_INFINITY; @@ -554,7 +550,7 @@ static void decide_start_workset(const ir_node *block) /* check predecessors */ arity = get_irn_arity(block); - pred_worksets = alloca(sizeof(pred_worksets[0]) * arity); + pred_worksets = ALLOCAN(workset_t*, arity); all_preds_known = true; for(i = 0; i < arity; ++i) { ir_node *pred_block = get_Block_cfgpred_block(block, i); @@ -581,7 +577,7 @@ static void decide_start_workset(const ir_node *block) if (! is_Phi(node)) break; - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, node)) + if (!arch_irn_consider_in_reg_alloc(cls, node)) continue; if (all_preds_known) { @@ -593,7 +589,7 @@ static void decide_start_workset(const ir_node *block) loc = to_take_or_not_to_take(first, node, loop, available); if (! USES_IS_INFINITE(loc.time)) { - if (USES_IS_PENDING(loc.time) && !all_preds_known) + if (USES_IS_PENDING(loc.time)) ARR_APP1(loc_t, delayed, loc); else ARR_APP1(loc_t, starters, loc); @@ -616,7 +612,7 @@ static void decide_start_workset(const ir_node *block) loc = to_take_or_not_to_take(first, node, loop, available); if (! USES_IS_INFINITE(loc.time)) { - if (USES_IS_PENDING(loc.time) && !all_preds_known) + if (USES_IS_PENDING(loc.time)) ARR_APP1(loc_t, delayed, loc); else ARR_APP1(loc_t, starters, loc); @@ -638,35 +634,35 @@ static void decide_start_workset(const ir_node *block) qsort(delayed, ARR_LEN(delayed), sizeof(delayed[0]), loc_compare); for (i = 0; i < ARR_LEN(delayed) && free_slots > 0; ++i) { - //int p, arity; + int p, arity; loc_t *loc = & delayed[i]; -#if 0 - /* don't use values which are dead in a known predecessors - * to not induce unnecessary reloads */ - arity = get_irn_arity(block); - for (p = 0; p < arity; ++p) { - ir_node *pred_block = get_Block_cfgpred_block(block, p); - block_info_t *pred_info = get_block_info(pred_block); - - if (pred_info == NULL) - continue; - - if (!workset_contains(pred_info->end_workset, loc->node)) { - DB((dbg, DBG_START, - " delayed %+F not live at pred %+F\n", loc->node, - pred_block)); - goto skip_delayed; + if (!is_Phi(loc->node)) { + /* don't use values which are dead in a known predecessors + * to not induce unnecessary reloads */ + arity = get_irn_arity(block); + for (p = 0; p < arity; ++p) { + ir_node *pred_block = get_Block_cfgpred_block(block, p); + block_info_t *pred_info = get_block_info(pred_block); + + if (pred_info == NULL) + continue; + + if (!workset_contains(pred_info->end_workset, loc->node)) { + DB((dbg, DBG_START, + " delayed %+F not live at pred %+F\n", loc->node, + pred_block)); + goto skip_delayed; + } } } -#endif DB((dbg, DBG_START, " delayed %+F taken\n", loc->node)); ARR_APP1(loc_t, starters, *loc); loc->node = NULL; --free_slots; -// skip_delayed: -// ; + skip_delayed: + ; } } @@ -818,7 +814,7 @@ static void process_block(ir_node *block) workset_clear(new_vals); for(i = 0, arity = get_irn_arity(irn); i < arity; ++i) { ir_node *in = get_irn_n(irn, i); - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, in)) + if (!arch_irn_consider_in_reg_alloc(cls, in)) continue; /* (note that "spilled" is irrelevant here) */ @@ -833,12 +829,12 @@ static void process_block(ir_node *block) foreach_out_edge(irn, edge) { ir_node *proj = get_edge_src_irn(edge); - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, proj)) + if (!arch_irn_consider_in_reg_alloc(cls, proj)) continue; workset_insert(new_vals, proj, false); } } else { - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) + if (!arch_irn_consider_in_reg_alloc(cls, irn)) continue; workset_insert(new_vals, irn, false); } @@ -932,7 +928,7 @@ static void fix_block_borders(ir_node *block, void *data) assert(!l->spilled); /* we might have unknowns as argument for the phi */ - if (!arch_irn_consider_in_reg_alloc(arch_env, cls, node)) + if (!arch_irn_consider_in_reg_alloc(cls, node)) continue; } @@ -987,7 +983,6 @@ static void be_spill_belady(be_irg_t *birg, const arch_register_class_t *rcls) /* init belady env */ stat_ev_tim_push(); obstack_init(&obst); - arch_env = birg->main_env->arch_env; cls = rcls; lv = be_get_birg_liveness(birg); n_regs = cls->n_regs - be_put_ignore_regs(birg, cls, NULL);