Commit 9ba43dc6 authored by Matthias Braun's avatar Matthias Braun
Browse files

bearch: Use bool:1 instead of a bitset for remainin reg_req types

parent 474447c7
......@@ -110,26 +110,18 @@ 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_none,
.should_be_same = BIT(0),
.must_be_different = 0,
.width = 1,
};
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_none,
.should_be_same = BIT(0),
.must_be_different = 0,
.width = 1,
};
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_none,
.should_be_same = BIT(0),
.must_be_different = BIT(1),
.width = 1,
......@@ -137,8 +129,6 @@ 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_none,
.should_be_same = BIT(0),
.must_be_different = BIT(1),
.width = 1,
......@@ -1438,7 +1428,7 @@ static ir_node *gen_Start(ir_node *node)
be_make_start_mem(&start_mem, start, o++);
/* the stack pointer */
be_make_start_out(&start_val[REG_RSP], start, o++, &amd64_registers[REG_RSP], arch_register_req_type_ignore);
be_make_start_out(&start_val[REG_RSP], start, o++, &amd64_registers[REG_RSP], true);
/* function parameters in registers */
const unsigned *allocatable_regs = be_birg_from_irg(irg)->allocatable_regs;
......@@ -1458,10 +1448,8 @@ static ir_node *gen_Start(ir_node *node)
for (size_t i = 0; i < N_AMD64_REGISTERS; ++i) {
if (!rbitset_is_set(cconv->callee_saves, i))
continue;
arch_register_req_type_t const flags =
i == REG_RBP && !cconv->omit_fp ? arch_register_req_type_ignore :
arch_register_req_type_none;
be_make_start_out(&start_val[i], start, o++, &amd64_registers[i], flags);
bool ignore = i == REG_RBP && !cconv->omit_fp;
be_make_start_out(&start_val[i], start, o++, &amd64_registers[i], ignore);
}
assert(n_outs == o);
......
......@@ -1729,7 +1729,7 @@ static ir_node *gen_Start(ir_node *node)
be_make_start_mem(&start_mem, start, o++);
be_make_start_out(&start_sp, start, o++, &arm_registers[REG_SP], arch_register_req_type_ignore);
be_make_start_out(&start_sp, start, o++, &arm_registers[REG_SP], true);
/* function parameters in registers */
start_params_offset = o;
......
......@@ -19,12 +19,7 @@
#include "raw_bitset.h"
arch_register_req_t const arch_no_requirement = {
.cls = NULL,
.limited = NULL,
.type = arch_register_req_type_none,
.should_be_same = 0,
.must_be_different = 0,
.width = 0,
.cls = NULL,
};
static reg_out_info_t *get_out_info_n(const ir_node *node, unsigned pos)
......@@ -97,13 +92,15 @@ void be_make_start_mem(be_start_info_t *const info, ir_node *const start, unsign
arch_set_irn_register_req_out(start, pos, arch_no_register_req);
}
void be_make_start_out(be_start_info_t *const info, ir_node *const start, unsigned const pos, arch_register_t const *const reg, arch_register_req_type_t const flags)
void be_make_start_out(be_start_info_t *const info, ir_node *const start,
unsigned const pos, arch_register_t const *const reg,
bool const ignore)
{
info->pos = pos;
info->irn = NULL;
arch_register_req_t const *const req =
flags == arch_register_req_type_none ? reg->single_req :
be_create_reg_req(be_get_be_obst(get_irn_irg(start)), reg, flags);
arch_register_req_t const *const req = ignore
? be_create_reg_req(be_get_be_obst(get_irn_irg(start)), reg, true)
: reg->single_req;
arch_set_irn_register_req_out(start, pos, req);
arch_set_irn_register_out(start, pos, reg);
}
......
......@@ -20,19 +20,6 @@
#include "beinfo.h"
#include "be.h"
/**
* Different types of register allocation requirements.
*/
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 registernumber should be aligned (in case of multiregister values)*/
arch_register_req_type_aligned = 1U << 0,
/** ignore while allocating registers */
arch_register_req_type_ignore = 1U << 1,
} arch_register_req_type_t;
ENUM_BITSET(arch_register_req_type_t)
extern arch_register_req_t const arch_no_requirement;
#define arch_no_register_req (&arch_no_requirement)
......@@ -204,16 +191,6 @@ static inline const arch_register_t *arch_register_for_index(
return &cls->regs[idx];
}
/**
* Convenience macro to check for set constraints.
* @param req A pointer to register requirements.
* @param kind The kind of constraint to check for
* (see arch_register_req_type_t).
* @return 1, If the kind of constraint is present, 0 if not.
*/
#define arch_register_req_is(req, kind) \
(((req)->type & (arch_register_req_type_ ## kind)) != 0)
/**
* Expresses requirements to register allocation for an operand.
*/
......@@ -223,13 +200,16 @@ struct arch_register_req_t {
/** allowed register bitset (in case of wide-values this is only about the
* 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. */
unsigned should_be_same;
/** Bitmask of ins which shall use a different register (must_be_different) */
unsigned must_be_different;
/** Specifies how many sequential registers are required */
unsigned char width;
/** ignore this input/output while allocating registers */
bool ignore : 1;
/** The registernumber should be aligned (in case of multiregister values)*/
bool aligned : 1;
};
static inline bool reg_reqs_equal(const arch_register_req_t *req1,
......@@ -238,10 +218,11 @@ static inline bool reg_reqs_equal(const arch_register_req_t *req1,
if (req1 == req2)
return true;
if (req1->type != req2->type ||
req1->cls != req2->cls ||
req1->should_be_same != req2->should_be_same ||
if (req1->cls != req2->cls ||
req1->should_be_same != req2->should_be_same ||
req1->must_be_different != req2->must_be_different ||
req1->ignore != req2->ignore ||
req1->aligned != req2->aligned ||
(req1->limited != NULL) != (req2->limited != NULL))
return false;
......@@ -253,6 +234,12 @@ static inline bool reg_reqs_equal(const arch_register_req_t *req1,
return true;
}
static inline bool reg_req_has_constraint(const arch_register_req_t *req)
{
return req->limited != NULL || req->should_be_same != 0
|| req->must_be_different != 0 || req->ignore || req->aligned;
}
/**
* Architecture interface.
*/
......@@ -311,14 +298,14 @@ struct arch_isa_if_t {
static inline bool arch_irn_is_ignore(const ir_node *irn)
{
const arch_register_req_t *req = arch_get_irn_register_req(irn);
return arch_register_req_is(req, ignore);
return req->ignore;
}
static inline bool arch_irn_consider_in_reg_alloc(
const arch_register_class_t *cls, const ir_node *node)
{
const arch_register_req_t *req = arch_get_irn_register_req(node);
return req->cls == cls && !arch_register_req_is(req, ignore);
return req->cls == cls && !req->ignore;
}
arch_register_t const *arch_find_register(char const *name);
......@@ -354,7 +341,7 @@ arch_register_t const *arch_find_register(char const *name);
*/
#define be_foreach_definition(node, ccls, value, req, code) \
be_foreach_definition_(node, ccls, value, req, \
if (arch_register_req_is(req, ignore)) \
if (req->ignore) \
continue; \
code \
)
......@@ -367,7 +354,7 @@ arch_register_t const *arch_find_register(char const *name);
continue; \
ir_node *value = get_irn_n(node, i_); \
const arch_register_req_t *value_req = arch_get_irn_register_req(value); \
if (value_req->type & arch_register_req_type_ignore) \
if (value_req->ignore) \
continue; \
code \
} \
......@@ -383,7 +370,8 @@ typedef struct be_start_info_t {
void be_make_start_mem(be_start_info_t *info, ir_node *start, unsigned pos);
void be_make_start_out(be_start_info_t *info, ir_node *start, unsigned pos, arch_register_t const *reg, arch_register_req_type_t flags);
void be_make_start_out(be_start_info_t *info, ir_node *start, unsigned pos,
arch_register_t const *reg, bool ignore);
ir_node *be_get_start_proj(ir_graph *irg, be_start_info_t *info);
......
......@@ -50,7 +50,6 @@ arch_register_req_t const *be_make_register_req(struct obstack *obst, be_asm_con
*limited = c->allowed_registers;
memset(req, 0, sizeof(*req));
req->type = arch_register_req_type_none;
req->cls = c->cls;
req->limited = limited;
req->width = 1;
......
......@@ -56,8 +56,9 @@ static unsigned check_alignment_constraints(ir_node *node)
{
const arch_register_req_t *req = arch_get_irn_register_req(node);
// For larger than 1 variables, support only aligned constraints
assert((arch_register_req_is(req, aligned) || req->width == 1) && "Unaligned large (width > 1) variables not supported");
return arch_register_req_is(req, aligned) && req->width > 1;
assert((req->aligned || req->width == 1) &&
"Unaligned large (width > 1) variables not supported");
return req->aligned && req->width > 1;
}
static void make_color_var_name(char *buf, size_t buf_size,
......
......@@ -199,7 +199,7 @@ static void free_copy_opt(copy_opt_t *co)
static bool co_is_optimizable_root(const ir_node *irn)
{
arch_register_req_t const *const req = arch_get_irn_register_req(irn);
if (arch_register_req_is(req, ignore))
if (req->ignore)
return false;
if (is_Phi(irn) || is_Perm_Proj(irn))
......@@ -602,7 +602,7 @@ static void build_graph_walker(ir_node *irn, void *env)
return;
copy_opt_t *co = (copy_opt_t*)env;
const arch_register_req_t *req = arch_get_irn_register_req(irn);
if (req->cls != co->cls || arch_register_req_is(req, ignore))
if (req->cls != co->cls || req->ignore)
return;
if (is_Phi(irn)) { /* Phis */
......@@ -713,7 +713,7 @@ static void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
be_ifg_foreach_node(ifg, irn) {
arch_register_req_t const *const req = arch_get_irn_register_req(irn);
if (arch_register_req_is(req, ignore))
if (req->ignore)
continue;
int idx = node_map[get_irn_idx(irn)];
......
......@@ -206,9 +206,9 @@ static void dump_register_req(FILE *const F, arch_register_req_t const *const re
if (req->width != 1)
fprintf(F, " width:%d", req->width);
if (arch_register_req_is(req, aligned))
if (req->aligned)
fputs(" aligned", F);
if (arch_register_req_is(req, ignore))
if (req->ignore)
fputs(" ignore", F);
}
......
......@@ -267,7 +267,7 @@ static bool consider_component_node(bitset_t *const seen, ir_node *const irn)
bitset_set(seen, get_irn_idx(irn));
arch_register_req_t const *const req = arch_get_irn_register_req(irn);
if (arch_register_req_is(req, ignore))
if (req->ignore)
return false;
return true;
......
......@@ -385,15 +385,14 @@ static bool push_through_perm(ir_node *const perm, arch_register_class_t const *
* If we would allow to move the Perm above this instruction,
* the former dead operand would be live now at the point of
* the Perm, increasing the register pressure by one. */
if (in_req->type != arch_register_req_type_none ||
in_req->limited != NULL || !is_node_operand(perm, op)) {
if (reg_req_has_constraint(in_req) || !is_node_operand(perm, op)) {
DB((dbg_permmove, LEVEL_2, "\tcannot move past %+F due to operand %+F\n", node, op));
goto done;
}
);
be_foreach_definition(node, cls, value, req,
if (req->type != 0 || req->limited != NULL)
if (reg_req_has_constraint(req))
goto done;
);
......
......@@ -149,9 +149,9 @@ ir_node *be_new_Perm(arch_register_class_t const *const cls,
arch_set_irn_register_req_out(irn, i, cls->class_req);
} else {
arch_register_req_t *const new_req = allocate_reg_req(irg);
new_req->cls = cls;
new_req->type = (req->type & arch_register_req_type_aligned);
new_req->width = req->width;
new_req->cls = cls;
new_req->width = req->width;
new_req->aligned = req->aligned;
be_node_set_register_req_in(irn, i, new_req);
arch_set_irn_register_req_out(irn, i, new_req);
}
......@@ -191,8 +191,8 @@ ir_node *be_new_Copy(ir_node *bl, ir_node *op)
arch_register_req_t *const req = allocate_reg_req(irg);
req->cls = cls;
req->type = in_req->type & arch_register_req_type_aligned;
req->should_be_same = 1U << 0;
req->aligned = in_req->aligned;
req->width = in_req->width;
arch_set_irn_register_req_out(res, 0, req);
return res;
......@@ -343,17 +343,18 @@ ir_node *be_new_AnyVal(ir_node *block, const arch_register_class_t *cls)
}
const arch_register_req_t *be_create_reg_req(struct obstack *obst,
const arch_register_t *reg, arch_register_req_type_t additional_types)
const arch_register_t *reg,
bool ignore)
{
arch_register_class_t const *cls = reg->cls;
unsigned *limited
= rbitset_obstack_alloc(obst, cls->n_regs);
rbitset_set(limited, reg->index);
arch_register_req_t *req = OALLOCZ(obst, arch_register_req_t);
req->type = additional_types;
req->cls = cls;
req->limited = limited;
req->width = 1;
req->ignore = ignore;
return req;
}
......
......@@ -162,7 +162,8 @@ ir_node *be_new_AnyVal(ir_node *block, const arch_register_class_t *cls);
arch_register_req_t const **be_allocate_in_reqs(ir_graph *irg, unsigned n);
const arch_register_req_t *be_create_reg_req(struct obstack *obst,
const arch_register_t *reg, arch_register_req_type_t additional_types);
const arch_register_t *reg,
bool ignore);
/**
* Set the register requirements for a phi node.
......
......@@ -652,7 +652,7 @@ static void assign_reg(ir_node const *const block, ir_node *const node, arch_reg
}
/* ignore reqs must be preassigned */
assert(!arch_register_req_is(req, ignore));
assert(!req->ignore);
/* give should_be_same boni */
allocation_info_t *info = get_allocation_info(node);
......@@ -703,7 +703,7 @@ static void assign_reg(ir_node const *const block, ir_node *const node, arch_reg
continue;
/* alignment constraint? */
if (width > 1) {
if (arch_register_req_is(req, aligned) && (final_reg_index % width) != 0)
if (req->aligned && (final_reg_index % width) != 0)
continue;
bool fine = true;
for (unsigned r0 = r+1; r0 < r+width; ++r0) {
......@@ -1121,11 +1121,9 @@ static void enforce_constraints(ir_nodeset_t *live_nodes, ir_node *node,
double_width = true;
const arch_register_t *reg = arch_get_irn_register(op);
unsigned reg_index = reg->index;
if (arch_register_req_is(req, aligned)) {
if (!is_aligned(reg_index, req->width)) {
good = false;
continue;
}
if (req->aligned && !is_aligned(reg_index, req->width)) {
good = false;
continue;
}
if (req->limited == NULL)
continue;
......@@ -1499,7 +1497,7 @@ static void allocate_coalesce_block(ir_node *block, void *data)
if (req->cls != cls)
continue;
if (arch_register_req_is(req, ignore)) {
if (req->ignore) {
allocation_info_t *info = get_allocation_info(node);
info->current_value = node;
......@@ -1538,9 +1536,9 @@ static void allocate_coalesce_block(ir_node *block, void *data)
const arch_register_req_t *phi_req = cls->class_req;
if (req->width > 1) {
arch_register_req_t *new_req = allocate_reg_req(irg);
new_req->cls = cls;
new_req->type = req->type & arch_register_req_type_aligned;
new_req->width = req->width;
new_req->cls = cls;
new_req->width = req->width;
new_req->aligned = req->aligned;
phi_req = new_req;
}
ir_node *phi = be_new_Phi(block, n_preds, phi_ins, mode,
......
......@@ -85,7 +85,7 @@ static unsigned count_result(const ir_node *irn)
return 1;
arch_register_req_t const *const req = arch_get_irn_register_req(irn);
return arch_register_req_is(req, ignore) ? 0 : 1;
return req->ignore ? 0 : 1;
}
static unsigned normal_tree_cost(ir_node *irn)
......
......@@ -731,9 +731,8 @@ static void prepare_constr_insn(ir_node *const node)
continue;
ir_node *in = get_irn_n(node, i);
const arch_register_req_t *const in_req
= arch_get_irn_register_req(in);
if (arch_register_req_is(in_req, ignore))
const arch_register_req_t *const in_req = arch_get_irn_register_req(in);
if (in_req->ignore)
continue;
for (int i2 = i + 1; i2 < arity; ++i2) {
const arch_register_req_t *const req2
......@@ -798,9 +797,8 @@ static void prepare_constr_insn(ir_node *const node)
if (req->limited == NULL)
continue;
ir_node *in = get_irn_n(node, i);
const arch_register_req_t *const in_req
= arch_get_irn_register_req(in);
if (arch_register_req_is(in_req, ignore))
const arch_register_req_t *const in_req = arch_get_irn_register_req(in);
if (in_req->ignore)
continue;
/* Only create the copy if the operand is no copy.
* this is necessary since the assure constraints phase inserts
......@@ -871,7 +869,7 @@ typedef struct {
static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env)
{
arch_register_req_t const *const req = arch_get_irn_register_req(other_different);
if (arch_register_req_is(req, ignore)) {
if (req->ignore) {
DB((dbg_constr, LEVEL_1, "ignore constraint for %+F because other_irn is ignore\n", irn));
return;
}
......
......@@ -403,10 +403,10 @@ static void determine_phi_req(be_ssa_construction_env_t *env, ir_node *value)
ir_graph *irg = get_irn_irg(value);
struct obstack *obst = be_get_be_obst(irg);
arch_register_req_t *new_req = OALLOCZ(obst, arch_register_req_t);
new_req->cls = req->cls;
new_req->type = req->type & arch_register_req_type_aligned;
new_req->width = req->width;
env->phi_req = new_req;
new_req->cls = req->cls;
new_req->width = req->width;
new_req->aligned = req->aligned;
env->phi_req = new_req;
}
}
......
......@@ -254,7 +254,7 @@ static void ssa_destruction_check_walker(ir_node *block, void *data)
/* iterate over all args of phi */
foreach_irn_in(phi, i, arg) {
const arch_register_req_t *req = arch_get_irn_register_req(arg);
if (arch_register_req_is(req, ignore))
if (req->ignore)
continue;
assert(arch_get_irn_register(phi) == arch_get_irn_register(arg));
......
......@@ -201,7 +201,7 @@ void be_fix_stack_nodes(ir_graph *const irg, arch_register_t const *const sp)
const arch_register_req_t *sp_req;
if (!rbitset_is_set(birg->allocatable_regs, sp->global_index)) {
struct obstack *const obst = be_get_be_obst(irg);
sp_req = be_create_reg_req(obst, sp, arch_register_req_type_ignore);
sp_req = be_create_reg_req(obst, sp, true);
} else {
sp_req = sp->single_req;
}
......
......@@ -4161,7 +4161,7 @@ static ir_node *gen_Start(ir_node *node)
be_make_start_mem(&start_mem, start, o++);
/* the stack pointer */
be_make_start_out(&start_val[REG_ESP], start, o++, &ia32_registers[REG_ESP], arch_register_req_type_ignore);
be_make_start_out(&start_val[REG_ESP], start, o++, &ia32_registers[REG_ESP], true);
/* function parameters in registers */
start_params_offset = o;
......@@ -4179,10 +4179,8 @@ static ir_node *gen_Start(ir_node *node)
for (size_t i = 0; i < N_IA32_REGISTERS; ++i) {
if (!rbitset_is_set(cconv->callee_saves, i))
continue;
arch_register_req_type_t const flags =
i == REG_EBP && !cconv->omit_fp ? arch_register_req_type_ignore :
arch_register_req_type_none;
be_make_start_out(&start_val[i], start, o++, &ia32_registers[i], flags);
bool ignore = i == REG_EBP && !cconv->omit_fp;
be_make_start_out(&start_val[i], start, o++, &ia32_registers[i], ignore);
}
assert(n_outs == o);
......
......@@ -1013,15 +1013,15 @@ sub generate_requirements {
my $idx = shift;
my $is_in = shift;
my $width = 1;
my $extra = "";
my $result;
my @req_type_mask;
if (defined($flags)) {
foreach my $f (split(/|/, $flags)) {
if ($f eq "I") {
push(@req_type_mask, "arch_register_req_type_ignore");
$extra .= "\n\t.ignore = true,";
} elsif ($f eq "a") {
push(@req_type_mask, "arch_register_req_type_aligned");
$extra .= "\n\t.aligned = true,";
} elsif ($f eq "2" or $f eq "4" or $f eq "8") {
$width = int($f);
}
......@@ -1045,16 +1045,11 @@ sub generate_requirements {
if ($reqs eq "none") {
return "arch_no_requirement";
} elsif (is_reg_class($reqs) && !$is_reg) {
my $reqtype = join(" | ", @req_type_mask) || "arch_register_req_type_none";
$class = $reqs;
$result = <<EOF;
{
.cls = &${arch}_reg_classes[CLASS_${arch}_${class}],
.limited = NULL,
.type = ${reqtype},
.should_be_same = 0,
.must_be_different = 0,
.width = $width,
.cls = &${arch}_reg_classes[CLASS_${arch}_${class}],
.width = $width,$extra
};
EOF
......@@ -1067,8 +1062,6 @@ EOF
die("Fatal error: Could not build subset for requirements '$reqs' of '$op' pos $idx ... exiting.\n");
}
my $reqtype = join(" | ", @req_type_mask) || "arch_register_req_type_none";
if(!defined($limit_bitset)) {
$limit_bitset = "NULL";
}
......@@ -1078,10 +1071,9 @@ EOF
{
.cls = &${arch}_reg_classes[CLASS_${arch}_${class}],
.limited = ${limit_bitset},
.type = ${reqtype},
.should_be_same = ${same_pos},
.must_be_different = ${different_pos},
.width = $width,
.width = $width,$extra
};
EOF
......
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