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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user