Commit 7e447b3e authored by Christoph Mallon's avatar Christoph Mallon
Browse files

bearch: Make the register requirements an output parameter of be_foreach_definition().

parent e882b686
......@@ -574,31 +574,31 @@ static inline bool arch_irn_consider_in_reg_alloc(
* are not marked as ignore.
* Executes @p code for each definition.
*/
#define be_foreach_definition_(node, ccls, value, code) \
#define be_foreach_definition_(node, ccls, value, req, code) \
do { \
if (get_irn_mode(node) == mode_T) { \
foreach_out_edge(node, edge_) { \
ir_node *const value = get_edge_src_irn(edge_); \
if (!is_Proj(value)) \
continue; \
long pn = get_Proj_proj(value); \
arch_register_req_t const *const req_ = arch_get_irn_register_req_out(node, pn); \
if (req_->cls != ccls) \
long pn = get_Proj_proj(value); \
arch_register_req_t const *const req = arch_get_irn_register_req_out(node, pn); \
if (req->cls != ccls) \
continue; \
code \
} \
} else { \
arch_register_req_t const *const req_ = arch_get_irn_register_req(node); \
ir_node *const value = node; \
if (req_->cls == ccls) { \
arch_register_req_t const *const req = arch_get_irn_register_req(node); \
if (req->cls == ccls) { \
code \
} \
} \
} while (0)
#define be_foreach_definition(node, ccls, value, code) \
be_foreach_definition_(node, ccls, value, \
if (arch_register_req_is(req_, ignore)) \
#define be_foreach_definition(node, ccls, value, req, code) \
be_foreach_definition_(node, ccls, value, req, \
if (arch_register_req_is(req, ignore)) \
continue; \
code \
)
......
......@@ -143,7 +143,7 @@ void create_borders(ir_node *block, void *env_ptr)
DB((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
DB((dbg, LEVEL_2, "\tlive: %B\n", live));
be_foreach_definition(irn, env->cls, def,
be_foreach_definition(irn, env->cls, def, req,
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
......
......@@ -46,9 +46,8 @@ be_insn_t *be_scan_insn(be_chordal_env_t *const env, ir_node *const irn)
const arch_register_class_t *cls = env->cls;
insn->irn = irn;
be_foreach_definition(irn, cls, p,
be_foreach_definition(irn, cls, p, req,
/* found a def: create a new operand */
arch_register_req_t const *const req = arch_get_irn_register_req(p);
if (arch_register_req_is(req, limited)) {
o.regs = req->limited;
has_constraints = true;
......
......@@ -482,7 +482,7 @@ void be_liveness_transfer(const arch_register_class_t *cls,
* function. */
assert(!is_Phi(node) && "liveness_transfer produces invalid results for phi nodes");
be_foreach_definition(node, cls, value,
be_foreach_definition(node, cls, value, req,
ir_nodeset_remove(nodeset, value);
);
......
......@@ -253,10 +253,8 @@ static void give_penalties_for_limits(const ir_nodeset_t *live_nodes,
* @param weight the weight
* @param node the current node
*/
static void check_defs(const ir_nodeset_t *live_nodes, float weight,
ir_node *node)
static void check_defs(ir_nodeset_t const *const live_nodes, float const weight, ir_node *const node, arch_register_req_t const *const req)
{
const arch_register_req_t *req = arch_get_irn_register_req(node);
if (arch_register_req_is(req, limited)) {
const unsigned *limited = req->limited;
float penalty = weight * DEF_FACTOR;
......@@ -306,8 +304,8 @@ static void analyze_block(ir_node *block, void *data)
if (is_Phi(node))
break;
be_foreach_definition(node, cls, value,
check_defs(&live_nodes, weight, value);
be_foreach_definition(node, cls, value, req,
check_defs(&live_nodes, weight, value, req);
);
/* mark last uses */
......@@ -356,10 +354,8 @@ static void analyze_block(ir_node *block, void *data)
ir_nodeset_destroy(&live_nodes);
}
static void congruence_def(ir_nodeset_t *live_nodes, const ir_node *node)
static void congruence_def(ir_nodeset_t *const live_nodes, ir_node const *const node, arch_register_req_t const *const req)
{
const arch_register_req_t *req = arch_get_irn_register_req(node);
/* should be same constraint? */
if (arch_register_req_is(req, should_be_same)) {
const ir_node *insn = skip_Proj_const(node);
......@@ -414,8 +410,8 @@ static void create_congruence_class(ir_node *block, void *data)
break;
}
be_foreach_definition(node, cls, value,
congruence_def(&live_nodes, value);
be_foreach_definition(node, cls, value, req,
congruence_def(&live_nodes, value, req);
);
be_liveness_transfer(cls, node, &live_nodes);
}
......@@ -682,14 +678,12 @@ static bool try_optimistic_split(ir_node *to_split, ir_node *before,
/**
* Determine and assign a register for node @p node
*/
static void assign_reg(const ir_node *block, ir_node *node,
unsigned *forbidden_regs)
static void assign_reg(ir_node const *const block, ir_node *const node, arch_register_req_t const *const req, unsigned *const forbidden_regs)
{
assert(!is_Phi(node));
/* preassigned register? */
const arch_register_t *final_reg = arch_get_irn_register(node);
const arch_register_req_t *req = arch_get_irn_register_req(node);
unsigned width = req->width;
arch_register_t const *final_reg = arch_get_irn_register(node);
unsigned const width = req->width;
if (final_reg != NULL) {
DB((dbg, LEVEL_2, "Preassignment %+F -> %s\n", node, final_reg->name));
use_reg(node, final_reg, width);
......@@ -1198,18 +1192,18 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node,
/* is any of the live-throughs using a constrained output register? */
unsigned *live_through_regs = NULL;
be_foreach_definition(node, cls, value,
be_foreach_definition(node, cls, value, req,
(void)value;
if (req_->width > 1)
if (req->width > 1)
double_width = true;
if (!arch_register_req_is(req_, limited))
if (!arch_register_req_is(req, limited))
continue;
if (live_through_regs == NULL) {
live_through_regs = rbitset_alloca(n_regs);
determine_live_through_regs(live_through_regs, node);
}
rbitset_or(forbidden_regs, req_->limited, n_regs);
if (rbitsets_have_common(req_->limited, live_through_regs, n_regs))
rbitset_or(forbidden_regs, req->limited, n_regs);
if (rbitsets_have_common(req->limited, live_through_regs, n_regs))
good = false;
);
......@@ -1691,8 +1685,8 @@ static void allocate_coalesce_block(ir_node *block, void *data)
free_last_uses(&live_nodes, node);
/* assign output registers */
be_foreach_definition_(node, cls, value,
assign_reg(block, value, forbidden_regs);
be_foreach_definition_(node, cls, value, req,
assign_reg(block, value, req, forbidden_regs);
);
}
......
......@@ -135,14 +135,14 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
);
/* collect all registers occurring in out constraints. */
be_foreach_definition(node, cls, def,
be_foreach_definition(node, cls, def, req,
(void)def;
if (!arch_register_req_is(req_, limited))
if (!arch_register_req_is(req, limited))
continue;
if (def_constr == NULL) {
def_constr = rbitset_alloca(cls->n_regs);
}
rbitset_or(def_constr, req_->limited, cls->n_regs);
rbitset_or(def_constr, req->limited, cls->n_regs);
);
/* no output constraints => we're good */
......
......@@ -819,8 +819,8 @@ static void process_block(ir_node *block)
/* allocate all values _defined_ by this instruction */
workset_clear(new_vals);
be_foreach_definition(irn, cls, value,
assert(req_->width == 1);
be_foreach_definition(irn, cls, value, req,
assert(req->width == 1);
workset_insert(new_vals, value, false);
);
displace(new_vals, 0);
......
......@@ -140,10 +140,10 @@ static unsigned get_value_width(const ir_node *node)
static void do_spilling(ir_nodeset_t *live_nodes, ir_node *node)
{
size_t values_defined = 0;
be_foreach_definition(node, cls, value,
be_foreach_definition(node, cls, value, req,
(void)value;
assert(req_->width >= 1);
values_defined += req_->width;
assert(req->width >= 1);
values_defined += req->width;
);
/* we need registers for the non-live argument values */
......@@ -225,7 +225,7 @@ static void remove_defs(ir_node *node, ir_nodeset_t *nodeset)
/* You must break out of your loop when hitting the first phi function. */
assert(!is_Phi(node));
be_foreach_definition(node, cls, value,
be_foreach_definition(node, cls, value, req,
ir_nodeset_remove(nodeset, value);
);
}
......
......@@ -566,7 +566,7 @@ static fp_liveness fp_liveness_transfer(ir_node *irn, fp_liveness live)
{
const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_fp];
be_foreach_definition(irn, cls, def,
be_foreach_definition(irn, cls, def, req,
const arch_register_t *reg = x87_get_irn_register(def);
live &= ~(1 << reg->index);
);
......
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