From: Daniel Grund Date: Fri, 29 Jul 2005 16:59:36 +0000 (+0000) Subject: Copied register assignments from in's to out's for all phi-perms. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=ddb63eee0f083f2b7f171232622ac6eb3180fc2f;p=libfirm Copied register assignments from in's to out's for all phi-perms. This should have fixed a bug. arch_set_irn_regiseter not working? --- diff --git a/ir/be/becopyilp.c b/ir/be/becopyilp.c index 4ff9f2535..8853c8bf1 100644 --- a/ir/be/becopyilp.c +++ b/ir/be/becopyilp.c @@ -445,7 +445,7 @@ static void M_constr_walker(ir_node *block, void *env) { /* compute the minimal costs (rhs) */ int phi_nr, sum=0, max=-1, minimal_costs; bitset_foreach(candidates, phi_nr) { - costs[phi_nr] = get_costs(pi, phis[phi_nr], irn); + costs[phi_nr] = get_costs(pi, phis[phi_nr], irn); //TODO this failes for nodes not in the ou. the interfering ones. sum += costs[phi_nr]; max = MAX(max, costs[phi_nr]); } diff --git a/ir/be/becopyoptmain.c b/ir/be/becopyoptmain.c index 0e3136775..e1be7a88d 100644 --- a/ir/be/becopyoptmain.c +++ b/ir/be/becopyoptmain.c @@ -19,7 +19,7 @@ #include "becopyoptmain.h" #define DO_HEUR -#define DO_ILP +#undef DO_ILP #define DEBUG_LVL SET_LEVEL_1 static firm_dbg_module_t *dbg = NULL; @@ -37,13 +37,13 @@ void be_copy_opt(be_chordal_env_t *chordal_env) { compute_outs(chordal_env->session_env->irg); co = new_copy_opt(chordal_env, get_costs_loop_depth); - DBG((dbg, LEVEL_1, "===> %s <===\n", co->name)); + DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name)); #ifdef DO_STAT lb = co_get_lower_bound(co); copy_costs = co_get_copy_costs(co); curr_vals[I_COPIES_INIT] += copy_costs; - DBG((dbg, LEVEL_1, "Init costs: %3d / %3d\n", lb, copy_costs)); + DBG((dbg, LEVEL_1, "Init costs: %3d <= %3d\n", lb, copy_costs)); #endif #ifdef DO_HEUR @@ -51,7 +51,7 @@ void be_copy_opt(be_chordal_env_t *chordal_env) { #ifdef DO_STAT copy_costs = co_get_copy_costs(co); curr_vals[I_COPIES_HEUR] += copy_costs; - DBG((dbg, LEVEL_1, "Heur costs: %3d / %3d\n", lb, copy_costs)); + DBG((dbg, LEVEL_1, "Heur costs: %3d <= %3d\n", lb, copy_costs)); #endif #endif @@ -67,7 +67,7 @@ void be_copy_opt(be_chordal_env_t *chordal_env) { copy_costs = co_get_copy_costs(co); assert(copy_costs>=lb && "At least one computation of these two is boooogy"); curr_vals[I_COPIES_OPT] += copy_costs; - DBG((dbg, LEVEL_1, "Opt costs: %3d / %3d\n", copy_costs)); + DBG((dbg, LEVEL_1, "Opt costs: %3d <= %3d\n", lb, copy_costs)); #endif #endif diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 7e8163cc4..ef14f15fa 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -36,7 +36,7 @@ #include "bearch_firm.h" #include "benode_t.h" #include "beirgmod.h" -#include "bespillilp.h" +//#include "bespillilp.h" #include "beasm_dump_globals.h" #include "beasm_asm_gnu.h" @@ -62,6 +62,7 @@ static be_main_env_t *be_init_env(be_main_env_t *env) obstack_init(&env->obst); env->dbg = firm_dbg_register("be.main"); + firm_dbg_set_mask(env->dbg, SET_LEVEL_1); env->arch_env = obstack_alloc(&env->obst, sizeof(env->arch_env[0])); arch_env_init(env->arch_env, isa); @@ -132,7 +133,7 @@ static void be_main_loop(void) ir_graph *irg = get_irp_irg(i); be_main_session_env_t session; - DBG((env.dbg, LEVEL_1, "be irg: %F\n", irg)); + DBG((env.dbg, LEVEL_1, "====> IRG: %F\n", irg)); /* Init the session. */ be_init_session_env(&session, &env, irg); @@ -147,28 +148,28 @@ static void be_main_loop(void) /* Verify the schedule */ sched_verify_irg(irg); - /* Build liveness information */ - be_liveness(irg); + /* Build liveness information */ + be_liveness(irg); copystat_reset(); copystat_collect_irg(irg, env.arch_env); - /* - * Verifying the schedule once again cannot hurt. - */ - sched_verify_irg(irg); + /* + * Verifying the schedule once again cannot hurt. + */ + sched_verify_irg(irg); /* Perform the following for each register class. */ for(j = 0, m = isa->get_n_reg_class(); j < m; ++j) { be_chordal_env_t *chordal_env; const arch_register_class_t *cls = isa->get_reg_class(j); - DBG((env.dbg, LEVEL_1, "\treg class: %s\n", cls->name)); + DBG((env.dbg, LEVEL_1, "----> Reg class: %s\n", cls->name)); - be_numbering(irg); - be_liveness(irg); + be_numbering(irg); + be_liveness(irg); - // be_spill_ilp(&session, cls); + //be_spill_ilp(&session, cls); chordal_env = be_ra_chordal(&session, cls); @@ -181,10 +182,10 @@ static void be_main_loop(void) be_ssa_destruction(chordal_env); be_ssa_destruction_check(chordal_env); - be_ra_chordal_check(chordal_env); - be_ra_chordal_done(chordal_env); - be_numbering_done(irg); + + be_ra_chordal_done(chordal_env); + be_numbering_done(irg); } dump_ir_block_graph(session.irg, "-post"); diff --git a/ir/be/bessadestr.c b/ir/be/bessadestr.c index 4e42ac124..17d5425dc 100644 --- a/ir/be/bessadestr.c +++ b/ir/be/bessadestr.c @@ -28,14 +28,13 @@ #include "besched_t.h" static firm_dbg_module_t *dbg = NULL; -#define DEBUG_LVL SET_LEVEL_2 +#define DEBUG_LVL SET_LEVEL_3 #define get_chordal_arch(ce) ((ce)->session_env->main_env->arch_env) #define get_reg(irn) arch_get_irn_register(get_chordal_arch(chordal_env), irn, 0) #define set_reg(irn, reg) arch_set_irn_register(get_chordal_arch(chordal_env), irn, 0, reg) -#define is_Branch(irn) (arch_irn_classify(arch_env, irn) == arch_irn_class_branch) #define is_Perm(irn) (arch_irn_classify(arch_env, irn) == arch_irn_class_perm) #define get_reg_cls(irn) (arch_get_irn_reg_class(arch_env, irn, arch_pos_make_out(0))) #define is_curr_reg_class(irn) (get_reg_cls(p) == chordal_env->cls) @@ -71,11 +70,84 @@ static INLINE void build_phi_rings(be_chordal_env_t *env) } static int skip_cf_predicator(const ir_node *irn, void *data) { - be_chordal_env_t *ce = data; - arch_env_t *ae = ce->session_env->main_env->arch_env; + be_chordal_env_t *chordal_env = data; + arch_env_t *ae = chordal_env->session_env->main_env->arch_env; return arch_irn_classify(ae, irn) == arch_irn_class_branch; } +static void insert_all_perms_walker(ir_node *bl, void *data) +{ + be_chordal_env_t *chordal_env = data; + pmap *perm_map = chordal_env->data; + ir_graph *irg = chordal_env->session_env->irg; + const be_node_factory_t *fact = chordal_env->session_env->main_env->node_factory; + + /* Dummy targets for the projs */ + ir_node *dummy = new_rd_Unknown(irg, mode_T); + + assert(is_Block(bl)); + + /* If the link flag is NULL, this block has no phis. */ + if(get_irn_link(bl)) { + int i, n; + + /* Look at all predecessors of the phi block */ + for(i = 0, n = get_irn_arity(bl); i < n; ++i) { + ir_node *pred_bl = get_Block_cfgpred_block(bl, i); + ir_node *phi, *perm, *insert_after; + ir_node **in; + int j, n_projs = 0; + pmap_entry *ent; + pmap *arg_map = pmap_create(); + + assert(!pmap_contains(perm_map, pred_bl) && "Already permed that block"); + + /* + * Note that all phis in the list are in the same register class + * by construction. + */ + for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) { + ir_node *arg = get_irn_n(phi, i); + ir_node *proj = pmap_get(arg_map, arg); + + if(!proj) { + proj = new_r_Proj(irg, pred_bl, dummy, get_irn_mode(arg), n_projs++); + pmap_insert(arg_map, arg, proj); + } + + set_irn_n(phi, i, proj); + } + + j = 0; + in = malloc(n_projs * sizeof(in[0])); + pmap_foreach(arg_map, ent) { + in[j++] = ent->key; + /* register allocation is copied form former arguments + * to the projs (new arguments) + */ + DBG((dbg, LEVEL_2, "Copy register assignment %s from %+F to %+F\n", get_reg(ent->key)->name, ent->key, ent->value)); + set_reg(ent->value, get_reg(ent->key)); + } + + perm = new_Perm(fact, chordal_env->cls, irg, pred_bl, n_projs, in); + insert_after = sched_skip(sched_last(pred_bl), 0, skip_cf_predicator, chordal_env); + sched_add_after(insert_after, perm); + exchange(dummy, perm); + + free(in); + pmap_destroy(arg_map); + + /* register in perm map */ + pmap_insert(perm_map, pred_bl, perm); + } + } +} + +static void insert_all_perms(be_chordal_env_t *chordal_env) { + DBG((dbg, LEVEL_1, "Placing perms...\n")); + irg_block_walk_graph(chordal_env->session_env->irg, insert_all_perms_walker, NULL, chordal_env); +} + #define is_pinned(irn) (get_irn_link(irn)) #define get_pinning_block(irn) ((ir_node *)get_irn_link(irn)) #define pin_irn(irn, lock) (set_irn_link(irn, lock)) @@ -88,8 +160,7 @@ static int skip_cf_predicator(const ir_node *irn, void *data) { static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { int i, max; ir_node *arg, *phi_block, *arg_block; - arch_env_t *arch_env = get_chordal_arch(chordal_env); - const be_main_session_env_t *session = chordal_env->session_env; + const be_main_session_env_t *session = chordal_env->session_env; const arch_register_t *phi_reg, *arg_reg; const arch_register_class_t *cls; @@ -105,27 +176,30 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { ir_node *perm; arg = get_irn_n(phi, i); + assert(is_Proj(arg)); arg_block = get_nodes_block(arg); arg_reg = get_reg(arg); + assert(arg_reg && "Register must be set while placing perms"); + DBG((dbg, LEVEL_3, "%+F has register %s assigned\n", arg, arg_reg->name)); perm = get_Proj_pred(arg); - // assert(is_Perm(perm)); + //TODO reenable this if classify is implemented. assert(is_Perm(perm)); DBG((dbg, LEVEL_1, " arg %+F has perm %+F\n", arg, perm)); /* if registers don't match ...*/ if (phi_reg != arg_reg) { - DBG((dbg, LEVEL_1, " regs don't match %d %d\n", phi_reg, arg_reg)); + DBG((dbg, LEVEL_1, " regs don't match %d %d\n", phi_reg->name, arg_reg->name)); /* First check if there is another phi in the same block * having arg at the same pos in its arg-list and the same color as arg */ if (!is_pinned(arg)) { - DBG((dbg, LEVEL_1, " arg is not pinned\n")); + DBG((dbg, LEVEL_1, " arg is not pinned\n")); ir_node *other_phi = phi; - for(other_phi = get_irn_link(phi_block); other_phi; other_phi = get_irn_link(other_phi)) { - if(other_phi == phi) - continue; + for(other_phi = get_irn_link(phi_block); other_phi; other_phi = get_irn_link(other_phi)) { + if(other_phi == phi) + continue; assert(is_Phi(other_phi) && get_nodes_block(phi) == get_nodes_block(other_phi) && "link fields are screwed up"); if (get_irn_n(other_phi, i) == arg && get_reg(other_phi) == arg_reg) { - DBG((dbg, LEVEL_1, " other phi pinned the argument\n")); + DBG((dbg, LEVEL_1, " but other phi (%+F) just pinned it\n", other_phi)); pin_irn(arg, phi_block); } } @@ -143,7 +217,7 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { dupl = new_Copy(session->main_env->node_factory, cls, session->irg, arg_block, arg); set_irn_n(phi, i, dupl); set_reg(dupl, phi_reg); - DBG((dbg, LEVEL_1, " inserting dupl %+F\n", dupl)); + DBG((dbg, LEVEL_1, " arg is pinned so insert dupl %+F\n", dupl)); /* Add dupl to schedule */ tmp = sched_next(perm); @@ -151,13 +225,6 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { tmp = sched_next(tmp); sched_add_after(tmp, dupl); - /* Add dupl to chained list of duplicates. Ptrs starting at the Perm */ - tmp = perm; - while (get_irn_link(tmp)) - tmp = get_irn_link(tmp); - set_irn_link(tmp, dupl); - set_irn_link(dupl, NULL); - /* now the arg is the dupl */ arg = dupl; } else { @@ -167,9 +234,11 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { * livein(PhiBl) = liveout(ArgBl), if all phis are processed then * every color is used exactly once. */ - DBG((dbg, LEVEL_1, " just set color\n")); + DBG((dbg, LEVEL_1, " arg is not pinned so just set register to %s\n", phi_reg->name)); set_reg(arg, phi_reg); } + } else { + DBG((dbg, LEVEL_1, " regs match %d\n")); } /* Now the color of the arg (arg may be a dupl now) and the phi-result are equal. @@ -180,92 +249,25 @@ static void adjust_phi_arguments(be_chordal_env_t *chordal_env, ir_node *phi) { } } -static void insert_all_perms_walker(ir_node *bl, void *data) -{ - be_chordal_env_t *ce = data; - pmap *perm_map = ce->data; - ir_graph *irg = ce->session_env->irg; - const be_node_factory_t *fact = ce->session_env->main_env->node_factory; - - /* Dummy targets for the projs */ - ir_node *dummy = new_rd_Unknown(irg, mode_T); - - assert(is_Block(bl)); - - /* If the link flag is NULL, this block has no phis. */ - if(get_irn_link(bl)) { - int i, n; - - /* Look at all predecessors of the phi block */ - for(i = 0, n = get_irn_arity(bl); i < n; ++i) { - ir_node *pred_bl = get_Block_cfgpred_block(bl, i); - ir_node *phi, *perm, *insert_after; - ir_node **in; - int j, n_projs = 0; - pmap_entry *ent; - pmap *arg_map = pmap_create(); - - assert(!pmap_contains(perm_map, pred_bl) && "Already permed that block"); - - /* - * Note that all phis in the ring are in the same register class - * by construction. - */ - for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) { - ir_node *arg = get_irn_n(phi, i); - ir_node *proj = pmap_get(arg_map, arg); - - if(!proj) { - proj = new_r_Proj(irg, pred_bl, dummy, get_irn_mode(arg), n_projs++); - pmap_insert(arg_map, arg, proj); - } - - set_irn_n(phi, i, proj); - } - - j = 0; - in = malloc(n_projs * sizeof(in[0])); - pmap_foreach(arg_map, ent) - in[j++] = ent->key; - - perm = new_Perm(fact, ce->cls, irg, pred_bl, n_projs, in); - insert_after = sched_skip(sched_last(pred_bl), 0, skip_cf_predicator, ce); - sched_add_after(insert_after, perm); - exchange(dummy, perm); - - free(in); - pmap_destroy(arg_map); - - /* register in perm map */ - pmap_insert(perm_map, pred_bl, perm); - } - } -} - -static void insert_all_perms(be_chordal_env_t *chordal_env) { - DBG((dbg, LEVEL_1, "Placing perms...\n")); - irg_block_walk_graph(chordal_env->session_env->irg, insert_all_perms_walker, NULL, chordal_env); -} - static void set_regs_or_place_dupls_walker(ir_node *bl, void *data) { - be_chordal_env_t *chordal_env = data; - ir_node *phi; + be_chordal_env_t *chordal_env = data; + ir_node *phi; - DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n")); - for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) - adjust_phi_arguments(chordal_env, phi); + for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) + adjust_phi_arguments(chordal_env, phi); } static void set_regs_or_place_dupls(be_chordal_env_t *chordal_env) { - irg_block_walk_graph(chordal_env->session_env->irg, - set_regs_or_place_dupls_walker, NULL, chordal_env); + DBG((dbg, LEVEL_1, "Setting regs and placing dupls...\n")); + irg_block_walk_graph(chordal_env->session_env->irg, + set_regs_or_place_dupls_walker, NULL, chordal_env); } void be_ssa_destruction(be_chordal_env_t *chordal_env) { pmap *perm_map = pmap_create(); - ir_graph *irg = chordal_env->session_env->irg; + ir_graph *irg = chordal_env->session_env->irg; dbg = firm_dbg_register("ir.be.ssadestr"); firm_dbg_set_mask(dbg, DEBUG_LVL); @@ -273,7 +275,7 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) { /* create a map for fast lookup of perms: block --> perm */ chordal_env->data = perm_map; - build_phi_rings(chordal_env); + build_phi_rings(chordal_env); insert_all_perms(chordal_env); dump_ir_block_graph(irg, "-ssa_destr_perms_placed"); @@ -285,30 +287,30 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) { static void ssa_destruction_check_walker(ir_node *bl, void *data) { - be_chordal_env_t *chordal_env = data; - ir_node *phi; + be_chordal_env_t *chordal_env = data; + ir_node *phi; int i, max; - for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) { - const arch_register_t *phi_reg, *arg_reg; - - phi_reg = get_reg(phi); - /* iterate over all args of phi */ - for(i=0, max=get_irn_arity(phi); iname, arg_reg->name); - assert(0 && "Registers of phi and arg differ\n"); - } - if(!is_pinned(arg)) - ir_printf("Warning: Arg %+F not pinned\n", arg); - } - } + for(phi = get_irn_link(bl); phi; phi = get_irn_link(phi)) { + const arch_register_t *phi_reg, *arg_reg; + + phi_reg = get_reg(phi); + /* iterate over all args of phi */ + for(i=0, max=get_irn_arity(phi); iname, arg_reg->name)); + assert(0); + } + if(!is_pinned(arg)) { + DBG((dbg, 0, "Warning: Phi argument %+F is not pinned.\n", arg)); + assert(0); + } + } + } } void be_ssa_destruction_check(be_chordal_env_t *chordal_env) { - irg_block_walk_graph(chordal_env->session_env->irg, - ssa_destruction_check_walker, NULL, chordal_env); + irg_block_walk_graph(chordal_env->session_env->irg, ssa_destruction_check_walker, NULL, chordal_env); }