values may die at every use
[libfirm] / ir / be / bespillmorgan.c
index 86c0342..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 "irloop.h"
 #include "irloop_t.h"
-#include "irgraph.h"
 #include "irgraph_t.h"
-#include "irphase.h"
 #include "irphase_t.h"
 #include "irprintf.h"
 
@@ -136,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)
@@ -196,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);
@@ -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
@@ -364,11 +364,9 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, ir_node* 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));
-                               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++;
                }
        } else {
                loop_unused_spills_needed = spills_needed;
@@ -430,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);
                        }
                }
@@ -492,7 +486,9 @@ void be_spill_morgan(const be_chordal_env_t *chordal_env) {
        be_remove_dead_nodes_from_schedule(env.irg);
 
        // cleanup
-       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);