mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 13:50:11 +01:00
pan/bi: schedule simple iterators to avoid extra move
Try to move iterator as close to the end of the block as possible. The goal is to avoid the iterator being used after being updated, to prevent the need for an extra move instruction. shader-db report on `Mali-G725`: ``` total instrs in shared programs: 720530 -> 716482 (-0.56%) instrs in affected programs: 231842 -> 227794 (-1.75%) helped: 3804 HURT: 1 helped stats (abs) min: 1.0 max: 8.0 x̄: 1.06 x̃: 1 helped stats (rel) min: 0.14% max: 6.25% x̄: 2.75% x̃: 2.86% HURT stats (abs) min: 1.0 max: 1.0 x̄: 1.00 x̃: 1 HURT stats (rel) min: 0.05% max: 0.05% x̄: 0.05% x̃: 0.05% 95% mean confidence interval for instrs value: -1.08 -1.04 95% mean confidence interval for instrs %-change: -2.79% -2.71% Instrs are helped. total cycles in shared programs: 35295.80 -> 35295.55 (<.01%) cycles in affected programs: 3.50 -> 3.25 (-7.14%) helped: 8 HURT: 0 helped stats (abs) min: 0.03125 max: 0.03125 x̄: 0.03 x̃: 0 helped stats (rel) min: 6.90% max: 7.41% x̄: 7.15% x̃: 7.15% 95% mean confidence interval for cycles value: -0.03 -0.03 95% mean confidence interval for cycles %-change: -7.38% -6.92% Cycles are helped. total fma in shared programs: 5054.34 -> 5054.34 (0.00%) fma in affected programs: 0 -> 0 helped: 0 HURT: 0 total cvt in shared programs: 4707.69 -> 4644.44 (-1.34%) cvt in affected programs: 1471.28 -> 1408.03 (-4.30%) helped: 3804 HURT: 1 helped stats (abs) min: 0.015625 max: 0.125 x̄: 0.02 x̃: 0 helped stats (rel) min: 0.37% max: 12.50% x̄: 6.01% x̃: 6.67% HURT stats (abs) min: 0.015625 max: 0.015625 x̄: 0.02 x̃: 0 HURT stats (rel) min: 0.13% max: 0.13% x̄: 0.13% x̃: 0.13% 95% mean confidence interval for cvt value: -0.02 -0.02 95% mean confidence interval for cvt %-change: -6.07% -5.94% Cvt are helped. total sfu in shared programs: 1878.25 -> 1878.25 (0.00%) sfu in affected programs: 0 -> 0 helped: 0 HURT: 0 total v in shared programs: 2353 -> 2353 (0.00%) v in affected programs: 0 -> 0 helped: 0 HURT: 0 total t in shared programs: 5530 -> 5530 (0.00%) t in affected programs: 0 -> 0 helped: 0 HURT: 0 total ls in shared programs: 27975 -> 27975 (0.00%) ls in affected programs: 0 -> 0 helped: 0 HURT: 0 total code size in shared programs: 6386560 -> 6289664 (-1.52%) code size in affected programs: 508544 -> 411648 (-19.05%) helped: 757 HURT: 0 helped stats (abs) min: 128.0 max: 128.0 x̄: 128.00 x̃: 128 helped stats (rel) min: 0.83% max: 33.33% x̄: 31.09% x̃: 33.33% 95% mean confidence interval for code size value: -128.00 -128.00 95% mean confidence interval for code size %-change: -31.57% -30.60% Code size are helped. total threads in shared programs: 14698 -> 14698 (0.00%) threads in affected programs: 0 -> 0 helped: 0 HURT: 0 total loops in shared programs: 166 -> 166 (0.00%) loops in affected programs: 0 -> 0 helped: 0 HURT: 0 total spills in shared programs: 37 -> 37 (0.00%) spills in affected programs: 0 -> 0 helped: 0 HURT: 0 total fills in shared programs: 111 -> 111 (0.00%) fills in affected programs: 0 -> 0 helped: 0 HURT: 0 ``` Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36021>
This commit is contained in:
parent
4a53eca97d
commit
7dc4f28507
4 changed files with 134 additions and 0 deletions
130
src/panfrost/compiler/bi_iterator_schedule.c
Normal file
130
src/panfrost/compiler/bi_iterator_schedule.c
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Google LLC.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors (Google):
|
||||||
|
* Romaric Jodin <rjodin@google.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "util/u_dynarray.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
struct iterator {
|
||||||
|
bi_block *block;
|
||||||
|
bi_instr *instr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
phi_src_is_simple_iterator(bi_instr *phi, bi_instr *phi_src, bi_block *block)
|
||||||
|
{
|
||||||
|
if (phi_src == NULL || block == NULL || phi_src->nr_dests != 1 ||
|
||||||
|
phi_src->op == BI_OPCODE_PHI) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bi_foreach_src(phi_src, idx) {
|
||||||
|
if (bi_is_equiv(phi->dest[0], phi_src->src[idx]))
|
||||||
|
/* If phi_src uses phi, then phi_src is a simple iterator */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bi_instr *
|
||||||
|
get_new_iterator_position(bi_block *block, bi_instr *instr)
|
||||||
|
{
|
||||||
|
bi_instr *prev = NULL;
|
||||||
|
bi_foreach_instr_in_block_from(block, I, instr) {
|
||||||
|
if (bi_is_branch(I))
|
||||||
|
return prev;
|
||||||
|
bi_foreach_src(I, s) {
|
||||||
|
if (bi_is_equiv(instr->dest[0], I->src[s]))
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
prev = I;
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to move iterator as close to the end of the block as possible. The goal
|
||||||
|
* is to avoid the iterator being used after being updated, to prevent the need
|
||||||
|
* for an extra move instruction.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* 1 = PHI <>, 2
|
||||||
|
* ...
|
||||||
|
* 2 = IADD_IMM.i32 1, index:1
|
||||||
|
* 3 = ICMP_OR.u32.ge.m1 1, ...
|
||||||
|
*
|
||||||
|
* Without this pass, after register allocation it can lead to:
|
||||||
|
* r1 = IADD_IMM.i32 r0, index:1
|
||||||
|
* r2 = ICMP_OR.u32.ge.m1 r0, ...
|
||||||
|
* r0 = MOV.i32 r1
|
||||||
|
*
|
||||||
|
* With this pass, we can get:
|
||||||
|
* r1 = ICMP_OR.u32.ge.m1 r0, ...
|
||||||
|
* r0 = IADD_IMM.i32 r0, index:1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
bi_iterator_schedule(bi_context *ctx)
|
||||||
|
{
|
||||||
|
bi_instr **bi_index_to_instr = calloc(ctx->ssa_alloc, sizeof(bi_instr *));
|
||||||
|
bi_block **bi_index_to_block = calloc(ctx->ssa_alloc, sizeof(bi_block *));
|
||||||
|
bi_foreach_block(ctx, block) {
|
||||||
|
bi_foreach_instr_in_block(block, instr) {
|
||||||
|
bi_foreach_ssa_dest(instr, idx) {
|
||||||
|
uint32_t value = instr->dest[idx].value;
|
||||||
|
bi_index_to_instr[value] = instr;
|
||||||
|
bi_index_to_block[value] = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct util_dynarray iterators;
|
||||||
|
util_dynarray_init(&iterators, NULL);
|
||||||
|
bi_foreach_instr_global(ctx, phi) {
|
||||||
|
if (phi->op != BI_OPCODE_PHI || phi->nr_dests != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bi_foreach_ssa_src(phi, phi_src_idx) {
|
||||||
|
uint32_t value = phi->src[phi_src_idx].value;
|
||||||
|
struct iterator iterator = {.instr = bi_index_to_instr[value],
|
||||||
|
.block = bi_index_to_block[value]};
|
||||||
|
if (!phi_src_is_simple_iterator(phi, iterator.instr, iterator.block))
|
||||||
|
continue;
|
||||||
|
util_dynarray_append(&iterators, struct iterator, iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
util_dynarray_foreach(&iterators, struct iterator, iterator)
|
||||||
|
{
|
||||||
|
bi_instr *instr = iterator->instr;
|
||||||
|
bi_instr *prev = get_new_iterator_position(iterator->block, instr);
|
||||||
|
if (prev == NULL || prev == instr)
|
||||||
|
continue;
|
||||||
|
bi_remove_instruction(instr);
|
||||||
|
list_add(&instr->link, &prev->link);
|
||||||
|
}
|
||||||
|
util_dynarray_clear(&iterators);
|
||||||
|
|
||||||
|
free(bi_index_to_instr);
|
||||||
|
free(bi_index_to_block);
|
||||||
|
}
|
||||||
|
|
@ -6256,6 +6256,8 @@ bi_compile_variant_nir(nir_shader *nir,
|
||||||
|
|
||||||
bi_validate(ctx, "Late lowering");
|
bi_validate(ctx, "Late lowering");
|
||||||
|
|
||||||
|
bi_iterator_schedule(ctx);
|
||||||
|
|
||||||
if (likely(!(bifrost_debug & BIFROST_DBG_NOPSCHED))) {
|
if (likely(!(bifrost_debug & BIFROST_DBG_NOPSCHED))) {
|
||||||
bi_pressure_schedule(ctx);
|
bi_pressure_schedule(ctx);
|
||||||
bi_validate(ctx, "Pre-RA scheduling");
|
bi_validate(ctx, "Pre-RA scheduling");
|
||||||
|
|
|
||||||
|
|
@ -1377,6 +1377,7 @@ void va_lower_split_64bit(bi_context *ctx);
|
||||||
|
|
||||||
void bi_lower_opt_instructions(bi_context *ctx);
|
void bi_lower_opt_instructions(bi_context *ctx);
|
||||||
|
|
||||||
|
void bi_iterator_schedule(bi_context *ctx);
|
||||||
void bi_pressure_schedule(bi_context *ctx);
|
void bi_pressure_schedule(bi_context *ctx);
|
||||||
void bi_schedule(bi_context *ctx);
|
void bi_schedule(bi_context *ctx);
|
||||||
bool bi_can_fma(bi_instr *ins);
|
bool bi_can_fma(bi_instr *ins);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ libpanfrost_bifrost_files = files(
|
||||||
'bi_opt_push_ubo.c',
|
'bi_opt_push_ubo.c',
|
||||||
'bi_opt_mod_props.c',
|
'bi_opt_mod_props.c',
|
||||||
'bi_opt_dual_tex.c',
|
'bi_opt_dual_tex.c',
|
||||||
|
'bi_iterator_schedule.c',
|
||||||
'bi_pressure_schedule.c',
|
'bi_pressure_schedule.c',
|
||||||
'bi_ra.c',
|
'bi_ra.c',
|
||||||
'bi_ra_ssa.c',
|
'bi_ra_ssa.c',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue