mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
i915/corm: add temporary register tracking and dead temp release
Track the last use of each SSA def and release temporary registers as soon as they're dead, allowing more aggressive temp reuse. Includes the register aliasing fix for mov/fneg: these ops alias the def to the source register, so the source's lifetime must be extended to match the def's to prevent premature release. shader-db (I915_FS=nir): 52/403 compiled, 231 alu shader-db (I915_FS=both): nir won 52 (26 identical, 16 tied, 9 better, 1 only), 233 TGSI, 118 neither Assisted-by: Claude
This commit is contained in:
parent
c6be264c2d
commit
9a88dff9f4
1 changed files with 54 additions and 0 deletions
|
|
@ -22,8 +22,51 @@ struct nir_to_i915 {
|
|||
|
||||
uint32_t *ureg_map;
|
||||
unsigned ureg_map_size;
|
||||
|
||||
int *last_use;
|
||||
int ip;
|
||||
};
|
||||
|
||||
static bool
|
||||
mark_last_use_cb(nir_src *src, void *state)
|
||||
{
|
||||
struct nir_to_i915 *c = state;
|
||||
if (src->ssa->index < c->ureg_map_size)
|
||||
c->last_use[src->ssa->index] = c->ip;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
compute_last_use(struct nir_to_i915 *c, nir_function_impl *impl)
|
||||
{
|
||||
c->ip = 0;
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr(instr, block) {
|
||||
nir_foreach_src(instr, mark_last_use_cb, c);
|
||||
c->ip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
release_if_last_use_cb(nir_src *src, void *state)
|
||||
{
|
||||
struct nir_to_i915 *c = state;
|
||||
unsigned idx = src->ssa->index;
|
||||
if (idx < c->ureg_map_size && c->last_use[idx] == c->ip) {
|
||||
uint32_t ureg = c->ureg_map[idx];
|
||||
if (GET_UREG_TYPE(ureg) == REG_TYPE_R)
|
||||
i915_release_temp(c->p, GET_UREG_NR(ureg));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
release_dead_temps(struct nir_to_i915 *c, nir_instr *instr)
|
||||
{
|
||||
nir_foreach_src(instr, release_if_last_use_cb, c);
|
||||
}
|
||||
|
||||
static void
|
||||
set_ureg(struct nir_to_i915 *c, nir_def *def, uint32_t ureg)
|
||||
{
|
||||
|
|
@ -185,6 +228,9 @@ emit_alu(struct nir_to_i915 *c, nir_alu_instr *alu)
|
|||
i915_release_temp(p, GET_UREG_NR(dest));
|
||||
set_ureg(c, def, alu->op == nir_op_fneg ? negate(src0, 1, 1, 1, 1)
|
||||
: src0);
|
||||
unsigned src_idx = alu->src[0].src.ssa->index;
|
||||
if (c->last_use[src_idx] == c->ip)
|
||||
c->last_use[src_idx] = c->last_use[def->index];
|
||||
return;
|
||||
}
|
||||
case nir_op_fabs:
|
||||
|
|
@ -727,13 +773,20 @@ i915_translate_fragment_program_nir(struct i915_context *i915,
|
|||
.opts = *opts,
|
||||
.ureg_map_size = impl->ssa_alloc,
|
||||
.ureg_map = CALLOC(impl->ssa_alloc, sizeof(uint32_t)),
|
||||
.last_use = CALLOC(impl->ssa_alloc, sizeof(int)),
|
||||
};
|
||||
|
||||
memset(c.last_use, -1, impl->ssa_alloc * sizeof(int));
|
||||
compute_last_use(&c, impl);
|
||||
|
||||
c.ip = 0;
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr(instr, block) {
|
||||
emit_instr(&c, instr);
|
||||
if (p->error[0])
|
||||
break;
|
||||
release_dead_temps(&c, instr);
|
||||
c.ip++;
|
||||
}
|
||||
if (p->error[0])
|
||||
break;
|
||||
|
|
@ -799,6 +852,7 @@ cleanup:
|
|||
else
|
||||
ralloc_free(p->error);
|
||||
|
||||
FREE(c.last_use);
|
||||
FREE(c.ureg_map);
|
||||
FREE(p);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue