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

bearch: rework should_be_same constraint

- Rename other_same field to should_be_same.
- Remove arch_register_req_type_other_same, it's enough to see if the
  should_be_same field is not zero.
parent 58b0168a
......@@ -30,7 +30,7 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
*/
static unsigned get_first_same(arch_register_req_t const *const req)
{
unsigned const other = req->other_same;
unsigned const other = req->should_be_same;
for (unsigned i = 0; i != 32; ++i) {
if (other & (1U << i))
return i;
......@@ -200,7 +200,7 @@ static void assure_should_be_same_requirements(ir_node *const node)
be_foreach_out(node, i) {
arch_register_req_t const *const req
= arch_get_irn_register_req_out(node, i);
if (!arch_register_req_is(req, should_be_same))
if (req->should_be_same == 0)
continue;
unsigned const same_pos = get_first_same(req);
ir_node *const in_node = get_irn_n(node, same_pos);
......@@ -264,7 +264,7 @@ static void amd64_finish_irg_walker(ir_node *const block, void *const env)
{
(void) env;
/* Insert should_be_same copies. */
/* Insert copies for should_be_same constraints. */
sched_foreach_safe(block, irn) {
if (is_amd64_irn(irn))
assure_should_be_same_requirements(irn);
......
......@@ -111,8 +111,8 @@ const x86_asm_constraint_list_t amd64_asm_constraints = {
static const arch_register_req_t amd64_requirement_gp_same_0 = {
.cls = &amd64_reg_classes[CLASS_amd64_gp],
.limited = NULL,
.type = arch_register_req_type_should_be_same,
.other_same = BIT(0),
.type = arch_register_req_type_none,
.should_be_same = BIT(0),
.other_different = 0,
.width = 1,
};
......@@ -120,8 +120,8 @@ static const arch_register_req_t amd64_requirement_gp_same_0 = {
static const arch_register_req_t amd64_requirement_xmm_same_0 = {
.cls = &amd64_reg_classes[CLASS_amd64_xmm],
.limited = NULL,
.type = arch_register_req_type_should_be_same,
.other_same = BIT(0),
.type = arch_register_req_type_none,
.should_be_same = BIT(0),
.other_different = 0,
.width = 1,
};
......@@ -129,9 +129,8 @@ static const arch_register_req_t amd64_requirement_xmm_same_0 = {
static const arch_register_req_t amd64_requirement_gp_same_0_not_1 = {
.cls = &amd64_reg_classes[CLASS_amd64_gp],
.limited = NULL,
.type = arch_register_req_type_should_be_same
| arch_register_req_type_must_be_different,
.other_same = BIT(0),
.type = arch_register_req_type_must_be_different,
.should_be_same = BIT(0),
.other_different = BIT(1),
.width = 1,
};
......@@ -139,9 +138,8 @@ static const arch_register_req_t amd64_requirement_gp_same_0_not_1 = {
static const arch_register_req_t amd64_requirement_xmm_same_0_not_1 = {
.cls = &amd64_reg_classes[CLASS_amd64_xmm],
.limited = NULL,
.type = arch_register_req_type_should_be_same
| arch_register_req_type_must_be_different,
.other_same = BIT(0),
.type = arch_register_req_type_must_be_different,
.should_be_same = BIT(0),
.other_different = BIT(1),
.width = 1,
};
......
......@@ -91,7 +91,7 @@ static void introduce_prolog_epilog(ir_graph *irg)
static int get_first_same(const arch_register_req_t* req)
{
const unsigned other = req->other_same;
const unsigned other = req->should_be_same;
for (int i = 0; i < 32; ++i) {
if (other & (1U << i))
return i;
......@@ -110,7 +110,7 @@ static void fix_should_be_same(ir_node *block, void *data)
be_foreach_out(node, i) {
const arch_register_req_t *req
= arch_get_irn_register_req_out(node, i);
if (!arch_register_req_is(req, should_be_same))
if (req->should_be_same == 0)
continue;
int same_pos = get_first_same(req);
......
......@@ -22,7 +22,7 @@ arch_register_req_t const arch_no_requirement = {
.cls = NULL,
.limited = NULL,
.type = arch_register_req_type_none,
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 0,
};
......
......@@ -26,14 +26,12 @@
typedef enum arch_register_req_type_t {
/** No special type, but may still have a limited array set. */
arch_register_req_type_none = 0,
/** The register should be equal to another one at the node. */
arch_register_req_type_should_be_same = 1U << 0,
/** The register must be unequal from some other at the node. */
arch_register_req_type_must_be_different = 1U << 1,
arch_register_req_type_must_be_different = 1U << 0,
/** The registernumber should be aligned (in case of multiregister values)*/
arch_register_req_type_aligned = 1U << 2,
arch_register_req_type_aligned = 1U << 1,
/** ignore while allocating registers */
arch_register_req_type_ignore = 1U << 3,
arch_register_req_type_ignore = 1U << 2,
} arch_register_req_type_t;
ENUM_BITSET(arch_register_req_type_t)
......@@ -228,8 +226,8 @@ struct arch_register_req_t {
* first register). NULL if all registers are allowed. */
const unsigned *limited;
arch_register_req_type_t type; /**< The type of the constraint. */
/** Bitmask of ins which should use the same register (should_be_same). */
unsigned other_same;
/** Bitmask of ins which should use the same register. */
unsigned should_be_same;
/** Bitmask of ins which shall use a different register (must_be_different) */
unsigned other_different;
/** Specifies how many sequential registers are required */
......@@ -244,7 +242,7 @@ static inline bool reg_reqs_equal(const arch_register_req_t *req1,
if (req1->type != req2->type ||
req1->cls != req2->cls ||
req1->other_same != req2->other_same ||
req1->should_be_same != req2->should_be_same ||
req1->other_different != req2->other_different ||
(req1->limited != NULL) != (req2->limited != NULL))
return false;
......
......@@ -23,11 +23,10 @@ arch_register_req_t const *be_make_register_req(struct obstack *obst, be_asm_con
if (same_as >= n_outs)
panic("invalid output number in same_as constraint");
arch_register_req_t *const req = OALLOC(obst, arch_register_req_t);
arch_register_req_t *const req = OALLOCZ(obst, arch_register_req_t);
arch_register_req_t const *const other = out_reqs[same_as];
*req = *other;
req->type |= arch_register_req_type_should_be_same;
req->other_same = 1U << pos;
*req = *other;
req->should_be_same = 1U << pos;
/* Switch constraints. This is because in firm we have same_as
* constraints on the output constraints while in the gcc asm syntax
......@@ -215,7 +214,7 @@ ir_node *be_make_asm(ir_node const *const node, ir_node **in, arch_register_req_
}
if (different != 0) {
arch_register_req_t *const req = OALLOC(obst, arch_register_req_t);
arch_register_req_t *const req = OALLOCZ(obst, arch_register_req_t);
*req = *oreq;
req->type |= arch_register_req_type_must_be_different;
req->other_different = different;
......
......@@ -205,7 +205,7 @@ static bool co_is_optimizable_root(const ir_node *irn)
if (is_Phi(irn) || is_Perm_Proj(irn))
return true;
if (arch_register_req_is(req, should_be_same))
if (req->should_be_same != 0)
return true;
return false;
......@@ -418,9 +418,9 @@ static void co_collect_units(ir_node *irn, void *env)
unit->nodes[0] = irn;
unit->nodes[1] = get_Perm_src(irn);
unit->costs[1] = co->get_costs(irn, -1);
} else if (arch_register_req_is(req, should_be_same)) {
} else if (req->should_be_same != 0) {
/* Src == Tgt of a 2-addr-code instruction */
const unsigned other = req->other_same;
const unsigned other = req->should_be_same;
int count = 0;
for (int i = 0; (1U << i) <= other; ++i) {
......@@ -612,8 +612,8 @@ static void build_graph_walker(ir_node *irn, void *env)
} else if (is_Perm_Proj(irn)) { /* Perms */
ir_node *arg = get_Perm_src(irn);
add_edges(co, irn, arg, co->get_costs(irn, -1));
} else if (arch_register_req_is(req, should_be_same)) {
const unsigned other = req->other_same;
} else if (req->should_be_same != 0) {
const unsigned other = req->should_be_same;
for (int i = 0; 1U << i <= other; ++i) {
if (other & (1U << i)) {
ir_node *other = get_irn_n(skip_Proj(irn), i);
......
......@@ -199,8 +199,8 @@ static void dump_register_req(FILE *const F, arch_register_req_t const *const re
}
}
if (arch_register_req_is(req, should_be_same))
dump_bitmask(F, " same as", req->other_same);
if (req->should_be_same != 0)
dump_bitmask(F, " same as", req->should_be_same);
if (arch_register_req_is(req, must_be_different))
dump_bitmask(F, " different from", req->other_different);
......
......@@ -393,8 +393,7 @@ static bool push_through_perm(ir_node *const perm, arch_register_class_t const *
);
be_foreach_definition(node, cls, value, req,
if ((req->type & ~arch_register_req_type_should_be_same) != 0
|| req->limited != NULL)
if (req->type != 0 || req->limited != NULL)
goto done;
);
......
......@@ -190,11 +190,10 @@ ir_node *be_new_Copy(ir_node *bl, ir_node *op)
arch_set_irn_register_req_out(res, 0, cls->class_req);
arch_register_req_t *const req = allocate_reg_req(irg);
req->cls = cls;
req->type = arch_register_req_type_should_be_same
| (in_req->type & arch_register_req_type_aligned);
req->other_same = 1U << 0;
req->width = in_req->width;
req->cls = cls;
req->type = in_req->type & arch_register_req_type_aligned;
req->should_be_same = 1U << 0;
req->width = in_req->width;
arch_set_irn_register_req_out(res, 0, req);
return res;
}
......@@ -350,7 +349,7 @@ const arch_register_req_t *be_create_reg_req(struct obstack *obst,
unsigned *limited
= rbitset_obstack_alloc(obst, cls->n_regs);
rbitset_set(limited, reg->index);
arch_register_req_t *req = OALLOC(obst, arch_register_req_t);
arch_register_req_t *req = OALLOCZ(obst, arch_register_req_t);
req->type = additional_types;
req->cls = cls;
req->limited = limited;
......
......@@ -253,8 +253,8 @@ static void create_affinity_edges(ir_node *irn, void *env)
return;
insert_afe_edge(pbqp_alloc_env, irn, arg, -1);
} else if (arch_register_req_is(req, should_be_same)) {
const unsigned other = req->other_same;
} else if (req->should_be_same != 0) {
const unsigned other = req->should_be_same;
int i;
for (i = 0; 1U << i <= other; ++i) {
......
......@@ -243,14 +243,14 @@ static void check_defs(ir_nodeset_t const *const live_nodes, float const weight,
give_penalties_for_limits(live_nodes, penalty, limited, node);
}
if (arch_register_req_is(req, should_be_same)) {
if (req->should_be_same != 0) {
ir_node *insn = skip_Proj(node);
allocation_info_t *info = get_allocation_info(node);
int arity = get_irn_arity(insn);
float factor = 1.0f / rbitset_popcount(&req->other_same, arity);
float factor = 1.0f / rbitset_popcount(&req->should_be_same, arity);
foreach_irn_in(insn, i, op) {
if (!rbitset_is_set(&req->other_same, i))
if (!rbitset_is_set(&req->should_be_same, i))
continue;
/* if we the value at the should_be_same input doesn't die at the
......@@ -326,13 +326,13 @@ static void analyze_block(ir_node *block, void *data)
static void congruence_def(ir_nodeset_t *const live_nodes, ir_node const *const node, arch_register_req_t const *const req)
{
/* should be same constraint? */
if (arch_register_req_is(req, should_be_same)) {
if (req->should_be_same != 0) {
const ir_node *insn = skip_Proj_const(node);
unsigned node_idx = get_irn_idx(node);
node_idx = uf_find(congruence_classes, node_idx);
foreach_irn_in(insn, i, op) {
if (!rbitset_is_set(&req->other_same, i))
if (!rbitset_is_set(&req->should_be_same, i))
continue;
int op_idx = get_irn_idx(op);
......@@ -657,12 +657,12 @@ static void assign_reg(ir_node const *const block, ir_node *const node, arch_reg
/* give should_be_same boni */
allocation_info_t *info = get_allocation_info(node);
ir_node *in_node = skip_Proj(node);
if (arch_register_req_is(req, should_be_same)) {
if (req->should_be_same != 0) {
float weight = (float)get_block_execfreq(block);
assert(get_irn_arity(in_node) <= (int)sizeof(req->other_same) * 8);
assert(get_irn_arity(in_node) <= (int)sizeof(req->should_be_same) * 8);
foreach_irn_in(in_node, i, in) {
if (!rbitset_is_set(&req->other_same, i))
if (!rbitset_is_set(&req->should_be_same, i))
continue;
const arch_register_t *reg = arch_get_irn_register(in);
......
......@@ -946,8 +946,8 @@ static void assure_different_constraints(ir_node *irn, ir_node *skipped_irn, con
if (arch_register_req_is(req, must_be_different)) {
const unsigned other = req->other_different;
if (arch_register_req_is(req, should_be_same)) {
const unsigned same = req->other_same;
if (req->should_be_same != 0) {
const unsigned same = req->should_be_same;
if (is_po2(other) && is_po2(same)) {
int idx_other = ntz(other);
......
......@@ -230,7 +230,7 @@ static void block_count_values(ir_node *block, void *data)
if (req->cls == NULL)
continue;
++stats->values;
if (arch_register_req_is(req, should_be_same) || is_Phi(value))
if (req->should_be_same != 0 || is_Phi(value))
++stats->should_be_sames;
if (req->limited != NULL)
++stats->constrained_values;
......
......@@ -196,7 +196,7 @@ static inline int need_constraint_copy(ir_node *irn)
*/
static int get_first_same(const arch_register_req_t* req)
{
const unsigned other = req->other_same;
const unsigned other = req->should_be_same;
for (int i = 0; i < 32; ++i) {
if (other & (1U << i))
return i;
......@@ -214,7 +214,7 @@ static void assure_should_be_same_requirements(ir_node *node)
/* check all OUT requirements, if there is a should_be_same */
be_foreach_out(node, i) {
arch_register_req_t const *const req = arch_get_irn_register_req_out(node, i);
if (!arch_register_req_is(req, should_be_same))
if (req->should_be_same == 0)
continue;
/* get in and out register */
......@@ -281,7 +281,7 @@ static void fix_am_source(ir_node *irn)
be_foreach_out(irn, i) {
const arch_register_req_t *req = arch_get_irn_register_req_out(irn, i);
if (!arch_register_req_is(req, should_be_same))
if (req->should_be_same == 0)
continue;
/* get in and out register */
......
......@@ -1258,7 +1258,7 @@ static bool reg_req_same_limited(arch_register_req_t const *const req, arch_regi
static bool is_clobber(ir_node const *const asm_n, ir_node const *const value)
{
arch_register_req_t const *const req = arch_get_irn_register_req(value);
if (arch_register_req_is(req, should_be_same))
if (req->should_be_same != 0)
return false;
unsigned const num = get_Proj_num(value);
......
......@@ -1052,7 +1052,7 @@ sub generate_requirements {
.cls = &${arch}_reg_classes[CLASS_${arch}_${class}],
.limited = NULL,
.type = ${reqtype},
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = $width,
};
......@@ -1067,9 +1067,6 @@ EOF
die("Fatal error: Could not build subset for requirements '$reqs' of '$op' pos $idx ... exiting.\n");
}
if ($same_pos != 0) {
push(@req_type_mask, "arch_register_req_type_should_be_same");
}
if ($different_pos != 0) {
push(@req_type_mask, "arch_register_req_type_must_be_different");
}
......@@ -1085,7 +1082,7 @@ EOF
.cls = &${arch}_reg_classes[CLASS_${arch}_${class}],
.limited = ${limit_bitset},
.type = ${reqtype},
.other_same = ${same_pos},
.should_be_same = ${same_pos},
.other_different = ${different_pos},
.width = $width,
};
......
......@@ -116,7 +116,7 @@ const arch_register_req_t ${arch}_class_reg_req_${old_classname} = {
.cls = &${arch}_reg_classes[CLASS_${arch}_${old_classname}],
.limited = NULL,
.type = arch_register_req_type_none,
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 1,
};
......@@ -193,7 +193,7 @@ const arch_register_req_t ${arch}_single_reg_req_${old_classname}_${name} = {
.type = arch_register_req_type_none,
.cls = ${class_ptr},
.limited = ${arch}_limited_${old_classname}_${name},
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 1,
};
......
......@@ -43,7 +43,7 @@
static int get_first_same(const arch_register_req_t *req)
{
const unsigned other = req->other_same;
const unsigned other = req->should_be_same;
for (int i = 0; i < 32; ++i) {
if (other & (1U << i))
return i;
......@@ -63,7 +63,7 @@ static void assure_should_be_same_requirements(ir_node *node)
/* check all OUT requirements, if there is a should_be_same */
be_foreach_out(node, i) {
const arch_register_req_t *req = arch_get_irn_register_req_out(node, i);
if (!arch_register_req_is(req, should_be_same))
if (req->should_be_same == 0)
continue;
int same_pos = get_first_same(req);
......
......@@ -2058,7 +2058,7 @@ static const arch_register_req_t float1_req = {
.cls = &sparc_reg_classes[CLASS_sparc_fp],
.limited = NULL,
.type = arch_register_req_type_none,
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 1,
};
......@@ -2066,7 +2066,7 @@ static const arch_register_req_t float2_req = {
.cls = &sparc_reg_classes[CLASS_sparc_fp],
.limited = NULL,
.type = arch_register_req_type_aligned,
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 2,
};
......@@ -2074,7 +2074,7 @@ static const arch_register_req_t float4_req = {
.cls = &sparc_reg_classes[CLASS_sparc_fp],
.limited = NULL,
.type = arch_register_req_type_aligned,
.other_same = 0,
.should_be_same = 0,
.other_different = 0,
.width = 4,
};
......
Markdown is supported
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