mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 09:18:04 +02:00
nir/opt_loop: Don't peel initial break from do-while loops
As the main purpose of this optimization is to transform while- into do-while loops, don't apply on loops which are already in do-while form. Also set nir_loop::do_while after this transformation, so that it is only applied once. Totals from 576 (0.28% of 202440) affected shaders: (Navi48) Instrs: 1337529 -> 1253438 (-6.29%); split: -6.36%, +0.07% CodeSize: 8390852 -> 7837328 (-6.60%); split: -6.61%, +0.01% VGPRs: 50856 -> 50844 (-0.02%) SpillSGPRs: 42198 -> 35395 (-16.12%); split: -16.13%, +0.01% SpillVGPRs: 47608 -> 44620 (-6.28%) Latency: 31043828 -> 44143753 (+42.20%); split: -0.06%, +42.26% InvThroughput: 6973433 -> 10079000 (+44.53%); split: -0.08%, +44.61% VClause: 26839 -> 24718 (-7.90%); split: -7.91%, +0.00% SClause: 21831 -> 21583 (-1.14%); split: -1.52%, +0.38% Copies: 183503 -> 150040 (-18.24%); split: -18.84%, +0.61% Branches: 27738 -> 26848 (-3.21%); split: -5.12%, +1.91% PreSGPRs: 40233 -> 39083 (-2.86%); split: -2.88%, +0.02% PreVGPRs: 38745 -> 38903 (+0.41%); split: -0.02%, +0.43% VALU: 688396 -> 645948 (-6.17%); split: -6.17%, +0.01% SALU: 189792 -> 177642 (-6.40%); split: -6.97%, +0.57% VMEM: 121500 -> 112748 (-7.20%) SMEM: 38765 -> 37767 (-2.57%); split: -2.58%, +0.00% VOPD: 102488 -> 89071 (-13.09%); split: +0.24%, -13.33% Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40349>
This commit is contained in:
parent
a9a2edfbb6
commit
1f9a0490c6
2 changed files with 35 additions and 14 deletions
|
|
@ -339,6 +339,37 @@ has_phi_with_constant_src(nir_block *block, nir_block *pred)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* For now, we restrict this optimization to cases where the outer IF
|
||||
* can be constant-folded or where at least one phi at the loop-header
|
||||
* has a constant loop-carried source. If it can be constant-folded,
|
||||
* we additionally require that there is actual work to be done after
|
||||
* the initial break. This is to avoid unconditionally unrolling long
|
||||
* loops.
|
||||
*
|
||||
* Note: If this restriction is lifted, it might recurse infinitely.
|
||||
* Prevent by e.g. restricting to single-exit loops.
|
||||
*/
|
||||
static bool
|
||||
should_peel_initial_break(nir_loop *loop)
|
||||
{
|
||||
nir_block *header_block = nir_loop_first_block(loop);
|
||||
nir_cf_node *if_node = nir_cf_node_next(&header_block->cf_node);
|
||||
nir_if *nif = nir_cf_node_as_if(if_node);
|
||||
|
||||
/* This loop is already in do-while form. */
|
||||
if (loop->do_while)
|
||||
return false;
|
||||
|
||||
/* If there is a phi with a constant loop-carried value, we can remove
|
||||
* the phi by peeling one iteration.
|
||||
*/
|
||||
if (has_phi_with_constant_src(header_block, nir_loop_last_block(loop)))
|
||||
return true;
|
||||
|
||||
return nir_block_contains_work(nir_cf_node_cf_tree_next(if_node)) &&
|
||||
can_constant_fold(nir_get_scalar(nif->condition.ssa, 0), header_block);
|
||||
}
|
||||
|
||||
/**
|
||||
* This optimization tries to peel the first loop break.
|
||||
*
|
||||
|
|
@ -399,19 +430,7 @@ opt_loop_peel_initial_break(nir_loop *loop)
|
|||
if (nir_block_ends_in_jump(nir_loop_last_block(loop)))
|
||||
return false;
|
||||
|
||||
/* For now, we restrict this optimization to cases where the outer IF
|
||||
* can be constant-folded or where at least one phi at the loop-header
|
||||
* has a constant loop-carried source. If it can be constant-folded,
|
||||
* we additionally require that there is actual work to be done after
|
||||
* the initial break. This is to avoid unconditionally unrolling long
|
||||
* loops.
|
||||
*
|
||||
* Note: If this restriction is lifted, it might recurse infinitely.
|
||||
* Prevent by e.g. restricting to single-exit loops.
|
||||
*/
|
||||
if (!has_phi_with_constant_src(header_block, nir_loop_last_block(loop)) &&
|
||||
(!nir_block_contains_work(nir_cf_node_cf_tree_next(if_node)) ||
|
||||
!can_constant_fold(nir_get_scalar(nif->condition.ssa, 0), header_block)))
|
||||
if (!should_peel_initial_break(loop))
|
||||
return false;
|
||||
|
||||
/* Even though this if statement has a jump on one side, we may still have
|
||||
|
|
@ -456,6 +475,9 @@ opt_loop_peel_initial_break(nir_loop *loop)
|
|||
nir_after_cf_node(&loop->cf_node));
|
||||
nir_cf_reinsert(&tmp, nir_after_block(nir_if_first_else_block(nif)));
|
||||
|
||||
/* This loop is now in do-while form. */
|
||||
loop->do_while = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ spec@glsl-1.50@execution@primitive-id-no-gs-quad-strip,Fail
|
|||
spec@glsl-1.50@execution@primitive-id-no-gs-quads,Fail
|
||||
spec@glsl-1.50@execution@primitive-id-no-gs-point,Fail
|
||||
spec@glsl-1.50@execution@variable-indexing@gs-output-array-vec4-index-wr,Crash
|
||||
shaders@ssa@fs-if-def-else-break,Fail
|
||||
|
||||
# These tests use a TCS output variable only as temporary storage. Since the output
|
||||
# is unused by the TES, we remove it.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue