mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
nir/opt_if: optimize phis between similar IFs
This small optimization targets phis between two IF statements with the same condition. If the phi dst is only used on one branch leg, the 'unused' phi source gets replaced with undef. Totals from 1773 (2.23% of 79395) affected shaders: (Navi31) Instrs: 6546338 -> 6539039 (-0.11%); split: -0.11%, +0.00% CodeSize: 34819124 -> 34780660 (-0.11%); split: -0.11%, +0.00% VGPRs: 92100 -> 92052 (-0.05%); split: -0.07%, +0.01% SpillVGPRs: 2211 -> 2206 (-0.23%) Latency: 51621404 -> 51620966 (-0.00%); split: -0.03%, +0.03% InvThroughput: 7907110 -> 7905382 (-0.02%); split: -0.05%, +0.03% VClause: 159268 -> 159273 (+0.00%); split: -0.00%, +0.01% SClause: 180166 -> 180155 (-0.01%) Copies: 559867 -> 553966 (-1.05%); split: -1.07%, +0.01% Branches: 237327 -> 236366 (-0.40%); split: -0.41%, +0.00% PreSGPRs: 81128 -> 81116 (-0.01%); split: -0.02%, +0.01% PreVGPRs: 74264 -> 74245 (-0.03%) VALU: 3547408 -> 3541257 (-0.17%); split: -0.18%, +0.00% SALU: 824426 -> 824104 (-0.04%); split: -0.04%, +0.00% VMEM: 265009 -> 265003 (-0.00%) SMEM: 235766 -> 235760 (-0.00%) VOPD: 1853 -> 1839 (-0.76%) Reviewed-by: Georg Lehmann <dadschoorse@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7710>
This commit is contained in:
parent
50d416fe89
commit
37881801c1
1 changed files with 64 additions and 0 deletions
|
|
@ -1123,6 +1123,69 @@ simple_merge_if(nir_if *dest_if, nir_if *src_if, bool dest_if_then,
|
|||
nir_cf_reinsert(&if_cf_list, nir_after_block(dest_blk));
|
||||
}
|
||||
|
||||
static bool
|
||||
opt_phi_src_unused(nir_builder *b, nir_phi_instr *phi,
|
||||
nir_if *prev_if, nir_if *next_if)
|
||||
{
|
||||
/* Return early, if either of the sources is already undef. */
|
||||
nir_foreach_phi_src(phi_src, phi) {
|
||||
if (phi_src->src.ssa->parent_instr->type == nir_instr_type_undef)
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_block *first_then = nir_if_first_then_block(next_if);
|
||||
nir_block *first_else = nir_if_first_else_block(next_if);
|
||||
bool then_used = false;
|
||||
bool else_used = false;
|
||||
|
||||
nir_foreach_use_including_if(use, &phi->def) {
|
||||
nir_block *use_block = nir_src_get_block(use);
|
||||
|
||||
/* Check whether the if_use is on the then- or else- side. */
|
||||
if (nir_block_dominates(first_then, use_block))
|
||||
then_used = true;
|
||||
else if (nir_block_dominates(first_else, use_block))
|
||||
else_used = true;
|
||||
else
|
||||
return false;
|
||||
if (then_used && else_used)
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_block *unused_blk = then_used ? nir_if_last_else_block(prev_if)
|
||||
: nir_if_last_then_block(prev_if);
|
||||
nir_src *unused_src = &nir_phi_get_src_from_block(phi, unused_blk)->src;
|
||||
|
||||
/* Create undef and replace phi-src. */
|
||||
b->cursor = nir_before_cf_node(&prev_if->cf_node);
|
||||
nir_def *undef = nir_undef(b, phi->def.num_components, phi->def.bit_size);
|
||||
nir_src_rewrite(unused_src, undef);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This small optimization targets phis between two IF statements with
|
||||
* the same condition. If the phi dst is only used in one branch leg,
|
||||
* the 'unused' phi source gets replaced with undef.
|
||||
*/
|
||||
static bool
|
||||
opt_if_phi_src_unused(nir_builder *b, nir_if *nif)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
nir_block *next_blk = nir_cf_node_cf_tree_next(&nif->cf_node);
|
||||
nir_if *next_if = nir_block_get_following_if(next_blk);
|
||||
if (!next_if || !nir_srcs_equal(nif->condition, next_if->condition))
|
||||
return false;
|
||||
|
||||
nir_foreach_phi(phi, next_blk) {
|
||||
progress |= opt_phi_src_unused(b, phi, nif, next_if);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool
|
||||
opt_if_merge(nir_if *nif)
|
||||
{
|
||||
|
|
@ -1304,6 +1367,7 @@ opt_if_safe_cf_list(nir_builder *b, struct exec_list *cf_list, nir_opt_if_option
|
|||
progress |= opt_if_evaluate_condition_use(b, nif);
|
||||
nir_scalar cond = nir_scalar_resolved(nif->condition.ssa, 0);
|
||||
progress |= opt_if_rewrite_uniform_uses(b, nif, cond, true);
|
||||
progress |= opt_if_phi_src_unused(b, nif);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue