X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbespillutil.c;h=ea4d2f04ca4ae63d0222c2b73a414cef1b5fadc8;hb=7142e46b9e442cacddec26387d8735444fb4421b;hp=bdae78cde9c0773051ff5456416ec9f8f83764aa;hpb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;p=libfirm diff --git a/ir/be/bespillutil.c b/ir/be/bespillutil.c index bdae78cde..ea4d2f04c 100644 --- a/ir/be/bespillutil.c +++ b/ir/be/bespillutil.c @@ -57,6 +57,7 @@ #include "bestatevent.h" #include "bessaconstr.h" #include "beirg.h" +#include "beirgmod.h" #include "beintlive_t.h" #include "bemodule.h" #include "be_t.h" @@ -231,29 +232,6 @@ void be_add_spill(spill_env_t *env, ir_node *to_spill, ir_node *after) spill_info->spills = spill; } -void be_add_remat(spill_env_t *env, ir_node *to_spill, ir_node *before, - ir_node *rematted_node) -{ - spill_info_t *spill_info; - reloader_t *reloader; - - spill_info = get_spillinfo(env, to_spill); - - /* add the remat information */ - reloader = OALLOC(&env->obst, reloader_t); - reloader->next = spill_info->reloaders; - reloader->reloader = before; - reloader->rematted_node = rematted_node; - reloader->remat_cost_delta = 0; /* We will never have a cost win over a - reload since we're not even allowed to - create a reload */ - - spill_info->reloaders = reloader; - - DBG((dbg, LEVEL_1, "creating spillinfo for %+F, will be rematerialized before %+F\n", - to_spill, before)); -} - void be_add_reload2(spill_env_t *env, ir_node *to_spill, ir_node *before, ir_node *can_spill_after, const arch_register_class_t *reload_cls, int allow_remat) @@ -277,6 +255,14 @@ 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; @@ -316,11 +302,17 @@ ir_node *be_get_end_of_block_insertion_point(const ir_node *block) return last; } -static ir_node *skip_keeps_phis(ir_node *node) +/** + * determine final spill position: it should be after all phis, keep nodes + * and behind nodes marked as prolog + */ +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)) + if (!is_Phi(next) && !be_is_Keep(next) && !be_is_CopyKeep(next) + && !(arch_irn_get_flags(next) & arch_irn_flags_prolog)) break; node = next; } @@ -387,7 +379,7 @@ void be_spill_phi(spill_env_t *env, ir_node *node) insert = be_get_end_of_block_insertion_point(pred_block); insert = sched_prev(insert); } else { - insert = skip_keeps_phis(arg); + insert = determine_spill_point(arg); } be_add_spill(env, arg, insert); @@ -439,7 +431,7 @@ static void spill_irn(spill_env_t *env, spill_info_t *spillinfo) ir_node *after = spill->after; ir_node *block = get_block(after); - after = skip_keeps_phis(after); + after = determine_spill_point(after); spill->spill = be_spill(block, to_spill); sched_add_after(skip_Proj(after), spill->spill); @@ -488,9 +480,10 @@ static void spill_phi(spill_env_t *env, spill_info_t *spillinfo) /* override or replace spills list... */ spill = OALLOC(&env->obst, spill_t); - spill->after = skip_keeps_phis(phi); - spill->spill = new_r_Phi(block, arity, ins, mode_M); + spill->after = determine_spill_point(phi); + spill->spill = be_new_Phi(block, arity, ins, mode_M, NULL); spill->next = NULL; + sched_add_after(block, spill->spill); spillinfo->spills = spill; #ifdef FIRM_STATISTICS @@ -604,7 +597,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)) { @@ -826,7 +819,7 @@ static void determine_spill_costs(spill_env_t *env, spill_info_t *spillinfo) /* override spillinfos or create a new one */ spill = OALLOC(&env->obst, spill_t); - spill->after = skip_keeps_phis(to_spill); + spill->after = determine_spill_point(to_spill); spill->next = NULL; spill->spill = NULL;