pan: Enable rematerialization for more ops

IADD_IMM and uniform loads should not be spilled. Make them
rematerializable. Restrict to loads that write at most one register
for simplicity for now.

Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37955>
This commit is contained in:
Christoph Pillmayer 2025-10-20 10:11:16 +00:00 committed by Marge Bot
parent d20049b430
commit eba3d3a17e

View file

@ -2,6 +2,7 @@
* Copyright 2023-2024 Alyssa Rosenzweig
* Copyright 2023-2024 Valve Corporation
* Copyright 2022,2025 Collabora Ltd.
* Copyright 2025 Arm Ltd.
* SPDX-License-Identifier: MIT
*/
@ -306,15 +307,37 @@ reconstruct_index(struct spill_ctx *ctx, unsigned node)
return r;
}
static bool
only_const_sources(bi_instr *I)
{
bool res = true;
for (uint32_t s = 0; s < I->nr_srcs && res; ++s) {
bi_index src = I->src[s];
enum bi_index_type t = src.type;
res &= t == BI_INDEX_CONSTANT || t == BI_INDEX_FAU;
}
return res;
}
static bool
can_remat(bi_instr *I)
{
switch (I->op) {
case BI_OPCODE_IADD_IMM_I32:
case BI_OPCODE_IADD_IMM_V2I16:
return only_const_sources(I);
case BI_OPCODE_LD_BUFFER_I8:
case BI_OPCODE_LD_BUFFER_I16:
case BI_OPCODE_LD_BUFFER_I24:
case BI_OPCODE_LD_BUFFER_I32:
/* TODO: Allow loads that write >1 reg. */
return only_const_sources(I);
case BI_OPCODE_MOV_I32:
assert(!I->src[0].memory);
assert(!I->dest[0].memory);
assert(I->dest[0].type == BI_INDEX_NORMAL);
return (I->src[0].type == BI_INDEX_CONSTANT); // || (I->src[0].type == BI_INDEX_REGISTER);
enum bi_index_type t = I->src[0].type;
return t == BI_INDEX_CONSTANT || t == BI_INDEX_FAU;
default:
return false;
}
@ -323,14 +346,27 @@ can_remat(bi_instr *I)
static bi_instr *
remat_to(bi_builder *b, bi_index dst, struct spill_ctx *ctx, unsigned node)
{
assert(dst.type == BI_INDEX_NORMAL);
assert(node < ctx->spill_max);
bi_instr *I = ctx->remat[node];
assert(can_remat(I));
switch (I->op) {
case BI_OPCODE_IADD_IMM_I32:
return bi_iadd_imm_i32_to(b, dst, I->src[0], I->index);
case BI_OPCODE_IADD_IMM_V2I16:
return bi_iadd_imm_v2i16_to(b, dst, I->src[0], I->index);
case BI_OPCODE_LD_BUFFER_I8:
return bi_ld_buffer_i8_to(b, dst, I->src[0], I->src[1]);
case BI_OPCODE_LD_BUFFER_I16:
return bi_ld_buffer_i16_to(b, dst, I->src[0], I->src[1]);
case BI_OPCODE_LD_BUFFER_I24:
return bi_ld_buffer_i24_to(b, dst, I->src[0], I->src[1]);
case BI_OPCODE_LD_BUFFER_I32:
return bi_ld_buffer_i32_to(b, dst, I->src[0], I->src[1]);
case BI_OPCODE_MOV_I32:
assert(I->src[0].type == BI_INDEX_CONSTANT /*|| I->src[0].type == BI_INDEX_REGISTER*/);
assert(dst.type == BI_INDEX_NORMAL);
assert(I->src[0].type == BI_INDEX_CONSTANT ||
I->src[0].type == BI_INDEX_FAU);
return bi_mov_i32_to(b, dst, I->src[0]);
default:
UNREACHABLE("invalid remat");