From 29c77ce9ad50b48b2e88659b67e5918a9ed78560 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sun, 16 Aug 2009 22:23:59 +0000 Subject: [PATCH] benewalloc: fix enforce_constraints sometimes looking at the original value instead of the current copy of a value [r26365] --- ir/be/benewalloc.c | 85 +++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/ir/be/benewalloc.c b/ir/be/benewalloc.c index b6fbd1d7a..305c4c2a6 100644 --- a/ir/be/benewalloc.c +++ b/ir/be/benewalloc.c @@ -580,7 +580,7 @@ static void permutate_values(ir_nodeset_t *live_nodes, ir_node *before, ir_node *block; unsigned r; - /* create a list of permutations. Leave out fix points. */ + /* determine how often each source register needs to be read */ for (r = 0; r < n_regs; ++r) { unsigned old_reg = permutation[r]; ir_node *value; @@ -594,15 +594,6 @@ static void permutate_values(ir_nodeset_t *live_nodes, ir_node *before, } ++n_used[old_reg]; - - /* no need to do anything for a fixpoint */ - if (old_reg == r) - continue; - - /* free occupation infos, we'll add the values back later */ - if (live_nodes != NULL) { - ir_nodeset_remove(live_nodes, value); - } } block = get_nodes_block(before); @@ -642,6 +633,9 @@ static void permutate_values(ir_nodeset_t *live_nodes, ir_node *before, assert(n_used[old_r] > 0); --n_used[old_r]; if (n_used[old_r] == 0) { + if (live_nodes != NULL) { + ir_nodeset_remove(live_nodes, src); + } free_reg_of_value(src); } @@ -692,9 +686,6 @@ static void permutate_values(ir_nodeset_t *live_nodes, ir_node *before, mark_as_copy_of(proj0, in[0]); reg = arch_register_for_index(cls, old_r); use_reg(proj0, reg); - if (live_nodes != NULL) { - ir_nodeset_insert(live_nodes, proj0); - } proj1 = new_r_Proj(block, perm, get_irn_mode(in[1]), 1); mark_as_copy_of(proj1, in[1]); @@ -707,7 +698,10 @@ static void permutate_values(ir_nodeset_t *live_nodes, ir_node *before, permutation[r] = r2; /* if we have reached a fixpoint update data structures */ - if (live_nodes != NULL && r == r2) { + if (live_nodes != NULL) { + ir_nodeset_remove(live_nodes, in[0]); + ir_nodeset_remove(live_nodes, in[1]); + ir_nodeset_remove(live_nodes, proj0); ir_nodeset_insert(live_nodes, proj1); } } @@ -745,6 +739,28 @@ static void free_last_uses(ir_nodeset_t *live_nodes, ir_node *node) } } +/** + * change inputs of a node to the current value (copies/perms) + */ +static void rewire_inputs(ir_node *node) +{ + int i; + int arity = get_irn_arity(node); + + for (i = 0; i < arity; ++i) { + ir_node *op = get_irn_n(node, i); + allocation_info_t *info; + + if (!arch_irn_consider_in_reg_alloc(cls, op)) + continue; + + info = get_allocation_info(op); + if (info->current_value != op) { + set_irn_n(node, i, info->current_value); + } + } +} + /** * Create a bitset of registers occupied with value living through an * instruction @@ -761,6 +777,8 @@ static void determine_live_through_regs(unsigned *bitset, ir_node *node) const assignment_t *assignment = &assignments[r]; if (assignment->value == NULL) continue; + if (!rbitset_is_set(normal_regs, r)) + continue; rbitset_set(bitset, r); } @@ -775,6 +793,7 @@ static void determine_live_through_regs(unsigned *bitset, ir_node *node) continue; op = get_irn_n(node, i); + op = get_allocation_info(op)->current_value; reg = arch_get_irn_register(op); rbitset_clear(bitset, arch_register_get_index(reg)); } @@ -880,7 +899,11 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node) } /* at this point we have to construct a bipartite matching problem to see - which values should go to which registers */ + * which values should go to which registers + * Note: We're building the matrix in "reverse" - source registers are + * right, destinations at l because this will produce the solution + * in the format required for permutate_values. + */ bp = hungarian_new(n_regs, n_regs, HUNGARIAN_MATCH_PERFECT); /* add all combinations, then remove not allowed ones */ @@ -917,6 +940,7 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node) continue; limited = req->limited; + op = get_allocation_info(op)->current_value; reg = arch_get_irn_register(op); current_reg = arch_register_get_index(reg); for (r = 0; r < n_regs; ++r) { @@ -934,11 +958,11 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node) assert(res == 0); #if 0 - printf("Swap result:"); + fprintf(stderr, "Swap result:"); for (i = 0; i < (int) n_regs; ++i) { - printf(" %d", assignment[i]); + fprintf(stderr, " %d", assignment[i]); } - printf("\n"); + fprintf(stderr, "\n"); #endif hungarian_free(bp); @@ -1082,28 +1106,6 @@ static void handle_phi_prefs(ir_node *phi) } } -/** - * change inputs of a node to the current value (copies/perms) - */ -static void rewire_inputs(ir_node *node) -{ - int i; - int arity = get_irn_arity(node); - - for (i = 0; i < arity; ++i) { - ir_node *op = get_irn_n(node, i); - allocation_info_t *info; - - if (!arch_irn_consider_in_reg_alloc(cls, op)) - continue; - - info = get_allocation_info(op); - if (info->current_value != op) { - set_irn_n(node, i, info->current_value); - } - } -} - /** * Walker: assign registers to all nodes of a block that * need registers from the currently considered register class. @@ -1399,12 +1401,11 @@ static void be_straight_alloc(be_irg_t *new_birg) * now */ /* TODO: test liveness_introduce */ be_liveness_invalidate(lv); + free(normal_regs); stat_ev_ctx_pop("regcls"); } - free(normal_regs); - BE_TIMER_PUSH(t_ra_spill_apply); be_abi_fix_stack_nodes(birg->abi); BE_TIMER_POP(t_ra_spill_apply); -- 2.20.1