unsigned int stack_count;
};
+/**
+ * Creates a set of registers for the allocator.
+ *
+ * mem_ctx is a ralloc context for the allocator. The reg set may be freed
+ * using ralloc_free().
+ */
struct ra_regs *
-ra_alloc_reg_set(unsigned int count)
+ra_alloc_reg_set(void *mem_ctx, unsigned int count)
{
unsigned int i;
struct ra_regs *regs;
- regs = rzalloc(NULL, struct ra_regs);
+ regs = rzalloc(mem_ctx, struct ra_regs);
regs->count = count;
regs->regs = rzalloc_array(regs, struct ra_reg, count);
}
}
+/**
+ * Adds a conflict between base_reg and reg, and also between reg and
+ * anything that base_reg conflicts with.
+ *
+ * This can simplify code for setting up multiple register classes
+ * which are aggregates of some base hardware registers, compared to
+ * explicitly using ra_add_reg_conflict.
+ */
+void
+ra_add_transitive_reg_conflict(struct ra_regs *regs,
+ unsigned int base_reg, unsigned int reg)
+{
+ int i;
+
+ ra_add_reg_conflict(regs, reg, base_reg);
+
+ for (i = 0; i < regs->regs[base_reg].num_conflicts; i++) {
+ ra_add_reg_conflict(regs, reg, regs->regs[base_reg].conflict_list[i]);
+ }
+}
+
unsigned int
ra_alloc_reg_class(struct ra_regs *regs)
{
/**
* Must be called after all conflicts and register classes have been
* set up and before the register set is used for allocation.
+ * To avoid costly q value computation, use the q_values paramater
+ * to pass precomputed q values to this function.
*/
void
-ra_set_finalize(struct ra_regs *regs)
+ra_set_finalize(struct ra_regs *regs, unsigned int **q_values)
{
unsigned int b, c;
regs->classes[b]->q = ralloc_array(regs, unsigned int, regs->class_count);
}
+ if (q_values) {
+ for (b = 0; b < regs->class_count; b++) {
+ for (c = 0; c < regs->class_count; c++) {
+ regs->classes[b]->q[c] = q_values[b][c];
+ }
+ }
+ return;
+ }
+
/* Compute, for each class B and C, how many regs of B an
* allocation to C could conflict with.
*/
* input data). These nodes do not end up in the stack during
* ra_simplify(), and thus at ra_select() time it is as if they were
* the first popped off the stack and assigned their fixed locations.
+ * Nodes that use this function do not need to be assigned a register
+ * class.
*
* Must be called before ra_simplify().
*/
if (cost <= 0.0)
continue;
+ /* Only consider registers for spilling if they are still in the
+ * interference graph (those on the stack have already been proven to be
+ * allocatable without spilling).
+ */
+ if (g->nodes[n].in_stack)
+ continue;
+
benefit = ra_get_spill_benefit(g, n);
if (benefit / cost > best_benefit) {