* Changed the liveness API:
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Thu, 14 Jun 2007 19:44:07 +0000 (19:44 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Thu, 14 Jun 2007 19:44:07 +0000 (19:44 +0000)
  - The liveness in the birg stays always the same
  - Invalidation is done with be_liveness_invalidate()
  - Each algo has to specify if it needs only liveness checks
      be_liveness_assure_chk()
    or the complete liveness sets for use with be_lv_foreach, etc.
      be_liveness_assure_sets()

* Adapted all the files to these changes
* made bessadestr.c liveness updating

[r14506]

25 files changed:
ir/be/bechordal.c
ir/be/bechordal_draw.c
ir/be/bechordal_main.c
ir/be/becopyopt.c
ir/be/beintlive_t.h
ir/be/beirg.c
ir/be/beirg.h
ir/be/beirg_t.h
ir/be/belive.c
ir/be/belive.h
ir/be/belive_t.h
ir/be/belower.c
ir/be/bepressurestat.c
ir/be/beraextern.c
ir/be/bespill.c
ir/be/bespillbelady.c
ir/be/bespilldaemel.c
ir/be/bespillmorgan.c
ir/be/bespillnaive.c
ir/be/bespillslots.c
ir/be/bessadestr.c
ir/be/bestate.c
ir/be/betranshlp.c
ir/be/beverify.c
ir/be/ia32/ia32_x87.c

index 1fa973b..dca28ef 100644 (file)
@@ -950,7 +950,6 @@ static void assign_new(ir_node *block, be_chordal_alloc_env_t *alloc_env, bitset
        bitset_t *live             = bitset_irg_malloc(env->irg);
        const arch_env_t *arch_env = env->birg->main_env->arch_env;
        be_irg_t *birg             = env->birg;
-       lv_chk_t *lv               = be_get_birg_liveness_chk(birg);
 
        bitset_pos_t elm;
        ir_node *irn;
@@ -968,7 +967,7 @@ static void assign_new(ir_node *block, be_chordal_alloc_env_t *alloc_env, bitset
         */
        bitset_foreach (live_end_dom, elm) {
                ir_node *irn = get_idx_irn(env->irg, elm);
-               if (lv_chk_bl_in(lv, block, irn)) {
+               if (be_is_live_in(birg->lv, block, irn)) {
                        const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
                        int col;
 
@@ -1066,6 +1065,7 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
 {
        be_chordal_alloc_env_t env;
        char buf[256];
+       be_lv_t *lv;
        be_irg_t *birg = chordal_env->birg;
        const arch_register_class_t *cls = chordal_env->cls;
 
@@ -1078,7 +1078,10 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
                return;
 
        be_assure_dom_front(birg);
-       be_assure_liveness(birg);
+       lv = be_assure_liveness(birg);
+       be_liveness_assure_sets(lv);
+       be_liveness_assure_chk(lv);
+
        assure_doms(irg);
 
        env.chordal_env   = chordal_env;
index 6f4ef2f..d9a6e72 100644 (file)
@@ -445,13 +445,16 @@ static void draw_block(ir_node *bl, void *data)
 static void draw(draw_chordal_env_t *env, const rect_t *start_box)
 {
        plotter_t *p = env->plotter;
+       be_lv_t *lv;
        rect_t bbox;
 
        bbox.x = bbox.y = 0;
        bbox.w = start_box->w + 2 * env->opts->x_margin;
        bbox.h = start_box->h + 2 * env->opts->y_margin;
 
-       be_assure_liveness(env->chordal_env->birg);
+       lv = be_assure_liveness(env->chordal_env->birg);
+       be_liveness_assure_sets(lv);
+       be_liveness_assure_chk(lv);
 
        p->vtab->begin(p, &bbox);
        irg_block_walk_graph(env->chordal_env->irg, draw_block, NULL, env);
index 278b5c2..440c16b 100644 (file)
@@ -634,7 +634,7 @@ static void be_ra_chordal_main(be_irg_t *birg)
        dump(BE_CH_DUMP_LOWER, irg, NULL, "-belower-after-ra", dump_ir_block_graph_sched);
 
        obstack_free(&obst, NULL);
-       be_invalidate_liveness(birg);
+       be_liveness_invalidate(be_get_birg_liveness(birg));
        BE_TIMER_POP(ra_timer.t_epilog);
 
        BE_TIMER_POP(ra_timer.t_other);
index 584da53..2f49c36 100644 (file)
@@ -1424,6 +1424,8 @@ void co_driver(be_chordal_env_t *cenv)
        if (algo < 0 || algo >= CO_ALGO_LAST)
                return;
 
+       be_liveness_assure_chk(be_get_birg_liveness(cenv->birg));
+
        co = new_copy_opt(cenv, cost_func);
        co_build_ou_structure(co);
        co_build_graph_structure(co);
index 659f5de..f096db3 100644 (file)
@@ -16,8 +16,6 @@
 #include "irphase_t.h"
 #include "iredges_t.h"
 
-#include "irlivechk.h"
-
 #include "beirg_t.h"
 #include "besched_t.h"
 
@@ -163,7 +161,7 @@ static INLINE int _strictly_dominates_use(const ir_node *irn, const ir_edge_t *e
  */
 static INLINE int _be_lv_chk_before_irn(const be_irg_t *birg, const ir_node *irn, const ir_node *where)
 {
-       const lv_chk_t *lv = be_get_birg_liveness_chk(birg);
+       const be_lv_t *lv = be_get_birg_liveness(birg);
        const ir_edge_t *edge;
 
        /* the node must strictly dominate the location, else it cannot be live there. */
@@ -174,7 +172,7 @@ static INLINE int _be_lv_chk_before_irn(const be_irg_t *birg, const ir_node *irn
         * now that it is clear that it strictly dominates the location it is surely live
         * if it is also live end at the block.
         */
-       if (lv_chk_bl_end(lv, get_nodes_block(where), irn))
+       if (be_is_live_end(lv, get_nodes_block(where), irn))
                return 1;
 
        /*
@@ -198,13 +196,13 @@ static INLINE int _be_lv_chk_before_irn(const be_irg_t *birg, const ir_node *irn
  */
 static INLINE int _be_lv_chk_after_irn(const be_irg_t *birg, const ir_node *irn, const ir_node *where)
 {
-       const lv_chk_t *lv = be_get_birg_liveness_chk(birg);
+       const be_lv_t *lv = be_get_birg_liveness(birg);
        const ir_edge_t *edge;
 
        if (!_value_dominates(irn, where))
                return 0;
 
-       if (lv_chk_bl_end(lv, get_nodes_block(where), irn))
+       if (be_is_live_end(lv, get_nodes_block(where), irn))
                return 1;
 
        foreach_out_edge (irn, edge) {
@@ -215,37 +213,12 @@ static INLINE int _be_lv_chk_after_irn(const be_irg_t *birg, const ir_node *irn,
        return 0;
 }
 
-/**
- * Check, if two nodes interfere.
- * This will become the favored rotine to call but it is not used yet.
- * @param birg   The backend irg.
- * @param a      The first node.
- * @param b      The second node.
- * @return       1, if a and b interfere, 0 if not.
- */
-static INLINE int _be_lv_chk_values_interfere(const be_irg_t *birg, const ir_node *a, const ir_node *b)
-{
-       int adb = _value_dominates(a, b);
-       int bda = _value_dominates(b, a);
-
-       if (bda) {
-               const ir_node *t = a;
-               a = b;
-               b = t;
-               adb = 1;
-       }
-
-       return adb && _be_lv_chk_after_irn(birg, a, b);
-}
-
 #define value_dominates_intrablock(a, b)         _value_dominates_intrablock(a, b)
 #define value_dominates(a, b)                    _value_dominates(a, b)
-#define lv_values_interfere(lv, a, b)            _lv_values_interfere(lv, a, b)
 #define values_interfere(birg, a, b)             _lv_values_interfere(be_get_birg_liveness(birg), a, b)
 #define dominates_use(a, e)                      _dominates_use(a, e)
 #define strictly_dominates_use(a, e)             _strictly_dominates_use(a, e)
 #define be_lv_chk_before_irn(birg, a, b)         _be_lv_chk_before_irn(birg, a, b)
 #define be_lv_chk_after_irn(birg, a, b)          _be_lv_chk_after_irn(birg, a, b)
-#define be_lv_chk_values_interfere(birg, a, b)   _be_lv_chk_values_interfere(birg, a, b)
 
 #endif /* _BELIVECHK_T_H */
index 9579177..da5e4f0 100644 (file)
 #include "execfreq.h"
 #include "beirg_t.h"
 
-void be_assure_liveness_chk(be_irg_t *birg)
-{
-       if (birg->lv_chk != NULL)
-               return;
-
-       birg->lv_chk = lv_chk_new(birg->irg);
-}
-
-void be_assure_liveness(be_irg_t *birg)
+be_lv_t *be_assure_liveness(be_irg_t *birg)
 {
        if (birg->lv != NULL)
                return;
 
-       birg->lv = be_liveness(birg->irg);
-}
-
-void be_invalidate_liveness(be_irg_t *birg)
-{
-       if (birg->lv == NULL)
-               return;
-
-       be_liveness_free(birg->lv);
-       birg->lv = NULL;
+       return birg->lv = be_liveness(birg->irg);
 }
 
 void be_assure_dom_front(be_irg_t *birg)
@@ -103,11 +86,6 @@ be_lv_t *(be_get_birg_liveness)(const be_irg_t *birg)
        return _be_get_birg_liveness(birg);
 }
 
-lv_chk_t *(be_get_birg_liveness_chk)(const be_irg_t *birg)
-{
-       return _be_get_birg_liveness_chk(birg);
-}
-
 be_dom_front_info_t *(be_get_birg_dom_front)(const be_irg_t *birg)
 {
        return _be_get_birg_dom_front(birg);
index 647480a..3c6be4f 100644 (file)
@@ -34,9 +34,7 @@ typedef struct be_irg_t be_irg_t;
 
 ir_graph *be_get_birg_irg(const be_irg_t *birg);
 
-void be_assure_liveness(be_irg_t *birg);
-void be_assure_liveness_chk(be_irg_t *birg);
-void be_invalidate_liveness(be_irg_t *birg);
+be_lv_t *be_assure_liveness(be_irg_t *birg);
 be_lv_t *be_get_birg_liveness(const be_irg_t *birg);
 
 void be_assure_dom_front(be_irg_t *birg);
@@ -53,11 +51,4 @@ ir_exec_freq *be_get_birg_exec_freq(const be_irg_t *birg);
  */
 void be_free_birg(be_irg_t *birg);
 
-/**
- * Compare the computed liveness information with the liveness check info.
- * @param lv    The computed liveness.
- * @param lvc   The liveness check information.
- */
-void be_live_chk_compare(be_irg_t *birg);
-
 #endif /* FIRM_BE_BEIRG_H */
index babc5ae..07a49c4 100644 (file)
@@ -43,7 +43,6 @@ struct be_irg_t {
        ir_exec_freq           *exec_freq;
        be_dom_front_info_t    *dom_front;
        be_lv_t                *lv;
-       lv_chk_t               *lv_chk;
 };
 
 static INLINE be_lv_t *
@@ -51,11 +50,6 @@ _be_get_birg_liveness(const be_irg_t *birg) {
        return birg->lv;
 }
 
-static INLINE lv_chk_t *
-_be_get_birg_liveness_chk(const be_irg_t *birg) {
-       return birg->lv_chk;
-}
-
 static INLINE ir_exec_freq *
 _be_get_birg_exec_freq(const be_irg_t *birg) {
        return birg->exec_freq;
@@ -78,7 +72,6 @@ _be_get_birg_arch_env(const be_irg_t *birg) {
 
 #define be_get_birg_exec_freq(birg)        _be_get_birg_exec_freq(birg)
 #define be_get_birg_liveness(birg)         _be_get_birg_liveness(birg)
-#define be_get_birg_liveness_chk(birg)     _be_get_birg_liveness_chk(birg)
 #define be_get_birg_dom_front(birg)        _be_get_birg_dom_front(birg)
 #define be_get_birg_irg(birg)              _be_get_birg_irg(birg)
 
index bffa22b..d4a7523 100644 (file)
@@ -486,6 +486,31 @@ static void compute_liveness(be_lv_t *lv)
        bitset_free(w.data);
 }
 
+void be_liveness_assure_sets(be_lv_t *lv)
+{
+       if (!lv->nodes) {
+               lv->nodes = bitset_malloc(2 * get_irg_last_idx(lv->irg));
+               phase_init(&lv->ph, "liveness", lv->irg, PHASE_DEFAULT_GROWTH, lv_phase_data_init, NULL);
+               compute_liveness(lv);
+       }
+}
+
+void be_liveness_assure_chk(be_lv_t *lv)
+{
+#ifndef USE_LIVE_CHK
+       be_liveness_assure_sets(be_lv_t *lv);
+#endif
+}
+
+void be_liveness_invalidate(be_lv_t *lv)
+{
+       if (lv && lv->nodes) {
+               phase_free(&lv->ph);
+               bitset_free(lv->nodes);
+               lv->nodes = NULL;
+       }
+}
+
 /* Compute the inter block liveness for a graph. */
 be_lv_t *be_liveness(ir_graph *irg)
 {
@@ -493,12 +518,10 @@ be_lv_t *be_liveness(ir_graph *irg)
 
        memset(lv, 0, sizeof(lv[0]));
        lv->irg = irg;
-       lv->nodes = bitset_malloc(2 * get_irg_last_idx(irg));
+       lv->lvc = lv_chk_new(irg);
        lv->hook_info.context = lv;
        lv->hook_info.hook._hook_node_info = lv_dump_block;
        register_hook(hook_node_info, &lv->hook_info);
-       phase_init(&lv->ph, "liveness", irg, PHASE_DEFAULT_GROWTH, lv_phase_data_init, NULL);
-       compute_liveness(lv);
 
        return lv;
 }
@@ -522,36 +545,39 @@ void be_liveness_recompute(be_lv_t *lv)
 
 void be_liveness_free(be_lv_t *lv)
 {
+       be_liveness_invalidate(lv);
        unregister_hook(hook_node_info, &lv->hook_info);
-       phase_free(&lv->ph);
-       bitset_free(lv->nodes);
        free(lv);
 }
 
 void be_liveness_remove(be_lv_t *lv, ir_node *irn)
 {
-       unsigned idx = get_irn_idx(irn);
-       struct _lv_walker_t w;
+       if (lv->nodes) {
+               unsigned idx = get_irn_idx(irn);
+               struct _lv_walker_t w;
 
-       /*
-        * Removes a single irn from the liveness information.
-        * Since an irn can only be live at blocks dominated by the block of its
-        * definition, we only have to process that dominance subtree.
-        */
-       w.lv   = lv;
-       w.data = irn;
-       dom_tree_walk(get_nodes_block(irn), lv_remove_irn_walker, NULL, &w);
-       if(idx < bitset_size(lv->nodes))
-               bitset_clear(lv->nodes, idx);
+               /*
+                * Removes a single irn from the liveness information.
+                * Since an irn can only be live at blocks dominated by the block of its
+                * definition, we only have to process that dominance subtree.
+                */
+               w.lv   = lv;
+               w.data = irn;
+               dom_tree_walk(get_nodes_block(irn), lv_remove_irn_walker, NULL, &w);
+               if(idx < bitset_size(lv->nodes))
+                       bitset_clear(lv->nodes, idx);
+       }
 }
 
 void be_liveness_introduce(be_lv_t *lv, ir_node *irn)
 {
-       struct _lv_walker_t w;
-       w.lv   = lv;
-       w.data = bitset_malloc(get_irg_last_idx(lv->irg));
-       liveness_for_node(irn, &w);
-       bitset_free(w.data);
+       if (lv->nodes) {
+               struct _lv_walker_t w;
+               w.lv   = lv;
+               w.data = bitset_malloc(get_irg_last_idx(lv->irg));
+               liveness_for_node(irn, &w);
+               bitset_free(w.data);
+       }
 }
 
 void be_liveness_update(be_lv_t *lv, ir_node *irn)
@@ -560,23 +586,6 @@ void be_liveness_update(be_lv_t *lv, ir_node *irn)
        be_liveness_introduce(lv, irn);
 }
 
-static void lv_add_missing_walker(ir_node *irn, void *data)
-{
-       struct _lv_walker_t *w = data;
-       if(!is_Block(irn) && !bitset_contains_irn(w->lv->nodes, irn)) {
-               liveness_for_node(irn, w);
-       }
-}
-
-void be_liveness_add_missing(be_lv_t *lv)
-{
-       struct _lv_walker_t w;
-       w.lv   = lv;
-       w.data = bitset_malloc(get_irg_last_idx(lv->irg));
-       irg_walk_graph(lv->irg, lv_add_missing_walker, NULL, &w);
-       bitset_free(w.data);
-}
-
 static void lv_check_walker(ir_node *bl, void *data)
 {
        struct _lv_walker_t *w = data;
@@ -753,6 +762,7 @@ void be_liveness_transfer_ir_nodeset(const arch_env_t *arch_env,
 pset *be_liveness_end_of_block(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *bl, pset *live)
 {
        int i;
+       assert(lv->nodes && "live sets must be computed");
        be_lv_foreach(lv, bl, be_lv_state_end, i) {
                ir_node *irn = be_lv_get_irn(lv, bl, i);
                if(arch_irn_consider_in_reg_alloc(arch_env, cls, irn))
@@ -770,6 +780,7 @@ void be_liveness_end_of_block_ir_nodeset(const be_lv_t *lv,
 {
        int i;
 
+       assert(lv->nodes && "live sets must be computed");
        be_lv_foreach(lv, block, be_lv_state_end, i) {
                ir_node *node = be_lv_get_irn(lv, block, i);
                if(!arch_irn_consider_in_reg_alloc(arch_env, cls, node))
@@ -806,6 +817,7 @@ pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_
        const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
        ir_node *irn;
 
+       assert(lv->nodes && "live sets must be computed");
        be_liveness_end_of_block(lv, arch_env, cls, bl, live);
        sched_foreach_reverse(bl, irn) {
                be_liveness_transfer(arch_env, cls, irn, live);
@@ -822,22 +834,15 @@ static void collect_node(ir_node *irn, void *data)
        obstack_ptr_grow(obst, irn);
 }
 
-void be_live_chk_compare(be_irg_t *birg)
+void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc)
 {
-       ir_graph *irg    = be_get_birg_irg(birg);
+       ir_graph *irg    = lv->irg;
 
        struct obstack obst;
        ir_node **nodes;
        ir_node **blocks;
-       be_lv_t *lv;
-       lv_chk_t *lvc;
        int i, j;
 
-       be_assure_liveness(birg);
-       be_assure_liveness_chk(birg);
-       lv  = be_get_birg_liveness(birg);
-       lvc = be_get_birg_liveness_chk(birg);
-
        obstack_init(&obst);
 
        irg_block_walk_graph(irg, collect_node, NULL, &obst);
index 1a3b4ac..1021f3c 100644 (file)
@@ -192,5 +192,25 @@ pset *be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env, c
  */
 pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live);
 
+/**
+ * Make sure the live sets are computed.
+ * @param lv The liveness infirmation.
+ */
+void be_liveness_assure_sets(be_lv_t *lv);
+
+/**
+ * Make sure all information needed for liveness checks is available.
+ * @param lv The liveness information.
+ */
+void be_liveness_assure_chk(be_lv_t *lv);
+
+/**
+ * Invalidate the liveness information.
+ * You must call this if you modify the program and do not
+ * update the liveness with the be_liveness_{update,remove,introduce}
+ * functions.
+ * @param lv The liveness info.
+ */
+void be_liveness_invalidate(be_lv_t *lv);
 
 #endif /* FIRM_BE_BELIVE_H */
index 4a79d38..3f248fe 100644 (file)
 
 #include "belive.h"
 
+#define USE_LIVE_CHK
+
+#ifdef USE_LIVE_CHK
+#include "irlivechk.h"
+#endif
+
 struct _be_lv_t {
        ir_phase ph;
        ir_graph *irg;
        bitset_t *nodes;
        hook_entry_t hook_info;
+#ifdef USE_LIVE_CHK
+       lv_chk_t *lvc;
+#endif
 };
 
 struct _be_lv_info_node_t {
@@ -88,8 +97,17 @@ struct _be_lv_info_node_t *be_lv_get(const struct _be_lv_t *li, const ir_node *b
 
 static INLINE int _be_is_live_xxx(const struct _be_lv_t *li, const ir_node *block, const ir_node *irn, unsigned flags)
 {
-       struct _be_lv_info_node_t *info = be_lv_get(li, block, irn);
-       return info ? (info->flags & flags) != 0 : 0;
+       if (li->nodes) {
+               struct _be_lv_info_node_t *info = be_lv_get(li, block, irn);
+               return info ? (info->flags & flags) != 0 : 0;
+       }
+
+#ifdef USE_LIVE_CHK
+       else
+               return (lv_chk_bl_xxx(li->lvc, block, irn) & flags) != 0;
+#else
+       assert(li->nodes && "node sets must be computed");
+#endif /* USE_LIVE_CHK */
 }
 
 #define be_lv_foreach(lv, bl, flags, i) \
index a02a73c..e29be2d 100644 (file)
@@ -872,7 +872,7 @@ void assure_constraints(be_irg_t *birg) {
 
        del_pset(cenv.op_set);
        obstack_free(&cenv.obst, NULL);
-       be_invalidate_liveness(birg);
+       be_liveness_invalidate(be_get_birg_liveness(birg));
 }
 
 
index cb0d1c2..6b9c34b 100644 (file)
@@ -133,7 +133,7 @@ void be_analyze_regpressure(be_irg_t *birg, const arch_register_class_t *cls, co
        f = fopen(fname, "w");
        assert(f);
 
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(be_assure_liveness(birg));
 
        FIRM_DBG_REGISTER(ra.dbg, "firm.be.regpressureana");
 
index 36305a6..6f66ad0 100644 (file)
@@ -783,7 +783,7 @@ static void be_ra_extern_main(be_irg_t *birg) {
        /* Clean up */
        free_ssa_destr_simple(raenv.vars);
 
-       be_invalidate_liveness(birg);
+       be_liveness_invalidate(be_get_birg_liveness(birg));
 }
 
 /******************************************************************************
index 9d8385c..57cfbd3 100644 (file)
@@ -892,7 +892,7 @@ void be_insert_spills_reloads(spill_env_t *env)
        be_remove_dead_nodes_from_schedule(env->irg);
        /* Matze: In theory be_ssa_construction should take care of the liveness...
         * try to disable this again in the future */
-       be_invalidate_liveness(env->birg);
+       be_liveness_invalidate(env->birg->lv);
 }
 
 void be_init_spill(void)
index 948bbe4..151344e 100644 (file)
@@ -83,7 +83,7 @@ typedef struct _belady_env_t {
        struct obstack ob;
        const arch_env_t *arch;
        const arch_register_class_t *cls;
-       const be_lv_t *lv;
+       be_lv_t *lv;
        be_loopana_t *loop_ana;
        int n_regs;                     /** number of regs in this reg-class */
 
@@ -709,8 +709,8 @@ void be_spill_belady_spill_env(be_irg_t *birg, const arch_register_class_t *cls,
        if(n_regs == 0)
                return;
 
-       be_invalidate_liveness(birg);
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(be_assure_liveness(birg));
+
        /* construct control flow loop tree */
        if(! (get_irg_loopinfo_state(irg) & loopinfo_cf_consistent)) {
                construct_cf_backedges(irg);
index fde2d65..b9459ca 100644 (file)
@@ -374,8 +374,7 @@ void be_spill_daemel(be_irg_t *birg, const arch_register_class_t *cls)
        if(n_regs == 0)
                return;
 
-       be_invalidate_liveness(birg);
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(be_assure_liveness(birg));
 
        env.spill_env     = be_new_spill_env(birg);
        env.n_regs        = n_regs;
index e931929..0f10523 100644 (file)
@@ -59,7 +59,7 @@ typedef struct morgan_env {
        const arch_env_t *arch;
        const arch_register_class_t *cls;
        ir_graph *irg;
-       const be_lv_t *lv;
+       be_lv_t *lv;
        struct obstack obst;
        /** maximum safe register pressure */
        int registers_available;
@@ -564,7 +564,7 @@ void be_spill_morgan(be_irg_t *birg, const arch_register_class_t *cls) {
        ir_graph     *irg = be_get_birg_irg(birg);
        morgan_env_t env;
 
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(be_assure_liveness(birg));
 
        env.arch = birg->main_env->arch_env;
        env.irg  = irg;
index 103a8d2..8a9de9c 100644 (file)
 
 /**
  * @file
- * @brief       Naiv spilling algorithm
+ * @brief       Naive spilling algorithm
  * @author      Matthias Braun
  * @date        20.09.2005
- * @version     $Id: bespillbelady.c 13913 2007-05-18 12:48:56Z matze $
+ * @version     $Id$
  * @summary
- *   This implements a naiv spilling algorithm. It is design to produce similar
+ *   This implements a naive spilling algorithm. It is design to produce similar
  *   effects to the spill decisions produced by traditional graph coloring
  *   register allocators that spill while they are coloring the graph.
  *
@@ -63,7 +63,7 @@ struct daemel_env_t {
        int                          n_regs;
        const arch_env_t            *arch_env;
        const arch_register_class_t *cls;
-       const be_lv_t               *lv;
+       be_lv_t               *lv;
        bitset_t                    *spilled_nodes;
 };
 
@@ -316,8 +316,7 @@ void be_spill_daemel(be_irg_t *birg, const arch_register_class_t *cls)
        if(n_regs == 0)
                return;
 
-       be_invalidate_liveness(birg);
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(be_assure_liveness(birg));
 
        env.spill_env     = be_new_spill_env(birg);
        env.n_regs        = n_regs;
index b8fc978..4946166 100644 (file)
@@ -662,7 +662,7 @@ be_fec_env_t *be_new_frame_entity_coalescer(be_irg_t *birg)
        const arch_env_t *arch_env = birg->main_env->arch_env;
        be_fec_env_t     *env      = xmalloc(sizeof(env[0]));
 
-       be_assure_liveness(birg);
+       be_liveness_assure_chk(be_assure_liveness(birg));
 
        obstack_init(&env->obst);
        env->arch_env       = arch_env;
index 41c11d3..c0f66b6 100644 (file)
@@ -169,7 +169,6 @@ static void insert_all_perms_walker(ir_node *bl, void *data) {
                        perm = be_new_Perm(chordal_env->cls, irg, pred_bl, n_projs, in);
                        be_stat_ev("phi_perm", n_projs);
 
-                       free(in);
                        insert_after = sched_skip(sched_last(pred_bl), 0, sched_skip_cf_predicator, chordal_env->birg->main_env->arch_env);
                        sched_add_after(insert_after, perm);
 
@@ -199,9 +198,19 @@ static void insert_all_perms_walker(ir_node *bl, void *data) {
                                pp        = set_find(arg_set, &templ, sizeof(templ), nodeset_hash(templ.arg));
 
                                /* If not found, it was an interfering argument */
-                               if (pp)
+                               if (pp) {
                                        set_irn_n(phi, i, pp->proj);
+                                       be_liveness_introduce(lv, pp->proj);
+                               }
+                       }
+
+                       /* update the liveness of the Perm's operands. It might be changed. */
+                       {
+                               int i;
+                               for (i = 0; i < n_projs; ++i)
+                                       be_liveness_update(lv, in[i]);
                        }
+                       free(in);
 
                        /* register in perm map */
                        pmap_insert(perm_map, pred_bl, perm);
@@ -221,6 +230,7 @@ static void insert_all_perms_walker(ir_node *bl, void *data) {
  */
 static void    set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
        be_chordal_env_t *chordal_env = data;
+       be_lv_t *lv = chordal_env->birg->lv;
        ir_node *phi;
 
        /* Consider all phis of this block */
@@ -273,6 +283,8 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
                                set_reg(dupl, phi_reg);
                                sched_add_after(sched_skip(sched_last(arg_block), 0, sched_skip_cf_predicator, chordal_env->birg->main_env->arch_env), dupl);
                                pin_irn(dupl, phi_block);
+                               be_liveness_introduce(lv, dupl);
+                               be_liveness_update(lv, arg);
                                DBG((dbg, LEVEL_1, "    they do interfere: insert %+F(%s)\n", dupl, get_reg(dupl)->name));
                                continue; /* with next argument */
                        }
@@ -345,6 +357,8 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
                                for(ins = sched_next(perm); is_Proj(ins); ins = sched_next(ins));
                                sched_add_before(ins, dupl);
                                pin_irn(dupl, phi_block);
+                               be_liveness_introduce(lv, dupl);
+                               be_liveness_update(lv, arg);
                                DBG((dbg, LEVEL_1, "      arg is pinned: insert %+F(%s)\n", dupl, get_reg(dupl)->name));
                        } else {
                                /*
@@ -360,13 +374,14 @@ static void       set_regs_or_place_dupls_walker(ir_node *bl, void *data) {
 }
 
 void be_ssa_destruction(be_chordal_env_t *chordal_env) {
+       insert_all_perms_env_t insert_perms_env;
        pmap *perm_map = pmap_create();
        ir_graph *irg  = chordal_env->irg;
-       insert_all_perms_env_t insert_perms_env;
+       be_lv_t *lv    = be_assure_liveness(chordal_env->birg);
 
        FIRM_DBG_REGISTER(dbg, "ir.be.ssadestr");
 
-       be_assure_liveness(chordal_env->birg);
+       be_liveness_assure_sets(lv);
 
        /* create a map for fast lookup of perms: block --> perm */
        irg_walk_graph(irg, clear_link, collect_phis_walker, chordal_env);
@@ -376,16 +391,21 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) {
        insert_perms_env.perm_map = perm_map;
        irg_block_walk_graph(irg, insert_all_perms_walker, NULL, &insert_perms_env);
 
+       // Matze: really needed here?
+       // Sebastian: Yes. the walker function uses interference.
+       be_liveness_invalidate(lv);
+
        if (chordal_env->opts->dump_flags & BE_CH_DUMP_SSADESTR)
                be_dump(irg, "-ssa_destr_perms_placed", dump_ir_block_graph_sched);
 
-       // Matze: really needed here?
-       be_invalidate_liveness(chordal_env->birg);
-       be_assure_liveness(chordal_env->birg);
+       be_liveness_assure_chk(lv);
 
        DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n"));
        irg_block_walk_graph(irg, set_regs_or_place_dupls_walker, NULL, chordal_env);
 
+       /* TODO: unfortunaltely updating doesn't work yet. */
+       be_liveness_invalidate(lv);
+
        if (chordal_env->opts->dump_flags & BE_CH_DUMP_SSADESTR)
                be_dump(irg, "-ssa_destr_regs_set", dump_ir_block_graph_sched);
 
index f883f87..37c5cbe 100644 (file)
@@ -502,9 +502,9 @@ void be_assure_state(be_irg_t *birg, const arch_register_t *reg, void *func_env,
        minibelady_env_t env;
        ir_graph *irg = be_get_birg_irg(birg);
        spill_info_t *info;
-       be_lv_t *lv = be_get_birg_liveness(birg);
+       be_lv_t *lv = be_assure_liveness(birg);
 
-       be_assure_liveness(birg);
+       be_liveness_assure_sets(lv);
        be_assure_dom_front(birg);
        /* construct control flow loop tree */
        if(! (get_irg_loopinfo_state(irg) & loopinfo_cf_consistent)) {
index d342f8a..bc078eb 100644 (file)
@@ -308,7 +308,8 @@ void be_transform_graph(be_irg_t *birg, arch_pretrans_nodes *func, void *cg)
        free_trouts();
        free_loop_information(irg);
        set_irg_doms_inconsistent(irg);
-       be_invalidate_liveness(birg);
+
+       be_liveness_invalidate(be_get_birg_liveness(birg));
        be_invalidate_dom_front(birg);
 
        /* create a new obstack */
index 3ced0cc..799793e 100644 (file)
@@ -125,6 +125,7 @@ int be_verify_register_pressure(const be_irg_t *birg,
        env.registers_available = env.cls->n_regs - be_put_ignore_regs(birg, env.cls, NULL);
        env.problem_found       = 0;
 
+       be_liveness_assure_sets(env.lv);
        irg_block_walk_graph(irg, verify_liveness_walker, NULL, &env);
        be_liveness_free(env.lv);
 
@@ -849,6 +850,7 @@ int be_verify_register_allocation(const arch_env_t *arch_env, ir_graph *irg) {
        env.lv = be_liveness(irg);
        env.problem_found = 0;
 
+       be_liveness_assure_sets(env.lv);
        irg_block_walk_graph(irg, verify_block_register_allocation, NULL, &env);
 
        be_liveness_free(env.lv);
index 12eb258..fee5acf 100644 (file)
@@ -2191,9 +2191,10 @@ void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
        sim.worklist = new_waitq();
        waitq_put(sim.worklist, start_block);
 
-       be_invalidate_liveness(birg);
        be_assure_liveness(birg);
        sim.lv = be_get_birg_liveness(birg);
+//     sim.lv = be_liveness(be_get_birg_irg(birg));
+       be_liveness_assure_sets(sim.lv);
 
        /* Calculate the liveness for all nodes. We must precalculate this info,
         * because the simulator adds new nodes (possible before Phi nodes) which