X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelower.c;h=ee09f6b537abe1e808cdb87631bd8eedbea66805;hb=dbc419164cf5e14cdf5757f1e105d02693bacb9f;hp=0ac9b746464c7487ca8a4462380dcb8f7ad8dacf;hpb=c2fcdf7cddd0c74d5b6562e7ddce316f1695d800;p=libfirm diff --git a/ir/be/belower.c b/ir/be/belower.c index 0ac9b7464..ee09f6b53 100644 --- a/ir/be/belower.c +++ b/ir/be/belower.c @@ -24,9 +24,7 @@ * @date 14.12.2005 * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include @@ -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 */