- determine_spill_costs(env, si);
-
- /* determine possibility of rematerialisations */
- if(be_do_remats) {
- /* calculate cost savings for each indivial value when it would
- be rematted instead of reloaded */
- for (rld = si->reloaders; rld != NULL; rld = rld->next) {
- double freq;
- int remat_cost;
- int remat_cost_delta;
- ir_node *block;
- ir_node *reloader = rld->reloader;
-
- if(rld->rematted_node != NULL) {
- DBG((dbg, LEVEL_2, "\tforced remat %+F before %+F\n",
- rld->rematted_node, reloader));
- continue;
- }
- if(rld->remat_cost_delta >= REMAT_COST_INFINITE) {
- DBG((dbg, LEVEL_2, "\treload before %+F is forbidden\n",
- reloader));
- all_remat_costs = REMAT_COST_INFINITE;
- continue;
- }
-
- remat_cost = check_remat_conditions_costs(env, to_spill,
- reloader, 0);
- if(remat_cost >= REMAT_COST_INFINITE) {
- DBG((dbg, LEVEL_2, "\tremat before %+F not possible\n",
- reloader));
- rld->remat_cost_delta = REMAT_COST_INFINITE;
- all_remat_costs = REMAT_COST_INFINITE;
- continue;
- }
-
- remat_cost_delta = remat_cost - env->reload_cost;
- rld->remat_cost_delta = remat_cost_delta;
- block = is_Block(reloader) ? reloader : get_nodes_block(reloader);
- freq = get_block_execfreq(exec_freq, block);
- all_remat_costs += remat_cost_delta * freq;
- DBG((dbg, LEVEL_2, "\tremat costs delta before %+F: "
- "%d (rel %f)\n", reloader, remat_cost_delta,
- remat_cost_delta * freq));
- }
- if(all_remat_costs < REMAT_COST_INFINITE) {
- /* we don't need the costs for the spill if we can remat
- all reloaders */
- all_remat_costs -= si->spill_costs;
-
- DBG((dbg, LEVEL_2, "\tspill costs %d (rel %f)\n",
- env->spill_cost, si->spill_costs));
- }
-
- if(all_remat_costs < 0) {
- DBG((dbg, LEVEL_1, "\nforcing remats of all reloaders (%f)\n",
- all_remat_costs));
- force_remat = 1;
- }
- }
-
- /* go through all reloads for this spill */
- for (rld = si->reloaders; rld != NULL; rld = rld->next) {
- ir_node *copy; /* a reload is a "copy" of the original value */
-
- if (rld->rematted_node != NULL) {
- copy = rld->rematted_node;
- sched_add_before(rld->reloader, copy);
- } else if (be_do_remats &&
- (force_remat || rld->remat_cost_delta < 0)) {
- copy = do_remat(env, to_spill, rld->reloader);
- } else {
- /* make sure we have a spill */
- spill_node(env, si);
-
- /* create a reload, use the first spill for now SSA
- * reconstruction for memory comes below */
- assert(si->spills != NULL);
- copy = be_reload(arch_env, si->reload_cls, rld->reloader, mode,
- si->spills->spill);
-#ifdef FIRM_STATISTICS
- env->reload_count++;
-#endif
- }
-
- DBG((dbg, LEVEL_1, " %+F of %+F before %+F\n",
- copy, to_spill, rld->reloader));
- ARR_APP1(ir_node*, copies, copy);
- }
-
- /* if we had any reloads or remats, then we need to reconstruct the
- * SSA form for the spilled value */
- if (ARR_LEN(copies) > 0) {
- be_ssa_construction_env_t senv;
- /* be_lv_t *lv = be_get_birg_liveness(env->birg); */
-
- be_ssa_construction_init(&senv, env->birg);
- be_ssa_construction_add_copy(&senv, to_spill);
- be_ssa_construction_add_copies(&senv, copies, ARR_LEN(copies));
- be_ssa_construction_fix_users(&senv, to_spill);
-
-#if 0
- /* no need to enable this as long as we invalidate liveness
- after this function... */
- be_ssa_construction_update_liveness_phis(&senv);
- be_liveness_update(to_spill);
- len = ARR_LEN(copies);
- for(i = 0; i < len; ++i) {
- be_liveness_update(lv, copies[i]);
- }
-#endif
- be_ssa_construction_destroy(&senv);
- }
- /* need to reconstruct SSA form if we had multiple spills */
- if (si->spills != NULL && si->spills->next != NULL) {
- spill_t *spill;
- int spill_count = 0;
-
- be_ssa_construction_env_t senv;
-
- be_ssa_construction_init(&senv, env->birg);
- spill = si->spills;
- for( ; spill != NULL; spill = spill->next) {
- /* maybe we rematerialized the value and need no spill */
- if(spill->spill == NULL)
- continue;
- be_ssa_construction_add_copy(&senv, spill->spill);
- spill_count++;
- }
- if(spill_count > 1) {
- /* all reloads are attached to the first spill, fix them now */
- be_ssa_construction_fix_users(&senv, si->spills->spill);
- }
-
- be_ssa_construction_destroy(&senv);
- }
-
- DEL_ARR_F(copies);
- si->reloaders = NULL;
- }
-
- stat_ev_dbl("spill_spills", env->spill_count);
- stat_ev_dbl("spill_reloads", env->reload_count);
- stat_ev_dbl("spill_remats", env->remat_count);
- stat_ev_dbl("spill_spilled_phis", env->spilled_phi_count);
-
- /* Matze: In theory be_ssa_construction should take care of the liveness...
- * try to disable this again in the future */
- be_liveness_invalidate(env->birg->lv);
-
- be_remove_dead_nodes_from_schedule(env->birg);
-}
-
-void be_init_spill(void)
-{
- FIRM_DBG_REGISTER(dbg, "firm.be.spill");