ctx = be_get_spill_ctx(senv->spill_ctxs, irn, ctx_irn);
if(!ctx->spill) {
- const be_main_env_t *env = senv->chordal_env->main_env;
+ const be_main_env_t *env = senv->chordal_env->birg->main_env;
ctx->spill = be_spill(env->arch_env, irn, ctx_irn);
}
static void phi_walker(ir_node *irn, void *env) {
spill_env_t *senv = env;
- const arch_env_t *arch = senv->chordal_env->main_env->arch_env;
+ const arch_env_t *arch = senv->chordal_env->birg->main_env->arch_env;
if (is_Phi(irn) && arch_irn_has_reg_class(arch, irn, 0, senv->cls)
&& senv->is_mem_phi(irn, senv->data)) {
}
void be_insert_spills_reloads(spill_env_t *senv, pset *reload_set) {
- ir_graph *irg = senv->chordal_env->irg;
+ const arch_env_t *aenv = senv->chordal_env->birg->main_env->arch_env;
+ ir_graph *irg = senv->chordal_env->irg;
ir_node *irn;
spill_info_t *si;
struct obstack ob;
ir_node *spill = be_spill_node(senv, si->spilled_node);
/* the reload */
- ir_node *bl = is_Block(rld->reloader) ? rld->reloader : get_nodes_block(rld->reloader);
- ir_node *reload = be_new_Reload(senv->cls, irg, bl, mode, spill);
+ ir_node *reload = be_reload(aenv, senv->cls, rld->reloader, mode, spill);
DBG((senv->dbg, LEVEL_1, " %+F of %+F before %+F\n", reload, si->spilled_node, rld->reloader));
if(reload_set)
pset_insert_ptr(reload_set, reload);
- /* remember the reaload */
+ /* remember the reload */
obstack_ptr_grow(&ob, reload);
- sched_add_before(rld->reloader, reload);
n_reloads++;
}
assert(n_reloads > 0);
+ obstack_ptr_grow(&ob, si->spilled_node);
reloads = obstack_finish(&ob);
- be_ssa_constr_single_ignore(senv->chordal_env->dom_front, si->spilled_node, n_reloads, reloads, senv->mem_phis);
+ be_ssa_constr_ignore(senv->chordal_env->dom_front, n_reloads + 1, reloads, senv->mem_phis);
obstack_free(&ob, reloads);
}
struct obstack ob;
be_chordal_env_t *cenv;
pmap *slots; /* maps spill_contexts to spill_slots */
+ pmap *types; /* maps modes to types */
} ss_env_t;
/* 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, 0));
+ 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 */
pmap_insert(ssenv->slots, ctx, ss);
ir_node *irn;
/* values with the same spill_ctx must go into the same spill slot */
ss = entry->value;
- assert(ss->size == (unsigned)get_mode_size_bytes(get_irn_mode(get_irn_n(spill, 0))) && "Different sizes for the same spill slot are not allowed yet.");
+ assert(ss->size == (unsigned)get_mode_size_bytes(get_irn_mode(get_irn_n(spill, be_pos_Spill_val))) && "Different sizes for the same spill slot are not allowed yet.");
for (irn = pset_first(ss->members); irn; irn = pset_next(ss->members)) {
/* use values_interfere here, because it uses the dominance check,
which does work for values in memory */
#define ALIGN_SPILL_AREA 16
#define pset_foreach(pset, elm) for(elm=pset_first(pset); elm; elm=pset_next(pset))
+/**
+ * Returns a spill type for a mode. Keep them in a map to reduce
+ * the number of types.
+ */
+static ir_type *get_spill_type(pmap *types, ir_mode *mode) {
+ pmap_entry *e = pmap_find(types, mode);
+ ir_type *res;
+
+ if (! e) {
+ char buf[64];
+ snprintf(buf, sizeof(buf), "spill_slot_type_%s", get_mode_name(mode));
+ res = new_type_primitive(new_id_from_str(buf), mode);
+ pmap_insert(types, mode, res);
+ }
+ else
+ res = e->value;
+ return res;
+}
+
static void assign_entities(ss_env_t *ssenv, int n, spill_slot_t **ss) {
int i, offset;
ir_type *frame = get_irg_frame_type(ssenv->cenv->irg);
/* create entities and assign offsets according to size and alignment*/
for (i=0; i<n; ++i) {
char buf[64];
- ident *name, *type_id;
+ ident *name;
entity *spill_ent;
ir_node *irn;
/* build entity */
snprintf(buf, sizeof(buf), "spill_slot_%d", i);
name = new_id_from_str(buf);
- snprintf(buf, sizeof(buf), "spill_slot_type_%d", i);
- type_id = new_id_from_str(buf);
- spill_ent = new_entity(frame, name, new_type_primitive(type_id, ss[i]->largest_mode));
+ spill_ent = new_entity(frame, name, get_spill_type(ssenv->types, ss[i]->largest_mode));
/* align */
offset = round_up2(offset, ss[i]->align);
obstack_init(&ssenv.ob);
ssenv.cenv = cenv;
ssenv.slots = pmap_create();
+ ssenv.types = pmap_create();
ssenv.dbg = firm_dbg_register("ir.be.spillslots");
/* Get initial spill slots */
/* Clean up */
pmap_foreach(ssenv.slots, pme)
- del_pset(((spill_slot_t *)pme->value)->members);
+ del_pset(((spill_slot_t *)pme->value)->members);
pmap_destroy(ssenv.slots);
+ pmap_destroy(ssenv.types);
obstack_free(&ssenv.ob, NULL);
+
+ be_copy_entities_to_reloads(cenv->irg);
}