X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeprefalloc.c;h=338b7a4380f042b33abd5d4c2fcbd5860242f206;hb=5474a1c188c9d59eea2c915515980cd9cbab58d8;hp=6f5b84024254cf12526937873fa8778e2a296c26;hpb=a6291e15c44a2b43ea1bbde18a8dcc60274c7512;p=libfirm diff --git a/ir/be/beprefalloc.c b/ir/be/beprefalloc.c index 6f5b84024..338b7a438 100644 --- a/ir/be/beprefalloc.c +++ b/ir/be/beprefalloc.c @@ -22,7 +22,6 @@ * @brief Preference Guided Register Assignment * @author Matthias Braun * @date 14.2.2009 - * @version $Id$ * * The idea is to allocate registers in 2 passes: * 1. A first pass to determine "preferred" registers for live-ranges. This @@ -54,6 +53,8 @@ #include "irnode_t.h" #include "irprintf.h" #include "irdump.h" +#include "irtools.h" +#include "util.h" #include "obst.h" #include "raw_bitset.h" #include "unionfind.h" @@ -271,7 +272,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 +353,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 +375,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 +391,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 +651,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 +722,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 +760,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)); @@ -922,7 +923,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 +1132,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; @@ -1244,6 +1245,13 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node, lpp_free(lpp); } +static bool is_aligned(unsigned num, unsigned alignment) +{ + unsigned mask = alignment-1; + assert(is_po2(alignment)); + return (num&mask) == 0; +} + /** * Enforce constraints at a node by live range splits. * @@ -1263,7 +1271,8 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node, /* construct a list of register occupied by live-through values */ unsigned *live_through_regs = NULL; - /* see if any use constraints are not met */ + /* see if any use constraints are not met and whether double-width + * values are involved */ bool double_width = false; bool good = true; for (i = 0; i < arity; ++i) { @@ -1277,19 +1286,25 @@ 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; + reg = arch_get_irn_register(op); + reg_index = arch_register_get_index(reg); + if (req->type & arch_register_req_type_aligned) { + if (!is_aligned(reg_index, req->width)) { + good = false; + continue; + } + } if (!(req->type & arch_register_req_type_limited)) continue; limited = req->limited; - reg = arch_get_irn_register(op); - reg_index = arch_register_get_index(reg); if (!rbitset_is_set(limited, reg_index)) { /* found an assignment outside the limited set */ good = false; - break; + continue; } } @@ -1359,7 +1374,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; @@ -1715,7 +1730,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,8 +2010,8 @@ static void be_pref_alloc_cls(void) { size_t i; - lv = be_assure_liveness(irg); - be_liveness_assure_sets(lv); + be_assure_live_sets(irg); + lv = be_get_irg_liveness(irg); ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); @@ -2094,8 +2109,7 @@ static void be_pref_alloc(ir_graph *new_irg) /* we most probably constructed new Phis so liveness info is invalid * now */ - /* TODO: test liveness_introduce */ - be_liveness_invalidate(lv); + be_invalidate_live_sets(irg); free(normal_regs); stat_ev_ctx_pop("regcls");