Commit 3643119e authored by Christian Würdig's avatar Christian Würdig
Browse files

be_add_reload now takes reload register class as additional argument (needed for STA backend)

parent 193c0cf4
......@@ -59,6 +59,9 @@ typedef struct _spill_info_t {
/** if we had the value of a phi spilled before but not the phi itself then
* this field contains the spill for the phi value */
ir_node *old_spill;
/** the register class in which the reload should be placed */
const arch_register_class_t *reload_cls;
} spill_info_t;
struct _spill_env_t {
......@@ -157,7 +160,7 @@ void be_delete_spill_env(spill_env_t *env) {
*
*/
void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before) {
void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before, const arch_register_class_t *reload_cls) {
spill_info_t *info;
reloader_t *rel;
......@@ -167,8 +170,9 @@ void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before) {
if(is_Phi(to_spill)) {
int i, arity;
// create spillinfos for the phi arguments
for(i = 0, arity = get_irn_arity(to_spill); i < arity; ++i) {
/* create spillinfos for the phi arguments */
for (i = 0, arity = get_irn_arity(to_spill); i < arity; ++i) {
ir_node *arg = get_irn_n(to_spill, i);
get_spillinfo(env, arg);
}
......@@ -178,7 +182,7 @@ void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before) {
// the belady algo decides later to spill the whole phi, then sees the
// spill node and adds a reload for that spill node, problem is the
// reload gets attach to that same spill (and is totally unnecessary)
if(info->old_spill != NULL &&
if (info->old_spill != NULL &&
(before == info->old_spill || value_dominates(before, info->old_spill))) {
printf("spilledphi hack was needed...\n");
before = sched_next(info->old_spill);
......@@ -186,10 +190,13 @@ void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before) {
#endif
}
/* put reload into list */
rel = obstack_alloc(&env->obst, sizeof(rel[0]));
rel->reloader = before;
rel->next = info->reloaders;
info->reloaders = rel;
info->reloaders = rel;
info->reload_cls = reload_cls;
}
static ir_node *get_reload_insertion_point(ir_node *block, int pos) {
......@@ -226,9 +233,11 @@ static ir_node *get_reload_insertion_point(ir_node *block, int pos) {
return last;
}
void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block, int pos) {
void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill,
ir_node *block, int pos, const arch_register_class_t *reload_cls)
{
ir_node *before = get_reload_insertion_point(block, pos);
be_add_reload(env, to_spill, before);
be_add_reload(env, to_spill, before, reload_cls);
}
void be_spill_phi(spill_env_t *env, ir_node *node) {
......@@ -608,33 +617,34 @@ int be_get_reload_costs_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *bl
void be_insert_spills_reloads(spill_env_t *env) {
const arch_env_t *arch_env = env->arch_env;
spill_info_t *si;
int remats = 0;
int reloads = 0;
int spills = 0;
int remats = 0;
int reloads = 0;
int spills = 0;
spill_info_t *si;
/* process each spilled node */
for(si = set_first(env->spills); si; si = set_next(env->spills)) {
for (si = set_first(env->spills); si; si = set_next(env->spills)) {
reloader_t *rld;
ir_mode *mode = get_irn_mode(si->spilled_node);
pset *values = pset_new_ptr(16);
ir_mode *mode = get_irn_mode(si->spilled_node);
pset *values = pset_new_ptr(16);
/* go through all reloads for this spill */
for(rld = si->reloaders; rld; rld = rld->next) {
for (rld = si->reloaders; rld; rld = rld->next) {
ir_node *new_val;
if (be_do_remats && check_remat_conditions(env, si->spilled_node, rld->reloader)) {
new_val = do_remat(env, si->spilled_node, rld->reloader);
remats++;
} else {
}
else {
/* make sure we have a spill */
if(si->spill == NULL) {
if (si->spill == NULL) {
spill_node(env, si);
spills++;
}
/* create a reload */
new_val = be_reload(arch_env, env->cls, rld->reloader, mode, si->spill);
new_val = be_reload(arch_env, si->reload_cls, rld->reloader, mode, si->spill);
reloads++;
}
......@@ -642,7 +652,7 @@ void be_insert_spills_reloads(spill_env_t *env) {
pset_insert_ptr(values, new_val);
}
if(pset_count(values) > 0) {
if (pset_count(values) > 0) {
/* introduce copies, rewire the uses */
pset_insert_ptr(values, si->spilled_node);
be_ssa_constr_set_ignore(env->birg->dom_front, env->birg->lv, values, env->mem_phis);
......@@ -653,11 +663,13 @@ void be_insert_spills_reloads(spill_env_t *env) {
si->reloaders = NULL;
}
if(be_stat_ev_is_active()) {
#ifdef FIRM_STATISTICS
if (be_stat_ev_is_active()) {
be_stat_ev("spill_spills", spills);
be_stat_ev("spill_reloads", reloads);
be_stat_ev("spill_remats", remats);
}
#endif /* FIRM_STATISTICS */
be_remove_dead_nodes_from_schedule(env->chordal_env->irg);
//be_liveness_recompute(env->birg->lv);
......
......@@ -41,12 +41,12 @@ DEBUG_ONLY(void be_set_spill_env_dbg_module(spill_env_t *env, firm_dbg_module_t
* the definition of a value as soon as a reload is created. (we should add a
* possibility for explicit spill placement in the future)
*/
void be_add_reload(spill_env_t *senv, ir_node *to_spill, ir_node *before);
void be_add_reload(spill_env_t *senv, ir_node *to_spill, ir_node *before, const arch_register_class_t *reload_cls);
/**
* Analog to be_add_reload, but places the reload "on an edge" between 2 blocks
*/
void be_add_reload_on_edge(spill_env_t *senv, ir_node *to_spill, ir_node *bl, int pos);
void be_add_reload_on_edge(spill_env_t *senv, ir_node *to_spill, ir_node *bl, int pos, const arch_register_class_t *reload_cls);
/**
* The main function that places real spills/reloads (or rematerializes values)
......
......@@ -317,7 +317,7 @@ static void displace(belady_env_t *env, workset_t *new_vals, int is_usage) {
to_insert[demand++] = val;
if (is_usage) {
DBG((dbg, DBG_SPILL, "Reload %+F before %+F\n", val, env->instr));
be_add_reload(env->senv, val, env->instr);
be_add_reload(env->senv, val, env->instr, env->cls);
}
}
else {
......@@ -679,7 +679,7 @@ static void fix_block_borders(ir_node *block, void *data) {
/* irnb is not in memory at the end of pred, so we have to reload it */
DBG((dbg, DBG_FIX, " reload %+F\n", irnb));
DBG((dbg, DBG_SPILL, "Reload %+F before %+F,%d\n", irnb, block, i));
be_add_reload_on_edge(env->senv, irnb, block, i);
be_add_reload_on_edge(env->senv, irnb, block, i, env->cls);
next_value:
/*epsilon statement :)*/;
......
......@@ -432,7 +432,7 @@ static void spill_values(morgan_env_t *env, const loop_attr_t *loop_attr, int sp
DBG((dbg, DBG_CHOOSE, "Spilling %+F ", to_spill));
for(edge = set_first(loop_attr->out_edges); edge != NULL; edge = set_next(loop_attr->out_edges)) {
be_add_reload_on_edge(env->senv, to_spill, edge->block, edge->pos);
be_add_reload_on_edge(env->senv, to_spill, edge->block, edge->pos, env->cls);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment