X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelower.c;h=344564cbefc822e894fcb1d6e317849c2d930d7a;hb=fc81b817119d8635eaeb345c8623255fc51bdb22;hp=1441c76fc9ad77ce3a1eb45e5830aff981c1e3f7;hpb=f80c2581282158d2c148640d9425e83fcd8cfa14;p=libfirm diff --git a/ir/be/belower.c b/ir/be/belower.c index 1441c76fc..344564cbe 100644 --- a/ir/be/belower.c +++ b/ir/be/belower.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -38,10 +38,10 @@ #include "irgwalk.h" #include "array_t.h" -#include "bearch_t.h" +#include "bearch.h" #include "belower.h" -#include "benode_t.h" -#include "besched_t.h" +#include "benode.h" +#include "besched.h" #include "bestat.h" #include "bessaconstr.h" #include "beintlive_t.h" @@ -52,7 +52,7 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg;) DEBUG_ONLY(static firm_dbg_module_t *dbg_constr;) DEBUG_ONLY(static firm_dbg_module_t *dbg_permmove;) -/** Associates an ir_node with it's copy and CopyKeep. */ +/** Associates an ir_node with its copy and CopyKeep. */ typedef struct { ir_nodeset_t copies; /**< all non-spillable copies of this irn */ const arch_register_class_t *cls; @@ -60,19 +60,19 @@ typedef struct { /** Environment for constraints. */ typedef struct { - be_irg_t *birg; + ir_graph *irg; ir_nodemap_t op_set; struct obstack obst; } constraint_env_t; /** Lowering walker environment. */ -typedef struct _lower_env_t { - be_irg_t *birg; - unsigned do_copy : 1; +typedef struct lower_env_t { + ir_graph *irg; + unsigned do_copy : 1; } lower_env_t; /** Holds a Perm register pair. */ -typedef struct _reg_pair_t { +typedef struct reg_pair_t { const arch_register_t *in_reg; /**< a perm IN register */ ir_node *in_node; /**< the in node to which the register belongs */ @@ -82,7 +82,7 @@ typedef struct _reg_pair_t { int checked; /**< indicates whether the pair was check for cycle or not */ } reg_pair_t; -typedef enum _perm_type_t { +typedef enum perm_type_t { PERM_CYCLE, PERM_CHAIN, PERM_SWAP, @@ -90,7 +90,7 @@ typedef enum _perm_type_t { } perm_type_t; /** Structure to represent cycles or chains in a Perm. */ -typedef struct _perm_cycle_t { +typedef struct perm_cycle_t { const arch_register_t **elems; /**< the registers in the cycle */ int n_elems; /**< number of elements in the cycle */ perm_type_t type; /**< type (CHAIN or CYCLE) */ @@ -120,7 +120,8 @@ static int get_n_unchecked_pairs(reg_pair_t const *const pairs, int const n) * @param reg The register to look for * @return The corresponding node or NULL if not found */ -static ir_node *get_node_for_in_register(reg_pair_t *pairs, int n, const arch_register_t *reg) { +static ir_node *get_node_for_in_register(reg_pair_t *pairs, int n, const arch_register_t *reg) +{ int i; for (i = 0; i < n; i++) { @@ -142,7 +143,8 @@ static ir_node *get_node_for_in_register(reg_pair_t *pairs, int n, const arch_re * @param reg The register to look for * @return The corresponding node or NULL if not found */ -static ir_node *get_node_for_out_register(reg_pair_t *pairs, int n, const arch_register_t *reg) { +static ir_node *get_node_for_out_register(reg_pair_t *pairs, int n, const arch_register_t *reg) +{ int i; for (i = 0; i < n; i++) { @@ -164,7 +166,8 @@ static ir_node *get_node_for_out_register(reg_pair_t *pairs, int n, const arch_r * * @return The corresponding index in pairs or -1 if not found */ -static int get_pairidx_for_in_regidx(reg_pair_t *pairs, int n, unsigned reg_idx) { +static int get_pairidx_for_in_regidx(reg_pair_t *pairs, int n, unsigned reg_idx) +{ int i; for (i = 0; i < n; i++) { @@ -185,7 +188,8 @@ static int get_pairidx_for_in_regidx(reg_pair_t *pairs, int n, unsigned reg_idx) * * @return The corresponding index in pairs or -1 if not found */ -static int get_pairidx_for_out_regidx(reg_pair_t *pairs, int n, unsigned reg_idx) { +static int get_pairidx_for_out_regidx(reg_pair_t *pairs, int n, unsigned reg_idx) +{ int i; for (i = 0; i < n; i++) { @@ -326,9 +330,9 @@ static void lower_perm_node(ir_node *irn, lower_env_t *env) pair = &pairs[n++]; pair->in_node = in; - pair->in_reg = arch_get_irn_register(in); + pair->in_reg = in_reg; pair->out_node = out; - pair->out_reg = arch_get_irn_register(out); + pair->out_reg = out_reg; pair->checked = 0; } @@ -424,7 +428,7 @@ static void lower_perm_node(ir_node *irn, lower_env_t *env) int pidx = get_pairidx_for_in_regidx(pairs, n, cycle.elems[i]->index); /* create intermediate proj */ - res1 = new_r_Proj(block, cpyxchg, get_irn_mode(res1), 0); + res1 = new_r_Proj(cpyxchg, get_irn_mode(res1), 0); /* set as in for next Perm */ pairs[pidx].in_node = res1; @@ -478,7 +482,8 @@ static void lower_perm_node(ir_node *irn, lower_env_t *env) -static int has_irn_users(const ir_node *irn) { +static int has_irn_users(const ir_node *irn) +{ return get_irn_out_edge_first_kind(irn, EDGE_KIND_NORMAL) != 0; } @@ -495,8 +500,8 @@ static ir_node *find_copy(ir_node *irn, ir_node *op) } } -static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env) { - ir_graph *irg; +static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env) +{ ir_nodemap_t *op_set; ir_node *block; const arch_register_class_t *cls; @@ -509,7 +514,6 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, return; } - irg = be_get_birg_irg(env->birg); op_set = &env->op_set; block = get_nodes_block(irn); cls = arch_get_irn_reg_class_out(other_different); @@ -539,7 +543,7 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, in[0] = irn; in[1] = cpy; - keep = be_new_Keep(cls, block, 2, in); + keep = be_new_Keep(block, 2, in); } DB((dbg_constr, LEVEL_1, "created %+F(%+F, %+F)\n\n", keep, irn, cpy)); @@ -550,10 +554,10 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, sched_add_before(skip_Proj(irn), cpy); sched_add_after(skip_Proj(irn), keep); - /* insert the other different and it's copies into the map */ - entry = ir_nodemap_get(op_set, other_different); + /* insert the other different and its copies into the map */ + entry = (op_copy_assoc_t*)ir_nodemap_get(op_set, other_different); if (! entry) { - entry = obstack_alloc(&env->obst, sizeof(*entry)); + entry = OALLOC(&env->obst, op_copy_assoc_t); entry->cls = cls; ir_nodeset_init(&entry->copies); @@ -576,7 +580,8 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, * @param skipped_irn if irn is a Proj node, its predecessor, else irn * @param env the constraint environment */ -static void assure_different_constraints(ir_node *irn, ir_node *skipped_irn, constraint_env_t *env) { +static void assure_different_constraints(ir_node *irn, ir_node *skipped_irn, constraint_env_t *env) +{ const arch_register_req_t *req = arch_get_register_req_out(irn); if (arch_register_req_is(req, must_be_different)) { @@ -614,8 +619,10 @@ static void assure_different_constraints(ir_node *irn, ir_node *skipped_irn, con * @param block The block to be checked * @param walk_env The walker environment */ -static void assure_constraints_walker(ir_node *block, void *walk_env) { +static void assure_constraints_walker(ir_node *block, void *walk_env) +{ ir_node *irn; + constraint_env_t *env = (constraint_env_t*)walk_env; sched_foreach_reverse(block, irn) { ir_mode *mode = get_irn_mode(irn); @@ -628,10 +635,10 @@ static void assure_constraints_walker(ir_node *block, void *walk_env) { mode = get_irn_mode(proj); if (mode_is_datab(mode)) - assure_different_constraints(proj, irn, walk_env); + assure_different_constraints(proj, irn, env); } } else if (mode_is_datab(mode)) { - assure_different_constraints(irn, irn, walk_env); + assure_different_constraints(irn, irn, env); } } } @@ -640,13 +647,14 @@ static void assure_constraints_walker(ir_node *block, void *walk_env) { * Melt all copykeeps pointing to the same node * (or Projs of the same node), copying the same operand. */ -static void melt_copykeeps(constraint_env_t *cenv) { +static void melt_copykeeps(constraint_env_t *cenv) +{ ir_nodemap_iterator_t map_iter; ir_nodemap_entry_t map_entry; /* for all */ foreach_ir_nodemap(&cenv->op_set, map_entry, map_iter) { - op_copy_assoc_t *entry = map_entry.data; + op_copy_assoc_t *entry = (op_copy_assoc_t*)map_entry.data; int idx, num_ck; ir_node *cp; struct obstack obst; @@ -756,20 +764,15 @@ static void melt_copykeeps(constraint_env_t *cenv) { } } -/** - * Walks over all nodes to assure register constraints. - * - * @param birg The birg structure containing the irg - */ -void assure_constraints(be_irg_t *birg) { - ir_graph *irg = be_get_birg_irg(birg); +void assure_constraints(ir_graph *irg) +{ constraint_env_t cenv; ir_nodemap_iterator_t map_iter; ir_nodemap_entry_t map_entry; FIRM_DBG_REGISTER(dbg_constr, "firm.be.lower.constr"); - cenv.birg = birg; + cenv.irg = irg; ir_nodemap_init(&cenv.op_set); obstack_init(&cenv.obst); @@ -782,8 +785,8 @@ void assure_constraints(be_irg_t *birg) { /* for all */ foreach_ir_nodemap(&cenv.op_set, map_entry, map_iter) { - op_copy_assoc_t *entry = map_entry.data; - int n = ir_nodeset_size(&entry->copies); + op_copy_assoc_t *entry = (op_copy_assoc_t*)map_entry.data; + size_t n = ir_nodeset_size(&entry->copies); ir_node **nodes = ALLOCAN(ir_node*, n); ir_node *cp; ir_nodeset_iterator_t iter; @@ -801,8 +804,8 @@ void assure_constraints(be_irg_t *birg) { DB((dbg_constr, LEVEL_1, "\n")); - /* introduce the copies for the operand and it's copies */ - be_ssa_construction_init(&senv, birg); + /* introduce the copies for the operand and its copies */ + be_ssa_construction_init(&senv, irg); be_ssa_construction_add_copy(&senv, map_entry.node); be_ssa_construction_add_copies(&senv, nodes, n); be_ssa_construction_fix_users(&senv, map_entry.node); @@ -812,11 +815,10 @@ void assure_constraints(be_irg_t *birg) { /* so we transform unnecessary ones into Keeps. */ foreach_ir_nodeset(&entry->copies, cp, iter) { if (be_is_CopyKeep(cp) && get_irn_n_edges(cp) < 1) { - const arch_register_class_t *cls = arch_get_irn_reg_class_out(cp); - int n = get_irn_arity(cp); - ir_node *keep; + int n = get_irn_arity(cp); + ir_node *keep; - keep = be_new_Keep(cls, get_nodes_block(cp), n, get_irn_in(cp) + 1); + keep = be_new_Keep(get_nodes_block(cp), n, get_irn_in(cp) + 1); sched_add_before(cp, keep); /* Set all ins (including the block) of the CopyKeep BAD to keep the verifier happy. */ @@ -830,7 +832,7 @@ void assure_constraints(be_irg_t *birg) { ir_nodemap_destroy(&cenv.op_set); obstack_free(&cenv.obst, NULL); - be_liveness_invalidate(be_get_birg_liveness(birg)); + be_liveness_invalidate(be_get_irg_liveness(irg)); } @@ -847,7 +849,7 @@ void assure_constraints(be_irg_t *birg) { * @return 1, if there is something left to perm over. * 0, if removed the complete perm. */ -static int push_through_perm(ir_node *perm, lower_env_t *env) +static int push_through_perm(ir_node *perm) { ir_graph *irg = get_irn_irg(perm); ir_node *bl = get_nodes_block(perm); @@ -881,8 +883,9 @@ static int push_through_perm(ir_node *perm, lower_env_t *env) 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); + be_lv_t *lv = be_get_irg_liveness(irg); if (arch_irn_consider_in_reg_alloc(cls, op) && - !values_interfere(env->birg, op, one_proj)) { + !be_values_interfere(lv, op, one_proj)) { frontier = irn; goto found_front; } @@ -897,7 +900,7 @@ found_front: while (!sched_is_begin(node)) { const arch_register_req_t *req; int input = -1; - ir_node *proj; + ir_node *proj = NULL; /* search if node is a INPUT of Perm */ foreach_out_edge(perm, edge) { @@ -939,11 +942,7 @@ found_front: 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); - - /* and kill it */ - set_Proj_pred(proj, new_Bad()); - kill_node(proj); + exchange(proj, node); bitset_set(moved, input); n_moved++; @@ -952,11 +951,11 @@ found_front: } /* well, we could not push anything through the perm */ - if(n_moved == 0) + if (n_moved == 0) return 1; new_size = arity - n_moved; - if(new_size == 0) { + if (new_size == 0) { sched_remove(perm); kill_node(perm); return 0; @@ -999,31 +998,23 @@ static void lower_nodes_after_ra_walker(ir_node *irn, void *walk_env) if (!be_is_Perm(irn)) return; - perm_stayed = push_through_perm(irn, walk_env); + perm_stayed = push_through_perm(irn); if (perm_stayed) - lower_perm_node(irn, walk_env); + lower_perm_node(irn, (lower_env_t*)walk_env); } -/** - * Walks over all blocks in an irg and performs lowering need to be - * done after register allocation (e.g. perm lowering). - * - * @param birg The birg object - * @param do_copy 1 == resolve cycles with a free reg if available - */ -void lower_nodes_after_ra(be_irg_t *birg, int do_copy) { +void lower_nodes_after_ra(ir_graph *irg, int do_copy) +{ lower_env_t env; - ir_graph *irg; FIRM_DBG_REGISTER(dbg, "firm.be.lower"); FIRM_DBG_REGISTER(dbg_permmove, "firm.be.lower.permmove"); - env.birg = birg; + env.irg = irg; env.do_copy = do_copy; /* we will need interference */ - be_liveness_assure_chk(be_get_birg_liveness(birg)); + be_liveness_assure_chk(be_get_irg_liveness(irg)); - irg = be_get_birg_irg(birg); irg_walk_graph(irg, NULL, lower_nodes_after_ra_walker, &env); }