Commit eba9656a authored by Matthias Braun's avatar Matthias Braun
Browse files

fix output constraints not always being respected

[r26364]
parent 59528405
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include "irgwalk.h" #include "irgwalk.h"
#include "irnode_t.h" #include "irnode_t.h"
#include "obst.h" #include "obst.h"
#include "raw_bitset.h"
#include "beabi.h" #include "beabi.h"
#include "bechordal_t.h" #include "bechordal_t.h"
...@@ -77,7 +78,6 @@ ...@@ -77,7 +78,6 @@
#include "bespillutil.h" #include "bespillutil.h"
#include "beverify.h" #include "beverify.h"
#include "bipartite.h"
#include "hungarian.h" #include "hungarian.h"
#define USE_FACTOR 1.0f #define USE_FACTOR 1.0f
...@@ -96,7 +96,7 @@ static const arch_register_req_t *default_cls_req; ...@@ -96,7 +96,7 @@ static const arch_register_req_t *default_cls_req;
static be_lv_t *lv; static be_lv_t *lv;
static const ir_exec_freq *execfreqs; static const ir_exec_freq *execfreqs;
static unsigned n_regs; static unsigned n_regs;
static bitset_t *ignore_regs; static unsigned *normal_regs;
/** info about the current assignment for a register */ /** info about the current assignment for a register */
struct assignment_t { struct assignment_t {
...@@ -322,8 +322,6 @@ static void check_defs(const ir_nodeset_t *live_nodes, float weight, ...@@ -322,8 +322,6 @@ static void check_defs(const ir_nodeset_t *live_nodes, float weight,
op = get_irn_n(insn, i); op = get_irn_n(insn, i);
op_info = get_allocation_info(op); op_info = get_allocation_info(op);
for (r = 0; r < n_regs; ++r) { for (r = 0; r < n_regs; ++r) {
if (bitset_is_set(ignore_regs, r))
continue;
op_info->prefs[r] += info->prefs[r] * factor; op_info->prefs[r] += info->prefs[r] * factor;
} }
} }
...@@ -438,9 +436,6 @@ static void fill_sort_candidates(reg_pref_t *regprefs, ...@@ -438,9 +436,6 @@ static void fill_sort_candidates(reg_pref_t *regprefs,
for (r = 0; r < n_regs; ++r) { for (r = 0; r < n_regs; ++r) {
float pref = info->prefs[r]; float pref = info->prefs[r];
if (bitset_is_set(ignore_regs, r)) {
pref = -10000;
}
regprefs[r].num = r; regprefs[r].num = r;
regprefs[r].pref = pref; regprefs[r].pref = pref;
} }
...@@ -458,7 +453,8 @@ static void assign_reg(const ir_node *block, ir_node *node) ...@@ -458,7 +453,8 @@ static void assign_reg(const ir_node *block, ir_node *node)
const arch_register_req_t *req; const arch_register_req_t *req;
reg_pref_t *reg_prefs; reg_pref_t *reg_prefs;
ir_node *in_node; ir_node *in_node;
unsigned i; unsigned i;
const unsigned *allowed_regs;
assert(arch_irn_consider_in_reg_alloc(cls, node)); assert(arch_irn_consider_in_reg_alloc(cls, node));
...@@ -492,8 +488,6 @@ static void assign_reg(const ir_node *block, ir_node *node) ...@@ -492,8 +488,6 @@ static void assign_reg(const ir_node *block, ir_node *node)
reg = arch_get_irn_register(in); reg = arch_get_irn_register(in);
assert(reg != NULL); assert(reg != NULL);
r = arch_register_get_index(reg); r = arch_register_get_index(reg);
if (bitset_is_set(ignore_regs, r))
continue;
info->prefs[r] += weight * AFF_SHOULD_BE_SAME; info->prefs[r] += weight * AFF_SHOULD_BE_SAME;
} }
} }
...@@ -508,15 +502,20 @@ static void assign_reg(const ir_node *block, ir_node *node) ...@@ -508,15 +502,20 @@ static void assign_reg(const ir_node *block, ir_node *node)
} }
DB((dbg, LEVEL_2, "\n")); DB((dbg, LEVEL_2, "\n"));
allowed_regs = normal_regs;
if (req->type & arch_register_req_type_limited) {
allowed_regs = req->limited;
}
for (i = 0; i < n_regs; ++i) { for (i = 0; i < n_regs; ++i) {
unsigned r = reg_prefs[i].num; unsigned r = reg_prefs[i].num;
/* ignores are last and we should have at least 1 non-ignore left */
assert(!bitset_is_set(ignore_regs, r));
/* already used? /* already used?
TODO: It might be better to copy the value occupying the register TODO: It might be better to copy the value occupying the register
around here instead of trying the next one, find out when... */ around here instead of trying the next one, find out when... */
if (assignments[r].value != NULL) if (assignments[r].value != NULL)
continue; continue;
if (!rbitset_is_set(allowed_regs, r))
continue;
reg = arch_register_for_index(cls, r); reg = arch_register_for_index(cls, r);
DB((dbg, LEVEL_2, "Assign %+F -> %s\n", node, reg->name)); DB((dbg, LEVEL_2, "Assign %+F -> %s\n", node, reg->name));
use_reg(node, reg); use_reg(node, reg);
...@@ -886,13 +885,13 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node) ...@@ -886,13 +885,13 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node)
/* add all combinations, then remove not allowed ones */ /* add all combinations, then remove not allowed ones */
for (l = 0; l < n_regs; ++l) { for (l = 0; l < n_regs; ++l) {
if (bitset_is_set(ignore_regs, l)) { if (!rbitset_is_set(normal_regs, l)) {
hungarian_add(bp, l, l, 1); hungarian_add(bp, l, l, 1);
continue; continue;
} }
for (r = 0; r < n_regs; ++r) { for (r = 0; r < n_regs; ++r) {
if (bitset_is_set(ignore_regs, r)) if (!rbitset_is_set(normal_regs, r))
continue; continue;
/* livethrough values may not use constrainted output registers */ /* livethrough values may not use constrainted output registers */
if (rbitset_is_set(live_through_regs, l) if (rbitset_is_set(live_through_regs, l)
...@@ -1375,8 +1374,8 @@ static void be_straight_alloc(be_irg_t *new_birg) ...@@ -1375,8 +1374,8 @@ static void be_straight_alloc(be_irg_t *new_birg)
stat_ev_ctx_push_str("regcls", cls->name); stat_ev_ctx_push_str("regcls", cls->name);
n_regs = arch_register_class_n_regs(cls); n_regs = arch_register_class_n_regs(cls);
ignore_regs = bitset_malloc(n_regs); normal_regs = rbitset_malloc(n_regs);
be_put_ignore_regs(birg, cls, ignore_regs); be_abi_set_non_ignore_regs(birg->abi, cls, normal_regs);
spill(); spill();
...@@ -1401,11 +1400,11 @@ static void be_straight_alloc(be_irg_t *new_birg) ...@@ -1401,11 +1400,11 @@ static void be_straight_alloc(be_irg_t *new_birg)
/* TODO: test liveness_introduce */ /* TODO: test liveness_introduce */
be_liveness_invalidate(lv); be_liveness_invalidate(lv);
bitset_free(ignore_regs);
stat_ev_ctx_pop("regcls"); stat_ev_ctx_pop("regcls");
} }
free(normal_regs);
BE_TIMER_PUSH(t_ra_spill_apply); BE_TIMER_PUSH(t_ra_spill_apply);
be_abi_fix_stack_nodes(birg->abi); be_abi_fix_stack_nodes(birg->abi);
BE_TIMER_POP(t_ra_spill_apply); BE_TIMER_POP(t_ra_spill_apply);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment