X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbespill.c;h=22b4028d422f0ee73dcd39a8adbfbbd857857857;hb=9abde7e0c25eddba9762cd44901bcbebbd0f567a;hp=5738414d6c400ff89536b48297ebe564756fe9be;hpb=c9623d3dd138aca08572167934c1a7c1fb826344;p=libfirm diff --git a/ir/be/bespill.c b/ir/be/bespill.c index 5738414d6..22b4028d4 100644 --- a/ir/be/bespill.c +++ b/ir/be/bespill.c @@ -27,6 +27,7 @@ #include "benode_t.h" #include "bechordal_t.h" +#undef REMAT /* This enables re-computation of values. Current state: Unfinished and buggy. */ #undef BUGGY_REMAT @@ -50,15 +51,15 @@ typedef struct _spill_ctx_t { } spill_ctx_t; struct _spill_env_t { - firm_dbg_module_t *dbg; const arch_register_class_t *cls; const be_chordal_env_t *chordal_env; struct obstack obst; set *spill_ctxs; set *spills; /**< all spill_info_t's, which must be placed */ - pset *mem_phis; /**< set of all special spilled phis. allocated and freed seperately */ + pset *mem_phis; /**< set of all special spilled phis. allocated and freed separately */ decide_irn_t is_mem_phi; /**< callback func to decide if a phi needs special spilling */ void *data; /**< data passed to all callbacks */ + DEBUG_ONLY(firm_dbg_module_t *dbg;) }; static int cmp_spillctx(const void *a, const void *b, size_t n) { @@ -73,15 +74,11 @@ static int cmp_spillinfo(const void *x, const void *y, size_t size) { return ! (xx->spilled_node == yy->spilled_node); } -spill_env_t *be_new_spill_env(firm_dbg_module_t *dbg, - const be_chordal_env_t *chordal_env, - decide_irn_t is_mem_phi, void *data) { - +spill_env_t *be_new_spill_env(const be_chordal_env_t *chordal_env, decide_irn_t is_mem_phi, void *data) { spill_env_t *env = xmalloc(sizeof(env[0])); env->spill_ctxs = new_set(cmp_spillctx, 1024); env->spills = new_set(cmp_spillinfo, 1024); env->cls = chordal_env->cls; - env->dbg = dbg; env->is_mem_phi = is_mem_phi; env->data = data; env->chordal_env = chordal_env; @@ -182,6 +179,7 @@ static void phi_walker(ir_node *irn, void *env) { } } +#ifdef REMAT #ifdef BUGGY_REMAT @@ -237,6 +235,18 @@ is_alive: ; return 1; } +#else /* BUGGY_REMAT */ + +static int check_remat_conditions(spill_env_t *senv, ir_node *spill, ir_node *spilled, ir_node *reloader) { + const arch_env_t *aenv = senv->chordal_env->birg->main_env->arch_env; + + return get_irn_arity(spilled) == 0 && + be_is_Spill(spill) && + arch_irn_is(aenv, spilled, rematerializable); +} + +#endif /* BUGGY_REMAT */ + static ir_node *do_remat(spill_env_t *senv, ir_node *spilled, ir_node *reloader) { ir_node *res; ir_node *bl = (is_Block(reloader)) ? reloader : get_nodes_block(reloader); @@ -247,6 +257,7 @@ static ir_node *do_remat(spill_env_t *senv, ir_node *spilled, ir_node *reloader) get_irn_mode(spilled), get_irn_arity(spilled), get_irn_in(spilled)); + copy_node_attr(spilled, res); DBG((senv->dbg, LEVEL_1, "Insert remat %+F before reloader %+F\n", res, reloader)); @@ -304,7 +315,7 @@ void be_insert_spills_reloads(spill_env_t *senv, pset *reload_set) { /* the spill for this reloader */ ir_node *spill = be_spill_node(senv, si->spilled_node); -#ifdef BUGGY_REMAT +#ifdef REMAT if (check_remat_conditions(senv, spill, si->spilled_node, rld->reloader)) new_val = do_remat(senv, si->spilled_node, rld->reloader); else @@ -371,14 +382,16 @@ typedef struct _spill_slot_t { } spill_slot_t; typedef struct _ss_env_t { - firm_dbg_module_t *dbg; struct obstack ob; be_chordal_env_t *cenv; pmap *slots; /* maps spill_contexts to spill_slots */ - pmap *types; /* maps modes to types */ + pmap *types; /* maps modes to types */ + DEBUG_ONLY(firm_dbg_module_t *dbg;) } ss_env_t; - +/** + * Walker: compute the spill slots + */ static void compute_spill_slots_walker(ir_node *spill, void *env) { ss_env_t *ssenv = env; ir_node *ctx; @@ -393,12 +406,18 @@ static void compute_spill_slots_walker(ir_node *spill, void *env) { entry = pmap_find(ssenv->slots, ctx); if (!entry) { + struct _arch_env_t *arch_env = ssenv->cenv->birg->main_env->arch_env; + ir_node *spilled = get_irn_n(spill, be_pos_Spill_val); + const arch_register_t *reg = arch_get_irn_register(arch_env, spilled); + const arch_register_class_t *cls = arch_register_get_class(reg); + ir_mode *largest_mode = arch_register_class_mode(cls); + /* this is a new spill context */ ss = obstack_alloc(&ssenv->ob, sizeof(*ss)); - ss->members = pset_new_ptr(8); - ss->largest_mode = get_irn_mode(get_irn_n(spill, be_pos_Spill_val)); - ss->size = get_mode_size_bytes(ss->largest_mode); - ss->align = ss->size; /* TODO Assumed for now */ + ss->members = pset_new_ptr(8); + ss->largest_mode = largest_mode; + ss->size = get_mode_size_bytes(ss->largest_mode); + ss->align = arch_isa_get_reg_class_alignment(arch_env->isa, cls); pmap_insert(ssenv->slots, ctx, ss); } else { ir_node *irn; @@ -568,7 +587,7 @@ void be_compute_spill_offsets(be_chordal_env_t *cenv) { ssenv.cenv = cenv; ssenv.slots = pmap_create(); ssenv.types = pmap_create(); - ssenv.dbg = firm_dbg_register("ir.be.spillslots"); + FIRM_DBG_REGISTER(ssenv.dbg, "ir.be.spillslots"); /* Get initial spill slots */ irg_walk_graph(cenv->irg, NULL, compute_spill_slots_walker, &ssenv);