X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbespillutil.c;h=ccef797c0b3c49348f3a1a494456bb20f9a9de3f;hb=0e4318adc38a54110c1b1f7f1d5edc0ee2c78170;hp=d7b1e47d3c1cfd011145526690b7d0a583eb0ed3;hpb=ea6e9be0bea5ad0079ab09d5e494cf7b5c889552;p=libfirm diff --git a/ir/be/bespillutil.c b/ir/be/bespillutil.c index d7b1e47d3..ccef797c0 100644 --- a/ir/be/bespillutil.c +++ b/ir/be/bespillutil.c @@ -106,12 +106,10 @@ struct spill_env_t { ir_nodeset_t mem_phis; /**< set of all spilled phis. */ ir_exec_freq *exec_freq; -#ifdef FIRM_STATISTICS unsigned spill_count; unsigned reload_count; unsigned remat_count; unsigned spilled_phi_count; -#endif }; /** @@ -162,12 +160,10 @@ spill_env_t *be_new_spill_env(ir_graph *irg) env->exec_freq = be_get_irg_exec_freq(irg); obstack_init(&env->obst); -#ifdef FIRM_STATISTICS env->spill_count = 0; env->reload_count = 0; env->remat_count = 0; env->spilled_phi_count = 0; -#endif return env; } @@ -255,14 +251,6 @@ void be_add_reload2(spill_env_t *env, ir_node *to_spill, ir_node *before, assert(!is_Proj(before) && !be_is_Keep(before)); - /* adjust before point to not be in the epilog */ - while (true) { - ir_node *before_prev = sched_prev(before); - if (! (arch_irn_get_flags(before_prev) & arch_irn_flags_epilog)) - break; - before = sched_prev(before); - } - /* put reload into list */ rel = OALLOC(&env->obst, reloader_t); rel->next = info->reloaders; @@ -311,8 +299,7 @@ static ir_node *determine_spill_point(ir_node *node) node = skip_Proj(node); while (true) { ir_node *next = sched_next(node); - if (!is_Phi(next) && !be_is_Keep(next) && !be_is_CopyKeep(next) - && !(arch_irn_get_flags(next) & arch_irn_flags_prolog)) + if (!is_Phi(next) && !be_is_Keep(next) && !be_is_CopyKeep(next)) break; node = next; } @@ -420,7 +407,7 @@ static void spill_irn(spill_env_t *env, spill_info_t *spillinfo) if (!sched_is_scheduled(insn)) { /* override spillinfos or create a new one */ ir_graph *irg = get_irn_irg(to_spill); - spillinfo->spills->spill = new_r_NoMem(irg); + spillinfo->spills->spill = get_irg_no_mem(irg); DB((dbg, LEVEL_1, "don't spill %+F use NoMem\n", to_spill)); return; } @@ -429,16 +416,11 @@ static void spill_irn(spill_env_t *env, spill_info_t *spillinfo) spill = spillinfo->spills; for ( ; spill != NULL; spill = spill->next) { ir_node *after = spill->after; - ir_node *block = get_block(after); - after = determine_spill_point(after); - spill->spill = be_spill(block, to_spill); - sched_add_after(skip_Proj(after), spill->spill); + spill->spill = arch_env_new_spill(env->arch_env, to_spill, after); DB((dbg, LEVEL_1, "\t%+F after %+F\n", spill->spill, after)); -#ifdef FIRM_STATISTICS env->spill_count++; -#endif } DBG((dbg, LEVEL_1, "\n")); } @@ -486,9 +468,7 @@ static void spill_phi(spill_env_t *env, spill_info_t *spillinfo) sched_add_after(block, spill->spill); spillinfo->spills = spill; -#ifdef FIRM_STATISTICS env->spilled_phi_count++; -#endif for (i = 0; i < arity; ++i) { ir_node *arg = get_irn_n(phi, i); @@ -597,7 +577,7 @@ static int check_remat_conditions_costs(spill_env_t *env, return REMAT_COST_INFINITE; } /* never rematerialize a node which modifies the flags. - * (would be better to test wether the flags are actually live at point + * (would be better to test whether the flags are actually live at point * reloader...) */ if (arch_irn_is(insn, modify_flags)) { @@ -631,7 +611,7 @@ static int check_remat_conditions_costs(spill_env_t *env, /** * Re-materialize a node. * - * @param senv the spill environment + * @param env the spill environment * @param spilled the node that was spilled * @param reloader a irn that requires a reload */ @@ -656,10 +636,8 @@ static ir_node *do_remat(spill_env_t *env, ir_node *spilled, ir_node *reloader) ins[i] = arg; } else { ins[i] = do_remat(env, arg, reloader); -#ifdef FIRM_STATISTICS - /* don't count the recursive call as remat */ - env->remat_count--; -#endif + /* don't count the argument rematerialization as an extra remat */ + --env->remat_count; } } @@ -676,9 +654,7 @@ static ir_node *do_remat(spill_env_t *env, ir_node *spilled, ir_node *reloader) /* insert in schedule */ sched_reset(res); sched_add_before(reloader, res); -#ifdef FIRM_STATISTICS - env->remat_count++; -#endif + ++env->remat_count; } return res; @@ -734,6 +710,39 @@ double be_get_reload_costs_on_edge(spill_env_t *env, ir_node *to_spill, return be_get_reload_costs(env, to_spill, before); } +ir_node *be_new_spill(ir_node *value, ir_node *after) +{ + ir_graph *irg = get_irn_irg(value); + ir_node *frame = get_irg_frame(irg); + const arch_register_class_t *cls = arch_get_irn_reg_class(value); + const arch_register_class_t *cls_frame = arch_get_irn_reg_class(frame); + ir_node *block = get_block(after); + ir_node *spill + = be_new_Spill(cls, cls_frame, block, frame, value); + + sched_add_after(after, spill); + return spill; +} + +ir_node *be_new_reload(ir_node *value, ir_node *spill, ir_node *before) +{ + ir_graph *irg = get_irn_irg(value); + ir_node *frame = get_irg_frame(irg); + ir_node *block = get_block(before); + const arch_register_class_t *cls = arch_get_irn_reg_class(value); + const arch_register_class_t *cls_frame = arch_get_irn_reg_class(frame); + ir_mode *mode = get_irn_mode(value); + ir_node *reload; + + assert(be_is_Spill(spill) || is_Phi(spill)); + assert(get_irn_mode(spill) == mode_M); + + reload = be_new_Reload(cls, cls_frame, block, frame, spill, mode); + sched_add_before(before, reload); + + return reload; +} + /* * ___ _ ____ _ _ * |_ _|_ __ ___ ___ _ __| |_ | _ \ ___| | ___ __ _ __| |___ @@ -772,7 +781,7 @@ static void determine_spill_costs(spill_env_t *env, spill_info_t *spillinfo) spill_t *spill = OALLOC(&env->obst, spill_t); spill->after = NULL; spill->next = NULL; - spill->spill = new_r_NoMem(irg); + spill->spill = get_irg_no_mem(irg); spillinfo->spills = spill; spillinfo->spill_costs = 0; @@ -880,12 +889,11 @@ void be_insert_spills_reloads(spill_env_t *env) /* process each spilled node */ foreach_set(env->spills, spill_info_t*, si) { - reloader_t *rld; ir_node *to_spill = si->to_spill; - ir_mode *mode = get_irn_mode(to_spill); ir_node **copies = NEW_ARR_F(ir_node*, 0); double all_remat_costs = 0; /** costs when we would remat all nodes */ - int force_remat = 0; + bool force_remat = false; + reloader_t *rld; DBG((dbg, LEVEL_1, "\nhandling all reloaders of %+F:\n", to_spill)); @@ -945,7 +953,7 @@ void be_insert_spills_reloads(spill_env_t *env) if (all_remat_costs < 0) { DBG((dbg, LEVEL_1, "\nforcing remats of all reloaders (%f)\n", all_remat_costs)); - force_remat = 1; + force_remat = true; } } @@ -966,11 +974,9 @@ void be_insert_spills_reloads(spill_env_t *env) /* create a reload, use the first spill for now SSA * reconstruction for memory comes below */ assert(si->spills != NULL); - copy = be_reload(si->reload_cls, rld->reloader, mode, - si->spills->spill); -#ifdef FIRM_STATISTICS + copy = arch_env_new_reload(env->arch_env, si->to_spill, + si->spills->spill, rld->reloader); env->reload_count++; -#endif } DBG((dbg, LEVEL_1, " %+F of %+F before %+F\n", @@ -1043,7 +1049,7 @@ void be_insert_spills_reloads(spill_env_t *env) be_timer_pop(T_RA_SPILL_APPLY); } -BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spill); +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spill) void be_init_spill(void) { FIRM_DBG_REGISTER(dbg, "firm.be.spill");