DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
typedef struct morgan_env {
+ const be_chordal_env_t *cenv;
const arch_env_t *arch;
const arch_register_class_t *cls;
ir_graph *irg;
*/
static bitset_t *construct_block_livethrough_unused(morgan_env_t* env, const ir_node* block) {
block_attr_t *block_attr = get_block_attr(env, block);
- irn_live_t *li;
ir_node *node;
+ int i;
DBG((dbg, DBG_LIVE, "Processing block %d\n", get_irn_node_nr(block)));
// copy all live-outs into the livethrough_unused set
- live_foreach(block, li) {
+ be_lv_foreach(env->cenv->lv, block, be_lv_state_in | be_lv_state_out, i) {
+ ir_node *irn = be_lv_get_irn(env->cenv->lv, block, i);
int node_idx;
+ /*
if(!live_is_in(li) || !live_is_out(li))
continue;
- if(!consider_for_spilling(env->arch, env->cls, li->irn))
+ */
+ if(!consider_for_spilling(env->arch, env->cls, irn))
continue;
- node_idx = get_irn_idx(li->irn);
+ node_idx = get_irn_idx(irn);
bitset_set(block_attr->livethrough_unused, node_idx);
}
int unused_spills_possible = loop_unused_spills_possible + block_unused_spills_possible;
pset *live_nodes = pset_new_ptr_default();
- be_liveness_end_of_block(env->arch, env->cls, block, live_nodes);
+ be_liveness_end_of_block(env->cenv->lv, env->arch, env->cls, block, live_nodes);
pressure = pset_count(live_nodes);
DBG((dbg, DBG_LIVE, "Reduce pressure to %d In Block %+F:\n", env->registers_available, block));
to_spill = get_idx_irn(env->irg, i);
foreach_block_succ(block, edge) {
DBG((dbg, DBG_PRESSURE, "Spilling node %+F around block %+F\n", to_spill, block));
- /* We always spill the whole phis and not just their results,
- * this shouldn't do any harm but avoids trouble if belady
- * decides to spill a whole phi where we only spilled the value
- */
- if(is_Phi(to_spill))
- be_spill_phi(env->senv, to_spill);
be_add_reload_on_edge(env->senv, to_spill, edge->src, edge->pos);
}
spills++;
ir_node *to_spill = get_idx_irn(env->irg, i);
for(edge = set_first(loop_attr->out_edges); edge != NULL; edge = set_next(loop_attr->out_edges)) {
- /* we always spill whole phis (look at reduce_register_pressure_in_block for details) */
- if(is_Phi(to_spill))
- be_spill_phi(env->senv, to_spill);
+ DBG((dbg, DBG_PRESSURE, "Spilling node %+F around loop %d\n", to_spill, loop->loop_nr));
be_add_reload_on_edge(env->senv, to_spill, edge->block, edge->pos);
-
}
spills_to_place--;
return outer_spills_needed;
}
-void be_spill_morgan(const be_chordal_env_t *chordal_env) {
+void be_spill_morgan(be_chordal_env_t *chordal_env) {
morgan_env_t env;
FIRM_DBG_REGISTER(dbg, "ir.be.spillmorgan");
//firm_dbg_set_mask(dbg, DBG_LOOPANA | DBG_PRESSURE);
+ env.cenv = chordal_env;
env.arch = chordal_env->birg->main_env->arch_env;
env.irg = chordal_env->irg;
env.cls = chordal_env->cls;
env.block_attr_set = new_set(block_attr_cmp, 20);
/*-- Part1: Analysis --*/
- be_liveness(env.irg);
+ be_liveness_recompute(chordal_env->lv);
/* construct control flow loop tree */
construct_cf_backedges(chordal_env->irg);
+ //dump_looptree(0, get_irg_loop(env.irg));
+ //dump_execfreqs(env.irg);
+
/* construct loop out edges and livethrough_unused sets for loops and blocks */
irg_block_walk_graph(chordal_env->irg, NULL, construct_loop_edges, &env);
construct_loop_livethrough_unused(&env, get_irg_loop(env.irg));
*/
reduce_register_pressure_in_loop(&env, get_irg_loop(env.irg), 0);
- /* Place copies for spilled phis */
- be_place_copies(env.senv);
/* Insert real spill/reload nodes and fix usages */
be_insert_spills_reloads(env.senv);
/* we have to remove dead nodes from schedule to not confuse liveness calculation */
be_remove_dead_nodes_from_schedule(env.irg);
- be_liveness(env.irg);
+ be_liveness_recompute(chordal_env->lv);
be_spill_belady_spill_env(chordal_env, env.senv);