nir/loop_analyze: determine whether all control flow gets eliminated upon loop unrolling
Totals from 17 (0.02% of 79839) affected shaders: (Navi48) MaxWaves: 241 -> 243 (+0.83%); split: +5.81%, -4.98% Instrs: 44198 -> 43786 (-0.93%); split: -8.19%, +7.26% CodeSize: 230284 -> 226900 (-1.47%); split: -10.55%, +9.08% VGPRs: 2152 -> 2524 (+17.29%); split: -3.90%, +21.19% Scratch: 718848 -> 0 (-inf%) Latency: 128977 -> 145720 (+12.98%); split: -2.12%, +15.10% InvThroughput: 206804 -> 254250 (+22.94%); split: -0.32%, +23.27% VClause: 1296 -> 1309 (+1.00%); split: -28.09%, +29.09% SClause: 835 -> 833 (-0.24%) Copies: 6284 -> 3630 (-42.23%); split: -44.51%, +2.28% Branches: 1003 -> 961 (-4.19%) PreSGPRs: 1003 -> 996 (-0.70%); split: -1.20%, +0.50% PreVGPRs: 1510 -> 2130 (+41.06%) VALU: 23577 -> 24309 (+3.10%); split: -6.26%, +9.37% SALU: 5875 -> 5688 (-3.18%); split: -6.26%, +3.08% VMEM: 3679 -> 3001 (-18.43%); split: -33.27%, +14.84% SMEM: 1632 -> 1631 (-0.06%) VOPD: 23 -> 24 (+4.35%) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38659>
This commit is contained in:
parent
4997d8fb1b
commit
598928d7e7
3 changed files with 17 additions and 0 deletions
|
|
@ -3444,6 +3444,9 @@ typedef struct nir_loop_info {
|
|||
/* Unroll the loop regardless of its size */
|
||||
bool force_unroll;
|
||||
|
||||
/* Whether all control flow gets eliminated upon unrolling. */
|
||||
bool flattens_all_control_flow;
|
||||
|
||||
/* Does the loop contain complex loop terminators, continues or other
|
||||
* complex behaviours? If this is true we can't rely on
|
||||
* loop_terminator_list to be complete or accurate.
|
||||
|
|
|
|||
|
|
@ -1405,6 +1405,8 @@ gather_constant_fold_info(loop_info_state *state, nir_instr *instr)
|
|||
static void
|
||||
gather_unroll_heuristic_info(loop_info_state *state, const nir_shader_compiler_options *options)
|
||||
{
|
||||
state->loop->info->flattens_all_control_flow = state->loop->info->exact_trip_count_known;
|
||||
|
||||
nir_foreach_block_in_cf_node(block, &state->loop->cf_node) {
|
||||
/* Calculate instruction cost. */
|
||||
nir_foreach_instr(instr, block) {
|
||||
|
|
@ -1412,6 +1414,15 @@ gather_unroll_heuristic_info(loop_info_state *state, const nir_shader_compiler_o
|
|||
state->loop->info->instr_cost += instr_cost(state, instr, options);
|
||||
}
|
||||
|
||||
nir_if *nif = nir_block_get_following_if(block);
|
||||
if (nif) {
|
||||
/* If all IF statements can be constant-folded after unrolling,
|
||||
* the loop becomes a single large basic block.
|
||||
*/
|
||||
state->loop->info->flattens_all_control_flow &=
|
||||
is_const_after_unrolling(state, nif->condition.ssa);
|
||||
}
|
||||
|
||||
if (state->loop->info->force_unroll)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -905,6 +905,9 @@ check_unrolling_restrictions(nir_shader *shader, nir_loop *loop)
|
|||
/* Unroll much more aggressively if it can hide load latency. */
|
||||
if (shader->options->max_unroll_iterations_aggressive && can_pipeline_loads(loop))
|
||||
max_iter = shader->options->max_unroll_iterations_aggressive;
|
||||
/* Unroll much more aggressively if all control flow gets eliminated. */
|
||||
if (shader->options->max_unroll_iterations_aggressive && li->flattens_all_control_flow)
|
||||
max_iter = shader->options->max_unroll_iterations_aggressive;
|
||||
/* Tune differently if the loop has double ops and soft fp64 is in use */
|
||||
else if (shader->options->max_unroll_iterations_fp64 && loop->info->has_soft_fp64)
|
||||
max_iter = shader->options->max_unroll_iterations_fp64;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue