unsigned node_count = bi_max_temp(ctx);
struct lcra_state *l =
- lcra_alloc_equations(node_count, 16, 1);
+ lcra_alloc_equations(node_count, 1);
l->class_start[BI_REG_CLASS_WORK] = 0;
l->class_size[BI_REG_CLASS_WORK] = 64 * 4; /* R0 - R63, all 32-bit */
continue;
l->class[dest] = BI_REG_CLASS_WORK;
- lcra_set_alignment(l, dest, 2); /* 2^2 = 4 */
+ lcra_set_alignment(l, dest, 2, 16); /* 2^2 = 4 */
lcra_restrict_range(l, dest, 4);
}
if (!ctx->temp_count)
return NULL;
- struct lcra_state *l = lcra_alloc_equations(ctx->temp_count, 16, 5);
+ struct lcra_state *l = lcra_alloc_equations(ctx->temp_count, 5);
/* Starts of classes, in bytes */
l->class_start[REG_CLASS_WORK] = 16 * 0;
unsigned *found_class = calloc(sizeof(unsigned), ctx->temp_count);
unsigned *min_alignment = calloc(sizeof(unsigned), ctx->temp_count);
+ unsigned *min_bound = calloc(sizeof(unsigned), ctx->temp_count);
mir_foreach_instr_global(ctx, ins) {
/* Swizzles of 32-bit sources on 64-bit instructions need to be
}
for (unsigned i = 0; i < ctx->temp_count; ++i) {
- lcra_set_alignment(l, i, min_alignment[i] ? min_alignment[i] : 2);
+ lcra_set_alignment(l, i, min_alignment[i] ? min_alignment[i] : 2,
+ min_bound[i] ? min_bound[i] : 16);
lcra_restrict_range(l, i, found_class[i]);
}
free(found_class);
free(min_alignment);
+ free(min_bound);
/* Next, we'll determine semantic class. We default to zero (work).
* But, if we're used with a special operation, that will force us to a
struct lcra_state *
lcra_alloc_equations(
- unsigned node_count,
- unsigned bound, unsigned class_count)
+ unsigned node_count, unsigned class_count)
{
struct lcra_state *l = calloc(1, sizeof(*l));
l->node_count = node_count;
l->class_count = class_count;
- l->bound = bound;
l->alignment = calloc(sizeof(l->alignment[0]), node_count);
l->linear = calloc(sizeof(l->linear[0]), node_count * node_count);
}
void
-lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2)
+lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2, unsigned bound)
{
- l->alignment[node] = align_log2 + 1;
+ l->alignment[node] = (align_log2 + 1) | (bound << 16);
}
void
void
lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len)
{
- if (node < l->node_count && l->alignment[node])
- l->modulus[node] = DIV_ROUND_UP(l->bound - len + 1, 1 << (l->alignment[node] - 1));
+ if (node < l->node_count && l->alignment[node]) {
+ unsigned BA = l->alignment[node];
+ unsigned alignment = (BA & 0xffff) - 1;
+ unsigned bound = BA >> 16;
+ l->modulus[node] = DIV_ROUND_UP(bound - len + 1, 1 << alignment);
+ }
}
void
unsigned _class = l->class[step];
unsigned class_start = l->class_start[_class];
- unsigned shift = l->alignment[step] - 1;
+ unsigned BA = l->alignment[step];
+ unsigned shift = (BA & 0xffff) - 1;
+ unsigned bound = BA >> 16;
- unsigned P = l->bound >> shift;
+ unsigned P = bound >> shift;
unsigned Q = l->modulus[step];
unsigned r_max = l->class_size[_class];
unsigned k_max = r_max >> shift;
struct lcra_state {
unsigned node_count;
- /* Word boundary where vectors can't cross */
- unsigned bound;
-
/* Alignment for node in log2(bytes)+1. Since alignment must be
* non-negative power-of-two, the elements are strictly positive
- * integers. Zero is the sentinel for a missing node */
+ * integers. Zero is the sentinel for a missing node. In upper word,
+ * bound. */
unsigned *alignment;
/* Linear constraints imposed. Nested array sized upfront, organized as
struct lcra_state *
lcra_alloc_equations(
- unsigned node_count,
- unsigned bound, unsigned class_count);
+ unsigned node_count, unsigned class_count);
void
lcra_free(struct lcra_state *l);
lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2);
void
-lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2);
+lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2, unsigned bound);
void
lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len);