values may die at every use
[libfirm] / ir / be / bespillmorgan.c
index 40a159f..1276581 100644 (file)
 
 #include "bespillmorgan.h"
 
-#include "bechordal.h"
 #include "bechordal_t.h"
 #include "bespill.h"
-#include "belive.h"
 #include "belive_t.h"
 #include "irgwalk.h"
 #include "besched.h"
 #include "beutil.h"
-#include "beuses.h"
-#include "interval_analysis.h"
-#include "irloop.h"
 #include "irloop_t.h"
-#include "irgraph.h"
 #include "irgraph_t.h"
-#include "irphase.h"
 #include "irphase_t.h"
 #include "irprintf.h"
 
@@ -45,7 +38,6 @@ typedef struct _morgan_env_t {
        int registers_available;
 
        spill_env_t *senv;
-       be_uses_t *uses;
 
        set *loop_attr_set;
        set *block_attr_set;
@@ -139,6 +131,13 @@ static INLINE block_attr_t *get_block_attr(morgan_env_t *env, ir_node *block) {
 
 //---------------------------------------------------------------------------
 
+static INLINE int consider_for_spilling(const arch_env_t *env, const arch_register_class_t *cls, const ir_node *node) {
+       if(!arch_irn_has_reg_class(env, node, -1, cls))
+               return 0;
+
+       return !(arch_irn_get_flags(env, node) & (arch_irn_flags_ignore | arch_irn_flags_dont_spill));
+}
+
 /**
  * Determine edges going out of a loop (= edges that go to a block that is not inside
  * the loop or one of its subloops)
@@ -185,7 +184,7 @@ static void show_nodebitset(ir_graph* irg, bitset_t* bitset) {
 }
 
 /**
- * Construct the livethrough unused information for a block
+ * Construct the livethrough unused set for a block
  */
 static bitset_t *construct_block_livethrough_unused(morgan_env_t* env, ir_node* block) {
        block_attr_t *block_attr = get_block_attr(env, block);
@@ -199,7 +198,7 @@ static bitset_t *construct_block_livethrough_unused(morgan_env_t* env, ir_node*
 
                if(!live_is_in(li) || !live_is_out(li))
                        continue;
-               if(!arch_irn_consider_in_reg_alloc(env->arch, env->cls, li->irn))
+               if(!consider_for_spilling(env->arch, env->cls, li->irn))
                        continue;
 
                node_idx = get_irn_idx(li->irn);
@@ -223,6 +222,9 @@ static bitset_t *construct_block_livethrough_unused(morgan_env_t* env, ir_node*
        return block_attr->livethrough_unused;
 }
 
+/**
+ * Construct the livethrough unused set for a loop (and all its subloops+blocks)
+ */
 static bitset_t *construct_loop_livethrough_unused(morgan_env_t *env, ir_loop *loop) {
        int i;
        loop_attr_t* loop_attr = get_loop_attr(env, loop);
@@ -308,7 +310,7 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, ir_node* block,
         */
        sched_foreach_reverse(block, irn) {
                // do we need more spills than possible with unused libethroughs?
-               int spills_needed = pressure - unused_spills_possible - env->registers_available;
+               int spills_needed = pressure - env->registers_available - unused_spills_possible;
                if(spills_needed > 0) {
                        DBG((dbg, DBG_PRESSURE, "\tWARNING %d more spills needed at %+F\n", spills_needed, irn));
                        // TODO further spills needed
@@ -325,14 +327,12 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, ir_node* block,
                        break;
 
                // update pressure
-               {
-                       int pressure_old = pressure;
-                       be_liveness_transfer(env->arch, env->cls, irn, live_nodes);
-                       pressure = pset_count(live_nodes);
-                       DBG((dbg, DBG_PRESSURE, "\tPressure at %+F - before: %d after: %d\n", irn, pressure_old, pressure));
-               }
+               be_liveness_transfer(env->arch, env->cls, irn, live_nodes);
+               pressure = pset_count(live_nodes);
        }
 
+       DBG((dbg, DBG_PRESSURE, "\tMax Pressure in %+F: %d\n", block, max_pressure));
+
        /*
         * Calculate number of spills from loop_unused_spills_possible that we want to use,
         * and spill unused livethroughs from the block if we still don't have enough registers
@@ -366,6 +366,7 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, ir_node* block,
                                DBG((dbg, DBG_PRESSURE, "Spilling node %+F around block %+F\n", to_spill, block));
                                be_add_reload_on_edge(env->senv, to_spill, edge->src, edge->pos);
                        }
+                       spills++;
                }
        } else {
                loop_unused_spills_needed = spills_needed;
@@ -427,10 +428,6 @@ static int reduce_register_pressure_in_loop(morgan_env_t *env, ir_loop *loop, in
                        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)) {
-                               if(is_Phi(to_spill)) {
-                                       be_spill_phi(env->senv, to_spill);
-                               }
-
                                be_add_reload_on_edge(env->senv, to_spill, edge->block, edge->pos);
                        }
                }
@@ -455,7 +452,6 @@ void be_spill_morgan(const be_chordal_env_t *chordal_env) {
        env.cls = chordal_env->cls;
        env.senv = be_new_spill_env(chordal_env);
        DEBUG_ONLY(be_set_spill_env_dbg_module(env.senv, dbg);)
-       env.uses = be_begin_uses(env.irg, env.arch, env.cls);
 
        phase_init(&env.phase, "spillmorgan", env.irg, PHASE_DEFAULT_GROWTH, init_phase_data);
 
@@ -486,17 +482,18 @@ void be_spill_morgan(const be_chordal_env_t *chordal_env) {
                assert(be_verify_schedule(env.irg));
        }
 
+       // we have to remove dead nodes from schedule to not confuse liveness calculation
+       be_remove_dead_nodes_from_schedule(env.irg);
+
        // cleanup
-       be_end_uses(env.uses);
-       be_dump(env.irg, "-spillmorgan", dump_ir_block_graph_sched);
+       if (chordal_env->opts->dump_flags & BE_CH_DUMP_SPILL)
+               be_dump(env.irg, "-spillmorgan", dump_ir_block_graph_sched);
+
        free_loop_out_edges(&env);
        del_set(env.loop_attr_set);
        del_set(env.block_attr_set);
 
        // fix the remaining places with too high register pressure with beladies algorithm
-
-       // 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_spill_belady_spill_env(chordal_env, env.senv);