mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 02:48:06 +02:00
pan/bi: Fix MEMMOV size calculation
Doing stores first, loads second doesn't work because there can be
chains of store, load, store... .
Use a fixed point approach instead to calculate sizes for all
destinations.
Fixes: 2fd5b8a391 ("pan/bi: Account for MEMMOV in bi_record_sizes")
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40915>
This commit is contained in:
parent
ce810bb19b
commit
3427b20b71
1 changed files with 41 additions and 47 deletions
|
|
@ -1398,58 +1398,52 @@ min_algorithm(struct spill_ctx *ctx)
|
|||
void
|
||||
bi_record_sizes(bi_context *ctx, uint32_t *sizes)
|
||||
{
|
||||
bi_foreach_instr_global(ctx, I) {
|
||||
if (I->nr_dests == 0 || I->dest[0].type != BI_INDEX_NORMAL)
|
||||
continue;
|
||||
unsigned idx = I->dest[0].value;
|
||||
bi_foreach_ssa_dest(I, d) {
|
||||
idx = I->dest[d].value;
|
||||
assert(sizes[idx] == 0 && "SSA broken");
|
||||
switch (I->op) {
|
||||
case BI_OPCODE_PHI:
|
||||
case BI_OPCODE_MEMMOV:
|
||||
break;
|
||||
default:
|
||||
sizes[idx] = bi_count_write_registers(I, d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(sizes, 0, ctx->ssa_alloc);
|
||||
|
||||
/* now that we know the rest of the sizes, find the sizes for PHI nodes */
|
||||
bi_foreach_block(ctx, block) {
|
||||
bi_foreach_phi_in_block(block, I) {
|
||||
if (I->dest[0].type != BI_INDEX_NORMAL)
|
||||
bool progress = true;
|
||||
|
||||
while (progress) {
|
||||
progress = false;
|
||||
|
||||
bi_foreach_instr_global(ctx, I) {
|
||||
if (I->nr_dests == 0 || I->dest[0].type != BI_INDEX_NORMAL)
|
||||
continue;
|
||||
unsigned idx = I->dest[0].value;
|
||||
sizes[idx] = 1;
|
||||
bi_foreach_ssa_src(I, s) {
|
||||
sizes[idx] = MAX2(sizes[idx], sizes[I->src[s].value]);
|
||||
|
||||
bi_foreach_ssa_dest(I, d) {
|
||||
const uint32_t old_size = sizes[I->dest[d].value];
|
||||
uint32_t new_size = old_size;
|
||||
|
||||
switch (I->op) {
|
||||
case BI_OPCODE_PHI:
|
||||
case BI_OPCODE_MEMMOV:
|
||||
/* Output size determined by the inputs. */
|
||||
bi_foreach_src(I, s) {
|
||||
switch (I->src[s].type) {
|
||||
case BI_INDEX_NORMAL:
|
||||
new_size = MAX2(new_size, sizes[I->src[s].value]);
|
||||
break;
|
||||
case BI_INDEX_CONSTANT:
|
||||
case BI_INDEX_FAU:
|
||||
new_size = 1;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("invalid index type for size calculation\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Output size independent of the inputs. */
|
||||
new_size = bi_count_write_registers(I, d);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Need to continue if there was a change or the dst is not yet
|
||||
* defined. */
|
||||
progress |= new_size == 0 || old_size != new_size;
|
||||
sizes[I->dest[d].value] = new_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* After we know PHI sizes, determine MEMMOV sizes. */
|
||||
|
||||
bi_foreach_instr_global(ctx, I) {
|
||||
if (I->op != BI_OPCODE_MEMMOV || I->dest[0].type != BI_INDEX_NORMAL)
|
||||
continue;
|
||||
|
||||
if (I->dest[0].memory) {
|
||||
assert(!I->src[0].memory);
|
||||
sizes[I->dest[0].value] = sizes[I->src[0].value];
|
||||
}
|
||||
}
|
||||
|
||||
bi_foreach_instr_global(ctx, I) {
|
||||
if (I->op != BI_OPCODE_MEMMOV || I->dest[0].type != BI_INDEX_NORMAL)
|
||||
continue;
|
||||
|
||||
if (!I->dest[0].memory) {
|
||||
assert(I->src[0].memory);
|
||||
sizes[I->dest[0].value] = sizes[I->src[0].value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue