Commit 87d50cbc authored by Christoph Mallon's avatar Christoph Mallon
Browse files

belive: Replace the union for head and nodes of the liveness sets by a struct...

belive: Replace the union for head and nodes of the liveness sets by a struct with a flexible array member.
parent ee066a1b
......@@ -48,7 +48,7 @@ typedef enum arch_irn_flags_t {
ENUM_BITSET(arch_irn_flags_t)
typedef struct be_lv_t be_lv_t;
typedef union be_lv_info_t be_lv_info_t;
typedef struct be_lv_info_t be_lv_info_t;
typedef struct be_stack_layout_t be_stack_layout_t;
typedef struct backend_info_t backend_info_t;
typedef struct sched_info_t sched_info_t;
......
......@@ -132,11 +132,8 @@ void be_dump_liveness_block(be_lv_t *lv, FILE *F, const ir_node *bl)
fprintf(F, "liveness:\n");
if (info != NULL) {
unsigned n = info[0].head.n_members;
unsigned i;
for (i = 0; i < n; ++i) {
be_lv_info_node_t *n = &info[i+1].node;
for (unsigned i = 0, n = info->n_members; i < n; ++i) {
be_lv_info_node_t *const n = &info->nodes[i];
ir_fprintf(F, "%s %+F\n", lv_flags_to_str(n->flags), n->node);
}
}
......
......@@ -29,22 +29,20 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
#define LV_STD_SIZE 64
#define LV_STD_SIZE 63
static unsigned _be_liveness_bsearch(const be_lv_info_t *arr,
const ir_node *node)
static unsigned _be_liveness_bsearch(be_lv_info_t const *const arr, ir_node const *const node)
{
unsigned n = arr[0].head.n_members;
unsigned const n = arr->n_members;
if (n == 0)
return 0;
unsigned lo = 0;
unsigned hi = n;
const be_lv_info_t *payload = arr + 1;
unsigned res;
unsigned lo = 0;
unsigned hi = n;
unsigned res;
do {
unsigned md = lo + ((hi - lo) >> 1);
ir_node *md_node = payload[md].node.node;
ir_node *md_node = arr->nodes[md].node;
if (node > md_node) {
lo = md + 1;
......@@ -71,9 +69,8 @@ be_lv_info_node_t *be_lv_get(const be_lv_t *li, const ir_node *bl,
/* Get the position of the index in the array. */
unsigned pos = _be_liveness_bsearch(irn_live, irn);
/* Get the record in question. 1 must be added, since the first record
* contains information about the array and must be skipped. */
be_lv_info_node_t *rec = &irn_live[pos + 1].node;
/* Get the record in question. */
be_lv_info_node_t *const rec = &irn_live->nodes[pos];
/* Check, if the irn is in deed in the array. */
if (rec->node == irn)
......@@ -91,44 +88,38 @@ static be_lv_info_node_t *be_lv_get_or_set(be_lv_t *li, ir_node *bl,
be_lv_info_t *irn_live = ir_nodehashmap_get(be_lv_info_t, &li->map, bl);
if (irn_live == NULL) {
irn_live = OALLOCNZ(&li->obst, be_lv_info_t, LV_STD_SIZE);
irn_live[0].head.n_size = LV_STD_SIZE-1;
irn_live = OALLOCFZ(&li->obst, be_lv_info_t, nodes, LV_STD_SIZE);
irn_live->n_size = LV_STD_SIZE;
ir_nodehashmap_insert(&li->map, bl, irn_live);
}
/* Get the position of the index in the array. */
unsigned pos = _be_liveness_bsearch(irn_live, irn);
/* Get the record in question. 1 must be added, since the first record
* contains information about the array and must be skipped. */
be_lv_info_node_t *res = &irn_live[pos + 1].node;
/* Get the record in question. */
be_lv_info_node_t *res = &irn_live->nodes[pos];
/* Check, if the irn is in deed in the array. */
if (res->node != irn) {
unsigned n_members = irn_live[0].head.n_members;
unsigned n_size = irn_live[0].head.n_size;
unsigned n_members = irn_live->n_members;
unsigned n_size = irn_live->n_size;
if (n_members + 1 >= n_size) {
/* double the array size. Remember that the first entry is
* metadata about the array and not a real array element */
unsigned old_size_bytes = (n_size + 1) * sizeof(irn_live[0]);
unsigned new_size = (2 * n_size) + 1;
size_t new_size_bytes = new_size * sizeof(irn_live[0]);
be_lv_info_t *nw = OALLOCN(&li->obst, be_lv_info_t, new_size);
memcpy(nw, irn_live, old_size_bytes);
memset(((char*) nw) + old_size_bytes, 0,
new_size_bytes - old_size_bytes);
nw[0].head.n_size = new_size - 1;
/* double the array size. */
unsigned const new_size = 2 * n_size;
be_lv_info_t *const nw = OALLOCF(&li->obst, be_lv_info_t, nodes, new_size);
memcpy(nw, irn_live, sizeof(*irn_live) + n_size * sizeof(*irn_live->nodes));
memset(&nw->nodes[n_size], 0, (new_size - n_size) * sizeof(*irn_live->nodes));
nw->n_size = new_size;
irn_live = nw;
ir_nodehashmap_insert(&li->map, bl, nw);
}
be_lv_info_t *payload = &irn_live[1];
for (unsigned i = n_members; i > pos; --i) {
payload[i] = payload[i - 1];
irn_live->nodes[i] = irn_live->nodes[i - 1];
}
++irn_live[0].head.n_members;
res = &payload[pos].node;
++irn_live->n_members;
res = &irn_live->nodes[pos];
res->node = irn;
res->flags = 0;
}
......@@ -151,22 +142,21 @@ static void lv_remove_irn_walker(ir_node *const bl, void *const data)
if (irn_live == NULL)
return;
unsigned const n = irn_live[0].head.n_members;
const ir_node *const irn = w->irn;
unsigned const pos = _be_liveness_bsearch(irn_live, irn);
be_lv_info_t *payload = irn_live + 1;
be_lv_info_node_t *res = &payload[pos].node;
unsigned const n = irn_live->n_members;
ir_node const *const irn = w->irn;
unsigned const pos = _be_liveness_bsearch(irn_live, irn);
be_lv_info_node_t *const res = &irn_live->nodes[pos];
if (res->node != irn)
return;
/* The node is indeed in the block's array. Let's remove it. */
for (unsigned i = pos + 1; i < n; ++i)
payload[i - 1] = payload[i];
irn_live->nodes[i - 1] = irn_live->nodes[i];
payload[n - 1].node.node = NULL;
payload[n - 1].node.flags = 0;
irn_live->nodes[n - 1].node = NULL;
irn_live->nodes[n - 1].flags = 0;
--irn_live[0].head.n_members;
--irn_live->n_members;
DBG((dbg, LEVEL_3, "\tdeleting %+F from %+F at pos %d\n", irn, bl, pos));
}
......
......@@ -143,14 +143,10 @@ struct be_lv_info_node_t {
unsigned flags;
};
struct be_lv_info_head_t {
unsigned n_members;
unsigned n_size;
};
union be_lv_info_t {
struct be_lv_info_head_t head;
struct be_lv_info_node_t node;
struct be_lv_info_t {
unsigned n_members;
unsigned n_size;
be_lv_info_node_t nodes[];
};
be_lv_info_node_t *be_lv_get(const be_lv_t *li, const ir_node *block,
......@@ -215,7 +211,7 @@ static inline lv_iterator_t be_lv_iteration_begin(const be_lv_t *lv,
assert(lv->sets_valid);
lv_iterator_t res;
res.info = ir_nodehashmap_get(be_lv_info_t, &lv->map, block);
res.i = res.info != NULL ? res.info[0].head.n_members : 0;
res.i = res.info ? res.info->n_members : 0;
return res;
}
......@@ -223,10 +219,10 @@ static inline ir_node *be_lv_iteration_next(lv_iterator_t *iterator,
be_lv_state_t flags)
{
while (iterator->i != 0) {
const be_lv_info_t *info = iterator->info + iterator->i--;
assert(get_irn_mode(info->node.node) != mode_T);
if (info->node.flags & flags)
return info->node.node;
be_lv_info_node_t const *const node = &iterator->info->nodes[--iterator->i];
assert(get_irn_mode(node->node) != mode_T);
if (node->flags & flags)
return node->node;
}
return NULL;
}
......@@ -236,12 +232,12 @@ static inline ir_node *be_lv_iteration_cls_next(lv_iterator_t *iterator,
const arch_register_class_t *cls)
{
while (iterator->i != 0) {
const be_lv_info_t *info = iterator->info + iterator->i--;
assert(get_irn_mode(info->node.node) != mode_T);
if (!(info->node.flags & flags))
be_lv_info_node_t const *const lnode = &iterator->info->nodes[--iterator->i];
assert(get_irn_mode(lnode->node) != mode_T);
if (!(lnode->flags & flags))
continue;
ir_node *node = info->node.node;
ir_node *const node = lnode->node;
if (!arch_irn_consider_in_reg_alloc(cls, node))
continue;
return node;
......
......@@ -758,27 +758,26 @@ static void lv_check_walker(ir_node *bl, void *data)
be_lv_info_t *const curr = ir_nodehashmap_get(be_lv_info_t, &w->given->map, bl);
be_lv_info_t *const fr = ir_nodehashmap_get(be_lv_info_t, &w->fresh->map, bl);
if (!fr && curr && curr[0].head.n_members > 0) {
if (!fr && curr && curr->n_members > 0) {
ir_fprintf(stderr, "%+F liveness should be empty but current liveness contains:\n", bl);
for (unsigned i = 0; i < curr[0].head.n_members; ++i) {
ir_fprintf(stderr, "\t%+F\n", curr[1 + i].node.node);
for (unsigned i = 0; i < curr->n_members; ++i) {
ir_fprintf(stderr, "\t%+F\n", curr->nodes[i].node);
}
} else if (curr) {
unsigned n_curr = curr[0].head.n_members;
unsigned n_fresh = fr[0].head.n_members;
unsigned const n_curr = curr->n_members;
unsigned const n_fresh = fr->n_members;
if (n_curr != n_fresh) {
ir_fprintf(stderr, "%+F: liveness set sizes differ. curr %d, correct %d\n", bl, n_curr, n_fresh);
ir_fprintf(stderr, "current:\n");
for (unsigned i = 0; i < n_curr; ++i) {
be_lv_info_node_t *n = &curr[1 + i].node;
be_lv_info_node_t *const n = &curr->nodes[i];
ir_fprintf(stderr, "%+F %u %+F %s\n", bl, i, n->node, lv_flags_to_str(n->flags));
}
ir_fprintf(stderr, "correct:\n");
for (unsigned i = 0; i < n_fresh; ++i) {
be_lv_info_node_t *n = &fr[1 + i].node;
be_lv_info_node_t *const n = &fr->nodes[i];
ir_fprintf(stderr, "%+F %u %+F %s\n", bl, i, n->node, lv_flags_to_str(n->flags));
}
}
......
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