X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeprefalloc.c;h=af2ece4eca9bb30a1452aa0ab66b51b858554b4d;hb=a00e3544975367a9437d32e4cb5ed502910c24ca;hp=4f0bf00ba29e9e0e4345757f839bf0c61dc3f5cd;hpb=321855ff2c234518e0ac8d794903eb78d23fc1fa;p=libfirm diff --git a/ir/be/beprefalloc.c b/ir/be/beprefalloc.c index 4f0bf00ba..af2ece4ec 100644 --- a/ir/be/beprefalloc.c +++ b/ir/be/beprefalloc.c @@ -271,7 +271,7 @@ static void give_penalties_for_limits(const ir_nodeset_t *live_nodes, static void check_defs(const ir_nodeset_t *live_nodes, float weight, ir_node *node) { - const arch_register_req_t *req = arch_get_register_req_out(node); + const arch_register_req_t *req = arch_get_irn_register_req(node); if (req->type & arch_register_req_type_limited) { const unsigned *limited = req->limited; float penalty = weight * DEF_FACTOR; @@ -352,7 +352,7 @@ static void analyze_block(ir_node *block, void *data) info = get_allocation_info(node); for (i = 0; i < arity; ++i) { ir_node *op = get_irn_n(node, i); - const arch_register_req_t *req = arch_get_register_req_out(op); + const arch_register_req_t *req = arch_get_irn_register_req(op); if (req->cls != cls) continue; @@ -374,7 +374,7 @@ static void analyze_block(ir_node *block, void *data) if (!arch_irn_consider_in_reg_alloc(cls, op)) continue; - req = arch_get_register_req(node, i); + req = arch_get_irn_register_req_in(node, i); if (!(req->type & arch_register_req_type_limited)) continue; @@ -390,7 +390,7 @@ static void analyze_block(ir_node *block, void *data) static void congruence_def(ir_nodeset_t *live_nodes, const ir_node *node) { - const arch_register_req_t *req = arch_get_register_req_out(node); + const arch_register_req_t *req = arch_get_irn_register_req(node); /* should be same constraint? */ if (req->type & arch_register_req_type_should_be_same) { @@ -650,7 +650,7 @@ static bool try_optimistic_split(ir_node *to_split, ir_node *before, * (so we don't split away the values produced because of * must_be_different constraints) */ original_insn = skip_Proj(info->original_value); - if (arch_irn_get_flags(original_insn) & arch_irn_flags_dont_spill) + if (arch_get_irn_flags(original_insn) & arch_irn_flags_dont_spill) return false; from_reg = arch_get_irn_register(to_split); @@ -721,7 +721,7 @@ static bool try_optimistic_split(ir_node *to_split, ir_node *before, return false; reg = arch_register_for_index(cls, r); - copy = be_new_Copy(cls, block, to_split); + copy = be_new_Copy(block, to_split); mark_as_copy_of(copy, to_split); /* hacky, but correct here */ if (assignments[arch_register_get_index(from_reg)] == to_split) @@ -759,7 +759,7 @@ static void assign_reg(const ir_node *block, ir_node *node, return; } - req = arch_get_register_req_out(node); + req = arch_get_irn_register_req(node); /* ignore reqs must be preassigned */ assert (! (req->type & arch_register_req_type_ignore)); @@ -882,7 +882,7 @@ static void assign_reg(const ir_node *block, ir_node *node, * registers. */ static void permute_values(ir_nodeset_t *live_nodes, ir_node *before, - unsigned *permutation) + unsigned *permutation) { unsigned *n_used = ALLOCANZ(unsigned, n_regs); ir_node *block; @@ -922,7 +922,7 @@ static void permute_values(ir_nodeset_t *live_nodes, ir_node *before, /* create a copy */ src = assignments[old_r]; - copy = be_new_Copy(cls, block, src); + copy = be_new_Copy(block, src); sched_add_before(before, copy); reg = arch_register_for_index(cls, r); DB((dbg, LEVEL_2, "Copy %+F (from %+F, before %+F) -> %s\n", @@ -1131,7 +1131,7 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node, if (!arch_irn_consider_in_reg_alloc(cls, op)) continue; - req = arch_get_register_req(node, i); + req = arch_get_irn_register_req_in(node, i); if (!(req->type & arch_register_req_type_limited)) continue; @@ -1146,8 +1146,15 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node, } } - /* add all combinations, then remove not allowed ones */ + /* add all combinations, except for not allowed ones */ for (l = 0; l < n_regs; ++l) { + if (!rbitset_is_set(normal_regs, l)) { + char name[15]; + snprintf(name, sizeof(name), "%u_to_%u", l, l); + lpp_vars[l*n_regs+l] = lpp_add_var(lpp, name, lpp_binary, 1); + continue; + } + for (r = 0; r < n_regs; ++r) { if (!rbitset_is_set(normal_regs, r)) continue; @@ -1158,26 +1165,48 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node, && rbitset_is_set(forbidden_regs, r)) continue; + char name[15]; + snprintf(name, sizeof(name), "%u_to_%u", l, r); + double costs = l==r ? 9 : 8; lpp_vars[l*n_regs+r] - = lpp_add_var(lpp, NULL, lpp_binary, costs); + = lpp_add_var(lpp, name, lpp_binary, costs); assert(lpp_vars[l*n_regs+r] > 0); } } /* add constraints */ for (l = 0; l < n_regs; ++l) { + int constraint; /* only 1 destination per register */ - int constraint = lpp_add_cst(lpp, NULL, lpp_equal, 1); + constraint = -1; for (r = 0; r < n_regs; ++r) { int var = lpp_vars[l*n_regs+r]; if (var == 0) continue; + if (constraint < 0) { + char name[64]; + snprintf(name, sizeof(name), "%u_to_dest", l); + constraint = lpp_add_cst(lpp, name, lpp_equal, 1); + } lpp_set_factor_fast(lpp, constraint, var, 1); } /* each destination used by at most 1 value */ - constraint = lpp_add_cst(lpp, NULL, lpp_less_equal, 1); + constraint = -1; + for (r = 0; r < n_regs; ++r) { + int var = lpp_vars[r*n_regs+l]; + if (var == 0) + continue; + if (constraint < 0) { + char name[64]; + snprintf(name, sizeof(name), "one_to_%u", l); + constraint = lpp_add_cst(lpp, name, lpp_less_equal, 1); + } + lpp_set_factor_fast(lpp, constraint, var, 1); + } } + lpp_dump_plain(lpp, fopen("lppdump.txt", "w")); + /* solve lpp */ { ir_graph *irg = get_irn_irg(node); @@ -1201,8 +1230,15 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node, } } assert(dest_reg != (unsigned)-1); - assignment[l] = dest_reg; + assignment[dest_reg] = l; + } + + fprintf(stderr, "Assignment: "); + for (l = 0; l < n_regs; ++l) { + fprintf(stderr, "%u ", assignment[l]); } + fprintf(stderr, "\n"); + fflush(stdout); permute_values(live_nodes, node, assignment); } lpp_free(lpp); @@ -1241,7 +1277,7 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node, continue; /* are there any limitations for the i'th operand? */ - req = arch_get_register_req(node, i); + req = arch_get_irn_register_req_in(node, i); if (req->width > 1) double_width = true; if (!(req->type & arch_register_req_type_limited)) @@ -1281,6 +1317,7 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node, } if (double_width) { + /* only the ILP variant can solve this yet */ solve_lpp(live_nodes, node, forbidden_regs, live_through_regs); return; } @@ -1322,7 +1359,7 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node, if (!arch_irn_consider_in_reg_alloc(cls, op)) continue; - req = arch_get_register_req(node, i); + req = arch_get_irn_register_req_in(node, i); if (!(req->type & arch_register_req_type_limited)) continue; @@ -1678,7 +1715,7 @@ static void allocate_coalesce_block(ir_node *block, void *data) int p; node = be_lv_get_irn(lv, block, i); - req = arch_get_register_req_out(node); + req = arch_get_irn_register_req(node); if (req->cls != cls) continue; @@ -1995,7 +2032,7 @@ static void spill(void) be_pre_spill_prepare_constr(irg, cls); be_timer_pop(T_RA_CONSTR); - dump(DUMP_RA, irg, "-spillprepare"); + dump(DUMP_RA, irg, "spillprepare"); /* spill */ be_timer_push(T_RA_SPILL); @@ -2006,7 +2043,7 @@ static void spill(void) check_for_memory_operands(irg); be_timer_pop(T_RA_SPILL_APPLY); - dump(DUMP_RA, irg, "-spill"); + dump(DUMP_RA, irg, "spill"); } /**