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:

committed by
Marge Bot

parent
af0685d05e
commit
0ce53b002f
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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, ®array->children);
|
||||
}
|
||||
|
||||
common_regarray->parent = regarray;
|
||||
ralloc_free(common_regarray->regs);
|
||||
common_regarray->regs = parent_regptr;
|
||||
list_addtail(®array->children, &common_regarray->child_link);
|
||||
list_addtail(&common_regarray->child_link, ®array->children);
|
||||
} else {
|
||||
/* We share registers with another regarray, and we are a subset of it.
|
||||
*/
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user