lima: Use ra_alloc_contig_reg_class().

This greatly simplifies our register allocation code and reduces the
number of registers RA has to walk over.

Reviewed-by: Erico Nunes <nunes.erico@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9437>
This commit is contained in:
Eric Anholt
2021-03-05 10:37:20 -08:00
committed by Marge Bot
parent cf33316ec0
commit 23df5dba92
+16 -91
View File
@@ -29,26 +29,7 @@
#include "ppir.h"
#include "lima_context.h"
#define PPIR_FULL_REG_NUM 6
#define PPIR_VEC1_REG_NUM (PPIR_FULL_REG_NUM * 4) /* x, y, z, w */
#define PPIR_VEC2_REG_NUM (PPIR_FULL_REG_NUM * 3) /* xy, yz, zw */
#define PPIR_VEC3_REG_NUM (PPIR_FULL_REG_NUM * 2) /* xyz, yzw */
#define PPIR_VEC4_REG_NUM PPIR_FULL_REG_NUM /* xyzw */
#define PPIR_HEAD_VEC1_REG_NUM PPIR_FULL_REG_NUM /* x */
#define PPIR_HEAD_VEC2_REG_NUM PPIR_FULL_REG_NUM /* xy */
#define PPIR_HEAD_VEC3_REG_NUM PPIR_FULL_REG_NUM /* xyz */
#define PPIR_HEAD_VEC4_REG_NUM PPIR_FULL_REG_NUM /* xyzw */
#define PPIR_VEC1_REG_BASE 0
#define PPIR_VEC2_REG_BASE (PPIR_VEC1_REG_BASE + PPIR_VEC1_REG_NUM)
#define PPIR_VEC3_REG_BASE (PPIR_VEC2_REG_BASE + PPIR_VEC2_REG_NUM)
#define PPIR_VEC4_REG_BASE (PPIR_VEC3_REG_BASE + PPIR_VEC3_REG_NUM)
#define PPIR_HEAD_VEC1_REG_BASE (PPIR_VEC4_REG_BASE + PPIR_VEC4_REG_NUM)
#define PPIR_HEAD_VEC2_REG_BASE (PPIR_HEAD_VEC1_REG_BASE + PPIR_HEAD_VEC1_REG_NUM)
#define PPIR_HEAD_VEC3_REG_BASE (PPIR_HEAD_VEC2_REG_BASE + PPIR_HEAD_VEC2_REG_NUM)
#define PPIR_HEAD_VEC4_REG_BASE (PPIR_HEAD_VEC3_REG_BASE + PPIR_HEAD_VEC3_REG_NUM)
#define PPIR_REG_COUNT (PPIR_HEAD_VEC4_REG_BASE + PPIR_HEAD_VEC4_REG_NUM)
#define PPIR_REG_COUNT (6 * 4)
enum ppir_ra_reg_class {
ppir_ra_reg_class_vec1,
@@ -68,70 +49,32 @@ enum ppir_ra_reg_class {
ppir_ra_reg_class_num,
};
static const int ppir_ra_reg_base[ppir_ra_reg_class_num + 1] = {
[ppir_ra_reg_class_vec1] = PPIR_VEC1_REG_BASE,
[ppir_ra_reg_class_vec2] = PPIR_VEC2_REG_BASE,
[ppir_ra_reg_class_vec3] = PPIR_VEC3_REG_BASE,
[ppir_ra_reg_class_vec4] = PPIR_VEC4_REG_BASE,
[ppir_ra_reg_class_head_vec1] = PPIR_HEAD_VEC1_REG_BASE,
[ppir_ra_reg_class_head_vec2] = PPIR_HEAD_VEC2_REG_BASE,
[ppir_ra_reg_class_head_vec3] = PPIR_HEAD_VEC3_REG_BASE,
[ppir_ra_reg_class_head_vec4] = PPIR_HEAD_VEC4_REG_BASE,
[ppir_ra_reg_class_num] = PPIR_REG_COUNT,
};
static unsigned int *
ppir_ra_reg_q_values[ppir_ra_reg_class_num] = {
(unsigned int []) {1, 2, 3, 4, 1, 2, 3, 4},
(unsigned int []) {2, 3, 3, 3, 1, 2, 3, 3},
(unsigned int []) {2, 2, 2, 2, 1, 2, 2, 2},
(unsigned int []) {1, 1, 1, 1, 1, 1, 1, 1},
(unsigned int []) {1, 1, 1, 1, 1, 1, 1, 1},
(unsigned int []) {1, 1, 1, 1, 1, 1, 1, 1},
(unsigned int []) {1, 1, 1, 1, 1, 1, 1, 1},
(unsigned int []) {1, 1, 1, 1, 1, 1, 1, 1},
};
struct ra_regs *ppir_regalloc_init(void *mem_ctx)
{
struct ra_regs *ret = ra_alloc_reg_set(mem_ctx, PPIR_REG_COUNT, false);
if (!ret)
return NULL;
/* (x, y, z, w) (xy, yz, zw) (xyz, yzw) (xyzw) (x) (xy) (xyz) (xyzw) */
static const int class_reg_num[ppir_ra_reg_class_num] = {
4, 3, 2, 1, 1, 1, 1, 1,
};
/* base reg (x, y, z, w) confliction with other regs */
for (int h = 0; h < 4; h++) {
int base_reg_mask = 1 << h;
for (int i = 1; i < ppir_ra_reg_class_num; i++) {
int class_reg_base_mask = (1 << ((i % 4) + 1)) - 1;
for (int j = 0; j < class_reg_num[i]; j++) {
if (base_reg_mask & (class_reg_base_mask << j)) {
for (int k = 0; k < PPIR_FULL_REG_NUM; k++) {
ra_add_reg_conflict(ret, k * 4 + h,
ppir_ra_reg_base[i] + k * class_reg_num[i] + j);
}
}
}
/* Classes for contiguous 1-4 channel groups anywhere within a register. */
struct ra_class *classes[ppir_ra_reg_class_num];
for (int i = 0; i < ppir_ra_reg_class_head_vec1; i++) {
classes[i] = ra_alloc_contig_reg_class(ret, i + 1);
for (int j = 0; j < PPIR_REG_COUNT; j += 4) {
for (int swiz = 0; swiz < (4 - i); swiz++)
ra_class_add_reg(classes[i], j + swiz);
}
}
/* build all other confliction by the base reg confliction */
for (int i = 0; i < PPIR_VEC1_REG_NUM; i++)
ra_make_reg_conflicts_transitive(ret, i);
struct ra_class *classes[ppir_ra_reg_class_num];
for (int i = 0; i < ppir_ra_reg_class_num; i++)
classes[i] = ra_alloc_reg_class(ret);
/* Classes for contiguous 1-4 channels with a start channel of .x */
for (int i = ppir_ra_reg_class_head_vec1; i < ppir_ra_reg_class_num; i++) {
classes[i] = ra_alloc_contig_reg_class(ret, i - ppir_ra_reg_class_head_vec1 + 1);
int reg_index = 0;
for (int i = 0; i < ppir_ra_reg_class_num; i++) {
while (reg_index < ppir_ra_reg_base[i + 1])
ra_class_add_reg(classes[i], reg_index++);
for (int j = 0; j < PPIR_REG_COUNT; j += 4)
ra_class_add_reg(classes[i], j);
}
ra_set_finalize(ret, ppir_ra_reg_q_values);
ra_set_finalize(ret, NULL);
return ret;
}
@@ -159,23 +102,6 @@ static void ppir_regalloc_update_reglist_ssa(ppir_compiler *comp)
}
}
static int get_phy_reg_index(int reg)
{
int i;
for (i = 0; i < ppir_ra_reg_class_num; i++) {
if (reg < ppir_ra_reg_base[i + 1]) {
reg -= ppir_ra_reg_base[i];
break;
}
}
if (i < ppir_ra_reg_class_head_vec1)
return reg / (4 - i) * 4 + reg % (4 - i);
else
return reg * 4;
}
static void ppir_regalloc_print_result(ppir_compiler *comp)
{
printf("======ppir regalloc result======\n");
@@ -651,8 +577,7 @@ static bool ppir_regalloc_prog_try(ppir_compiler *comp, bool *spilled)
n = 0;
list_for_each_entry(ppir_reg, reg, &comp->reg_list, list) {
int reg_index = ra_get_node_reg(g, n++);
reg->index = get_phy_reg_index(reg_index);
reg->index = ra_get_node_reg(g, n++);
}
ralloc_free(g);