- use ir_nodemap_t instead of pset: This probably
[libfirm] / ir / be / belower.c
index 0ac9b74..ee09f6b 100644 (file)
@@ -24,9 +24,7 @@
  * @date        14.12.2005
  * @version     $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <stdlib.h>
 
@@ -35,6 +33,7 @@
 #include "irhooks.h"
 #include "xmalloc.h"
 #include "irnodeset.h"
+#include "irnodemap.h"
 #include "irgmod.h"
 #include "iredges_t.h"
 #include "irgwalk.h"
@@ -50,9 +49,8 @@
 
 #undef KEEP_ALIVE_COPYKEEP_HACK
 
-/** Associates an op with it's copy and CopyKeep. */
+/** Associates an ir_node with it's copy and CopyKeep. */
 typedef struct {
-       ir_node *op;         /**< an irn which must be different */
        ir_nodeset_t copies; /**< all non-spillable copies of this irn */
        const arch_register_class_t *cls;
 } op_copy_assoc_t;
@@ -60,7 +58,7 @@ typedef struct {
 /** Environment for constraints. */
 typedef struct {
        be_irg_t       *birg;
-       pset           *op_set;
+       ir_nodemap_t   op_set;
        struct obstack obst;
        DEBUG_ONLY(firm_dbg_module_t *dbg;)
 } constraint_env_t;
@@ -68,7 +66,6 @@ typedef struct {
 /** Lowering walker environment. */
 typedef struct _lower_env_t {
        be_irg_t         *birg;
-       const arch_env_t *arch_env;
        unsigned          do_copy : 1;
        DEBUG_ONLY(firm_dbg_module_t *dbg_module;)
 } lower_env_t;
@@ -98,14 +95,6 @@ typedef struct _perm_cycle_t {
        perm_type_t             type;        /**< type (CHAIN or CYCLE) */
 } perm_cycle_t;
 
-/** Compare the two operands. */
-static int cmp_op_copy_assoc(const void *a, const void *b) {
-       const op_copy_assoc_t *op1 = a;
-       const op_copy_assoc_t *op2 = b;
-
-       return op1->op != op2->op;
-}
-
 /** Compare the in registers of two register pairs. */
 static int compare_reg_pair(const void *a, const void *b) {
        const reg_pair_t *pair_a = a;
@@ -283,7 +272,6 @@ static perm_cycle_t *get_perm_cycle(perm_cycle_t *cycle, reg_pair_t *pairs, int
 static void lower_perm_node(ir_node *irn, void *walk_env) {
        ir_graph        *irg = get_irn_irg(irn);
        const arch_register_class_t *reg_class;
-       const arch_env_t            *arch_env;
        lower_env_t     *env         = walk_env;
        int             real_size    = 0;
        int             keep_perm    = 0;
@@ -295,7 +283,6 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
        ir_node         *cpyxchg = NULL;
        DEBUG_ONLY(firm_dbg_module_t *mod;)
 
-       arch_env = env->arch_env;
        do_copy  = env->do_copy;
        DEBUG_ONLY(mod = env->dbg_module;)
        block    = get_nodes_block(irn);
@@ -314,7 +301,7 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
        n = get_irn_arity(irn);
        assert(n == get_irn_n_edges(irn) && "perm's in and out numbers different");
 
-       reg_class = arch_get_irn_register(arch_env, get_irn_n(irn, 0))->reg_class;
+       reg_class = arch_get_irn_register(get_irn_n(irn, 0))->reg_class;
        pairs     = alloca(n * sizeof(pairs[0]));
 
        /* build the list of register pairs (in, out) */
@@ -324,8 +311,8 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
                pn                = get_Proj_proj(pairs[i].out_node);
                pairs[i].in_node  = get_irn_n(irn, pn);
 
-               pairs[i].in_reg  = arch_get_irn_register(arch_env, pairs[i].in_node);
-               pairs[i].out_reg = arch_get_irn_register(arch_env, pairs[i].out_node);
+               pairs[i].in_reg  = arch_get_irn_register(pairs[i].in_node);
+               pairs[i].out_reg = arch_get_irn_register(pairs[i].out_node);
 
                pairs[i].checked = 0;
                i++;
@@ -465,8 +452,8 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
                                set_Proj_pred(res1, cpyxchg);
                                set_Proj_proj(res1, 1);
 
-                               arch_set_irn_register(arch_env, res2, cycle->elems[i + 1]);
-                               arch_set_irn_register(arch_env, res1, cycle->elems[i]);
+                               arch_set_irn_register(res2, cycle->elems[i + 1]);
+                               arch_set_irn_register(res1, cycle->elems[i]);
 
                                /* insert the copy/exchange node in schedule after the magic schedule node (see above) */
                                sched_add_after(sched_point, cpyxchg);
@@ -481,7 +468,7 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
                                        irn, arg1, cycle->elems[i]->name, res2, cycle->elems[i + 1]->name));
 
                                cpyxchg = be_new_Copy(reg_class, irg, block, arg1);
-                               arch_set_irn_register(arch_env, cpyxchg, cycle->elems[i + 1]);
+                               arch_set_irn_register(cpyxchg, cycle->elems[i + 1]);
                                n_ops++;
 
                                /* exchange copy node and proj */
@@ -521,16 +508,16 @@ static INLINE ir_node *belower_skip_proj(ir_node *irn) {
        return irn;
 }
 
-static ir_node *find_copy(constraint_env_t *env, ir_node *irn, ir_node *op) {
-       const arch_env_t *arch_env = be_get_birg_arch_env(env->birg);
-       ir_node          *block    = get_nodes_block(irn);
-       ir_node          *cur_node;
+static ir_node *find_copy(ir_node *irn, ir_node *op)
+{
+       ir_node *block    = get_nodes_block(irn);
+       ir_node *cur_node;
 
        for (cur_node = sched_prev(irn);
                ! is_Block(cur_node) && be_is_Copy(cur_node) && get_nodes_block(cur_node) == block;
                cur_node = sched_prev(cur_node))
        {
-               if (be_get_Copy_op(cur_node) == op && arch_irn_is(arch_env, cur_node, dont_spill))
+               if (be_get_Copy_op(cur_node) == op && arch_irn_is(cur_node, dont_spill))
                        return cur_node;
        }
 
@@ -540,15 +527,15 @@ static ir_node *find_copy(constraint_env_t *env, ir_node *irn, ir_node *op) {
 static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env) {
        be_irg_t                    *birg     = env->birg;
        ir_graph                    *irg      = be_get_birg_irg(birg);
-       pset                        *op_set   = env->op_set;
-       const arch_env_t            *arch_env = be_get_birg_arch_env(birg);
+       ir_nodemap_t                *op_set   = &env->op_set;
        ir_node                     *block    = get_nodes_block(irn);
        const arch_register_class_t *cls      = arch_get_irn_reg_class(other_different, -1);
        ir_node                     *in[2], *keep, *cpy;
-       op_copy_assoc_t             key, *entry;
+       op_copy_assoc_t             *entry;
        DEBUG_ONLY(firm_dbg_module_t *mod     = env->dbg;)
 
-       if (arch_irn_is(arch_env, other_different, ignore) || ! mode_is_datab(get_irn_mode(other_different))) {
+       if (arch_irn_is(other_different, ignore) ||
+                       !mode_is_datab(get_irn_mode(other_different))) {
                DBG((mod, LEVEL_1, "ignore constraint for %+F because other_irn is ignore or not a datab node\n", irn));
                return;
        }
@@ -559,7 +546,7 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
        /* The copy is optimized later if not needed         */
 
        /* check if already exists such a copy in the schedule immediately before */
-       cpy = find_copy(env, belower_skip_proj(irn), other_different);
+       cpy = find_copy(belower_skip_proj(irn), other_different);
        if (! cpy) {
                cpy = be_new_Copy(cls, irg, block, other_different);
                be_node_set_flags(cpy, BE_OUT_POS(0), arch_irn_flags_dont_spill);
@@ -590,15 +577,14 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
                sched_add_before(belower_skip_proj(irn), cpy);
        sched_add_after(irn, keep);
 
-       /* insert the other different and it's copies into the set */
-       key.op = other_different;
-       entry  = pset_find(op_set, &key, hash_irn(other_different));
-
+       /* insert the other different and it's copies into the map */
+       entry = ir_nodemap_get(op_set, other_different);
        if (! entry) {
-               entry         = obstack_alloc(&env->obst, sizeof(*entry));
+               entry      = obstack_alloc(&env->obst, sizeof(*entry));
+               entry->cls = cls;
                ir_nodeset_init(&entry->copies);
-               entry->op     = other_different;
-               entry->cls    = cls;
+
+               ir_nodemap_insert(op_set, other_different, entry);
        }
 
        /* insert copy */
@@ -608,8 +594,6 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
        if (be_is_CopyKeep(keep)) {
                ir_nodeset_insert(&entry->copies, keep);
        }
-
-       pset_insert(op_set, entry, hash_irn(other_different));
 }
 
 /**
@@ -670,10 +654,12 @@ static void assure_constraints_walker(ir_node *irn, void *walk_env) {
 static void melt_copykeeps(constraint_env_t *cenv) {
        be_irg_t *birg = cenv->birg;
        ir_graph *irg  = be_get_birg_irg(birg);
-       op_copy_assoc_t *entry;
+       ir_nodemap_iterator_t map_iter;
+       ir_nodemap_entry_t    map_entry;
 
        /* for all */
-       foreach_pset(cenv->op_set, entry) {
+       foreach_ir_nodemap(&cenv->op_set, map_entry, map_iter) {
+               op_copy_assoc_t *entry = map_entry.data;
                int     idx, num_ck;
                ir_node *cp;
                struct obstack obst;
@@ -789,15 +775,16 @@ static void melt_copykeeps(constraint_env_t *cenv) {
  * @param birg  The birg structure containing the irg
  */
 void assure_constraints(be_irg_t *birg) {
-       ir_graph         *irg      = be_get_birg_irg(birg);
-       constraint_env_t cenv;
-       op_copy_assoc_t  *entry;
-       ir_node          **nodes;
+       ir_graph              *irg = be_get_birg_irg(birg);
+       constraint_env_t      cenv;
+       ir_node               **nodes;
+       ir_nodemap_iterator_t map_iter;
+       ir_nodemap_entry_t    map_entry;
        FIRM_DBG_REGISTER(firm_dbg_module_t *mod, "firm.be.lower.constr");
 
        DEBUG_ONLY(cenv.dbg = mod;)
        cenv.birg   = birg;
-       cenv.op_set = new_pset(cmp_op_copy_assoc, 16);
+       ir_nodemap_init(&cenv.op_set);
        obstack_init(&cenv.obst);
 
        irg_walk_blkwise_graph(irg, NULL, assure_constraints_walker, &cenv);
@@ -808,7 +795,8 @@ void assure_constraints(be_irg_t *birg) {
        melt_copykeeps(&cenv);
 
        /* for all */
-       foreach_pset(cenv.op_set, entry) {
+       foreach_ir_nodemap(&cenv.op_set, map_entry, map_iter) {
+               op_copy_assoc_t *entry = map_entry.data;
                int     n;
                ir_node *cp;
                ir_nodeset_iterator_t iter;
@@ -818,7 +806,7 @@ void assure_constraints(be_irg_t *birg) {
                nodes = alloca(n * sizeof(nodes[0]));
 
                /* put the node in an array */
-               DBG((mod, LEVEL_1, "introduce copies for %+F ", entry->op));
+               DBG((mod, LEVEL_1, "introduce copies for %+F ", map_entry.node));
 
                /* collect all copies */
                n = 0;
@@ -831,9 +819,9 @@ void assure_constraints(be_irg_t *birg) {
 
                /* introduce the copies for the operand and it's copies */
                be_ssa_construction_init(&senv, birg);
-               be_ssa_construction_add_copy(&senv, entry->op);
+               be_ssa_construction_add_copy(&senv, map_entry.node);
                be_ssa_construction_add_copies(&senv, nodes, n);
-               be_ssa_construction_fix_users(&senv, entry->op);
+               be_ssa_construction_fix_users(&senv, map_entry.node);
                be_ssa_construction_destroy(&senv);
 
                /* Could be that not all CopyKeeps are really needed, */
@@ -856,7 +844,7 @@ void assure_constraints(be_irg_t *birg) {
                ir_nodeset_destroy(&entry->copies);
        }
 
-       del_pset(cenv.op_set);
+       ir_nodemap_destroy(&cenv.op_set);
        obstack_free(&cenv.obst, NULL);
        be_liveness_invalidate(be_get_birg_liveness(birg));
 }
@@ -875,8 +863,7 @@ void assure_constraints(be_irg_t *birg) {
  */
 static int push_through_perm(ir_node *perm, void *data)
 {
-       lower_env_t *env       = data;
-       const arch_env_t *aenv = env->arch_env;
+       lower_env_t *env = data;
 
        ir_graph *irg     = get_irn_irg(perm);
        ir_node *bl       = get_nodes_block(perm);
@@ -914,7 +901,7 @@ static int push_through_perm(ir_node *perm, void *data)
        sched_foreach_reverse_from (sched_prev(perm), irn) {
                for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
                        ir_node *op = get_irn_n(irn, i);
-                       if (arch_irn_consider_in_reg_alloc(aenv, cls, op) &&
+                       if (arch_irn_consider_in_reg_alloc(cls, op) &&
                            !values_interfere(env->birg, op, one_proj)) {
                                frontier = irn;
                                goto found_front;
@@ -948,7 +935,7 @@ found_front:
                        break;
                if(!sched_comes_after(frontier, node))
                        break;
-               if(arch_irn_is(aenv, node, modify_flags))
+               if (arch_irn_is(node, modify_flags))
                        break;
                if(is_Proj(node)) {
                        req = arch_get_register_req(get_Proj_pred(node),
@@ -960,7 +947,7 @@ found_front:
                        break;
                for(i = get_irn_arity(node) - 1; i >= 0; --i) {
                        ir_node *opop = get_irn_n(node, i);
-                       if (arch_irn_consider_in_reg_alloc(aenv, cls, opop)) {
+                       if (arch_irn_consider_in_reg_alloc(cls, opop)) {
                                break;
                        }
                }
@@ -974,7 +961,7 @@ found_front:
                sched_add_after(perm, node);
 
                /* give it the proj's register */
-               arch_set_irn_register(aenv, node, arch_get_irn_register(aenv, proj));
+               arch_set_irn_register(node, arch_get_irn_register(proj));
 
                /* reroute all users of the proj to the moved node. */
                edges_reroute(proj, node, irg);
@@ -1054,9 +1041,8 @@ void lower_nodes_after_ra(be_irg_t *birg, int do_copy) {
        lower_env_t env;
        ir_graph    *irg = be_get_birg_irg(birg);
 
-       env.birg     = birg;
-       env.arch_env = be_get_birg_arch_env(birg);
-       env.do_copy  = do_copy;
+       env.birg    = birg;
+       env.do_copy = do_copy;
        FIRM_DBG_REGISTER(env.dbg_module, "firm.be.lower");
 
        /* we will need interference */