pvr: Amend subarray ownership code

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Acked-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>
This commit is contained in:
Simon Perretta
2023-02-13 14:17:01 +00:00
committed by Marge Bot
parent af0685d05e
commit 0ce53b002f
3 changed files with 73 additions and 20 deletions

View File

@@ -23,10 +23,12 @@
#include "rogue.h"
#include "util/macros.h"
#include "util/u_qsort.h"
#include "util/ralloc.h"
#include "util/register_allocate.h"
#include <stdbool.h>
#include <stdlib.h>
/**
* \file rogue_regalloc.c
@@ -41,6 +43,20 @@ typedef struct rogue_live_range {
unsigned end;
} rogue_live_range;
static int regarray_cmp(const void *lhs, const void *rhs, UNUSED void *arg)
{
const rogue_regarray *l = lhs;
const rogue_regarray *r = rhs;
/* Signs swapped for sorting largest->smallest. */
if (l->size > r->size)
return -1;
else if (l->size < r->size)
return 1;
return 0;
}
PUBLIC
bool rogue_regalloc(rogue_shader *shader)
{
@@ -201,6 +217,7 @@ bool rogue_regalloc(rogue_shader *shader)
rogue_regarray **parent_regarrays =
rzalloc_array_size(shader, sizeof(*parent_regarrays), regarray_count);
/* Construct list of sorted parent regarrays. */
unsigned num_parent_regarrays = 0;
rogue_foreach_regarray (regarray, shader) {
if (regarray->parent || regarray->regs[0]->class != ROGUE_REG_CLASS_SSA)
@@ -209,6 +226,12 @@ bool rogue_regalloc(rogue_shader *shader)
parent_regarrays[num_parent_regarrays++] = regarray;
}
util_qsort_r(parent_regarrays,
num_parent_regarrays,
sizeof(*parent_regarrays),
regarray_cmp,
NULL);
for (unsigned u = 0; u < num_parent_regarrays; ++u) {
rogue_regarray *regarray = parent_regarrays[u];
@@ -219,9 +242,13 @@ bool rogue_regalloc(rogue_shader *shader)
enum rogue_reg_class new_class = regalloc_info[ra_class].class;
bool used = false;
for (unsigned r = 0; r < regarray->size; ++r)
for (unsigned r = 0; r < regarray->size; ++r) {
used |= rogue_reg_is_used(shader, new_class, new_base_index + r);
if (used)
break;
}
/* First time using new regarray, modify in place. */
if (!used) {
progress |=
@@ -234,21 +261,7 @@ bool rogue_regalloc(rogue_shader *shader)
regarray->size,
new_class,
new_base_index);
progress |= rogue_regarray_replace(regarray, new_regarray);
/* Replace subarrays. */
rogue_foreach_subarray_safe (subarray, regarray) {
unsigned idx_offset =
subarray->regs[0]->index - regarray->regs[0]->index;
new_regarray = rogue_regarray_cached(shader,
subarray->size,
new_class,
new_base_index + idx_offset);
progress |= rogue_regarray_replace(subarray, new_regarray);
rogue_regarray_delete(subarray);
}
rogue_regarray_delete(regarray);
progress |= rogue_regarray_replace(shader, regarray, new_regarray);
}
}

View File

@@ -475,10 +475,23 @@ static rogue_regarray *rogue_regarray_create(rogue_shader *shader,
for (unsigned u = 0; u < common_regarray->size; ++u)
common_regarray->regs[u]->regarray = regarray;
/* Steal its children. */
rogue_foreach_subarray_safe (subarray, common_regarray) {
unsigned parent_index = common_regarray->regs[0]->index;
unsigned child_index = subarray->regs[0]->index;
assert(child_index >= parent_index);
subarray->parent = regarray;
subarray->regs = &parent_regptr[child_index - parent_index];
list_del(&subarray->child_link);
list_addtail(&subarray->child_link, &regarray->children);
}
common_regarray->parent = regarray;
ralloc_free(common_regarray->regs);
common_regarray->regs = parent_regptr;
list_addtail(&regarray->children, &common_regarray->child_link);
list_addtail(&common_regarray->child_link, &regarray->children);
} else {
/* We share registers with another regarray, and we are a subset of it.
*/

View File

@@ -2379,11 +2379,15 @@ static inline bool rogue_src_regarray_replace(rogue_regarray_use *use,
return true;
}
static inline bool rogue_regarray_replace(rogue_regarray *old_regarray,
static inline bool rogue_regarray_replace(rogue_shader *shader,
rogue_regarray *old_regarray,
rogue_regarray *new_regarray)
{
bool replaced = true;
assert(!old_regarray->parent);
assert(!new_regarray->parent);
rogue_foreach_regarray_write_safe (write, old_regarray) {
replaced &= rogue_dst_regarray_replace(write, new_regarray);
}
@@ -2392,8 +2396,31 @@ static inline bool rogue_regarray_replace(rogue_regarray *old_regarray,
replaced &= rogue_src_regarray_replace(use, new_regarray);
}
/* N.B. The old regarray isn't automatically deleted here, this needs to be
* done manually. */
enum rogue_reg_class new_class = new_regarray->regs[0]->class;
unsigned new_base_index = new_regarray->regs[0]->index;
/* Replace subarrays. */
rogue_foreach_subarray_safe (old_subarray, old_regarray) {
unsigned idx_offset =
old_subarray->regs[0]->index - old_regarray->regs[0]->index;
rogue_regarray *new_subarray =
rogue_regarray_cached(shader,
old_subarray->size,
new_class,
new_base_index + idx_offset);
rogue_foreach_regarray_write_safe (write, old_subarray) {
replaced &= rogue_dst_regarray_replace(write, new_subarray);
}
rogue_foreach_regarray_use_safe (use, old_subarray) {
replaced &= rogue_src_regarray_replace(use, new_subarray);
}
rogue_regarray_delete(old_subarray);
}
rogue_regarray_delete(old_regarray);
return replaced;
}