nir: replace nir_opt_conditional_discard with nir_opt_peephole_select
Foz-DB Navi21: Totals from 118 (0.15% of 79377) affected shaders: Instrs: 208001 -> 207355 (-0.31%); split: -0.33%, +0.01% CodeSize: 1080428 -> 1078432 (-0.18%); split: -0.20%, +0.02% SpillSGPRs: 202 -> 211 (+4.46%) Latency: 1923508 -> 1919093 (-0.23%); split: -0.62%, +0.39% InvThroughput: 407475 -> 407081 (-0.10%); split: -0.12%, +0.02% SClause: 7050 -> 7033 (-0.24%); split: -0.31%, +0.07% Copies: 12156 -> 11821 (-2.76%); split: -3.04%, +0.28% PreSGPRs: 8198 -> 8331 (+1.62%); split: -0.02%, +1.65% PreVGPRs: 7628 -> 7528 (-1.31%) VALU: 155747 -> 155657 (-0.06%); split: -0.06%, +0.00% SALU: 18295 -> 17782 (-2.80%); split: -2.98%, +0.18% SMEM: 10521 -> 10519 (-0.02%) Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33590>
This commit is contained in:
@@ -208,7 +208,11 @@ radv_optimize_nir(struct nir_shader *shader, bool optimize_conservatively)
|
||||
nir_var_function_temp | nir_var_shader_in | nir_var_shader_out | nir_var_mem_shared, NULL);
|
||||
|
||||
if (shader->info.stage == MESA_SHADER_FRAGMENT && shader->info.fs.uses_discard) {
|
||||
NIR_PASS(progress, shader, nir_opt_conditional_discard);
|
||||
nir_opt_peephole_select_options peephole_select_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, shader, nir_opt_peephole_select, &peephole_select_options);
|
||||
NIR_PASS(progress, shader, nir_opt_move_discards_to_top);
|
||||
}
|
||||
|
||||
|
||||
@@ -811,7 +811,12 @@ hk_lower_nir(struct hk_device *dev, nir_shader *nir,
|
||||
NIR_PASS(_, nir, agx_nir_lower_multisampled_image_store);
|
||||
|
||||
agx_preprocess_nir(nir);
|
||||
NIR_PASS(_, nir, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_select_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(_, nir, nir_opt_peephole_select, &peephole_select_options);
|
||||
NIR_PASS(_, nir, nir_opt_if,
|
||||
nir_opt_if_optimize_phi_true_false | nir_opt_if_avoid_64bit_phis);
|
||||
}
|
||||
|
||||
@@ -2188,7 +2188,11 @@ v3d_optimize_nir(struct v3d_compile *c, struct nir_shader *s)
|
||||
NIR_PASS(progress, s, nir_opt_dce);
|
||||
}
|
||||
|
||||
NIR_PASS(progress, s, nir_opt_conditional_discard);
|
||||
peephole_select_options = (nir_opt_peephole_select_options){
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, s, nir_opt_peephole_select, &peephole_select_options);
|
||||
|
||||
NIR_PASS(progress, s, nir_opt_remove_phis);
|
||||
NIR_PASS(progress, s, nir_opt_if, false);
|
||||
|
||||
@@ -128,7 +128,12 @@ gl_nir_opts(nir_shader *nir)
|
||||
}
|
||||
|
||||
NIR_PASS(progress, nir, nir_opt_undef);
|
||||
NIR_PASS(progress, nir, nir_opt_conditional_discard);
|
||||
|
||||
peephole_select_options = (nir_opt_peephole_select_options){
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, nir, nir_opt_peephole_select, &peephole_select_options);
|
||||
if (nir->options->max_unroll_iterations ||
|
||||
(nir->options->max_unroll_iterations_fp64 &&
|
||||
(nir->options->lower_doubles_options & nir_lower_fp64_full_software))) {
|
||||
|
||||
@@ -227,7 +227,6 @@ files_libnir = files(
|
||||
'nir_opt_clip_cull_const.c',
|
||||
'nir_opt_combine_stores.c',
|
||||
'nir_opt_comparison_pre.c',
|
||||
'nir_opt_conditional_discard.c',
|
||||
'nir_opt_constant_folding.c',
|
||||
'nir_opt_copy_prop_vars.c',
|
||||
'nir_opt_copy_propagate.c',
|
||||
|
||||
@@ -6094,7 +6094,6 @@ bool nir_opt_vectorize(nir_shader *shader, nir_vectorize_cb filter,
|
||||
void *data);
|
||||
bool nir_opt_vectorize_io(nir_shader *shader, nir_variable_mode modes);
|
||||
|
||||
bool nir_opt_conditional_discard(nir_shader *shader);
|
||||
bool nir_opt_move_discards_to_top(nir_shader *shader);
|
||||
|
||||
bool nir_opt_ray_queries(nir_shader *shader);
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
|
||||
/** @file nir_opt_conditional_discard.c
|
||||
*
|
||||
* Handles optimization of lowering of
|
||||
* - if (cond) discard to discard_if(cond) and
|
||||
* - if (cond) demote to demote_if(cond)
|
||||
* - if (cond) terminate to terminate_if(cond)
|
||||
*/
|
||||
|
||||
static bool
|
||||
nir_opt_conditional_discard_block(nir_builder *b, nir_block *block)
|
||||
{
|
||||
if (nir_cf_node_is_first(&block->cf_node))
|
||||
return false;
|
||||
|
||||
nir_cf_node *prev_node = nir_cf_node_prev(&block->cf_node);
|
||||
if (prev_node->type != nir_cf_node_if)
|
||||
return false;
|
||||
|
||||
nir_if *if_stmt = nir_cf_node_as_if(prev_node);
|
||||
nir_block *then_block = nir_if_first_then_block(if_stmt);
|
||||
nir_block *else_block = nir_if_first_else_block(if_stmt);
|
||||
|
||||
/* check there is only one else block and it is empty */
|
||||
if (nir_if_last_else_block(if_stmt) != else_block)
|
||||
return false;
|
||||
if (!exec_list_is_empty(&else_block->instr_list))
|
||||
return false;
|
||||
|
||||
/* check there is only one then block and it has only one instruction in it */
|
||||
if (nir_if_last_then_block(if_stmt) != then_block)
|
||||
return false;
|
||||
if (exec_list_is_empty(&then_block->instr_list))
|
||||
return false;
|
||||
if (exec_list_length(&then_block->instr_list) > 1)
|
||||
return false;
|
||||
/*
|
||||
* make sure no subsequent phi nodes point at this if.
|
||||
*/
|
||||
nir_block *after = nir_cf_node_as_block(nir_cf_node_next(&if_stmt->cf_node));
|
||||
nir_foreach_phi_safe(phi, after) {
|
||||
nir_foreach_phi_src(phi_src, phi) {
|
||||
if (phi_src->pred == then_block ||
|
||||
phi_src->pred == else_block)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the first instruction in the then block and confirm it is
|
||||
* a discard or a demote instruction.
|
||||
*/
|
||||
nir_instr *instr = nir_block_first_instr(then_block);
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
nir_intrinsic_op op = intrin->intrinsic;
|
||||
nir_def *cond = if_stmt->condition.ssa;
|
||||
b->cursor = nir_before_cf_node(prev_node);
|
||||
|
||||
switch (intrin->intrinsic) {
|
||||
case nir_intrinsic_demote:
|
||||
op = nir_intrinsic_demote_if;
|
||||
break;
|
||||
case nir_intrinsic_terminate:
|
||||
op = nir_intrinsic_terminate_if;
|
||||
break;
|
||||
case nir_intrinsic_demote_if:
|
||||
case nir_intrinsic_terminate_if:
|
||||
cond = nir_iand(b, cond, intrin->src[0].ssa);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_intrinsic_instr *discard_if =
|
||||
nir_intrinsic_instr_create(b->shader, op);
|
||||
discard_if->src[0] = nir_src_for_ssa(cond);
|
||||
|
||||
nir_instr_insert_before_cf(prev_node, &discard_if->instr);
|
||||
nir_instr_remove(&intrin->instr);
|
||||
nir_cf_node_remove(&if_stmt->cf_node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_opt_conditional_discard(nir_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
nir_builder builder;
|
||||
|
||||
nir_foreach_function_impl(impl, shader) {
|
||||
builder = nir_builder_create(impl);
|
||||
|
||||
bool impl_progress = false;
|
||||
nir_foreach_block_safe(block, impl) {
|
||||
if (nir_opt_conditional_discard_block(&builder, block))
|
||||
impl_progress = true;
|
||||
}
|
||||
|
||||
if (impl_progress) {
|
||||
nir_metadata_preserve(impl, nir_metadata_none);
|
||||
progress = true;
|
||||
} else {
|
||||
nir_metadata_preserve(impl, nir_metadata_all);
|
||||
}
|
||||
}
|
||||
return progress;
|
||||
}
|
||||
@@ -344,8 +344,8 @@ break_all:
|
||||
return progress;
|
||||
}
|
||||
|
||||
/* This optimization only operates on discard_if/demoe_if so
|
||||
* nir_opt_conditional_discard and nir_lower_discard_or_demote
|
||||
/* This optimization only operates on terminate_if/demote_if so
|
||||
* nir_opt_peephole_select and nir_lower_discard_or_demote
|
||||
* should have been called before.
|
||||
*/
|
||||
bool
|
||||
|
||||
@@ -135,7 +135,11 @@ tu_spirv_to_nir(struct tu_device *dev,
|
||||
init_ir3_nir_options(&options, key);
|
||||
ir3_optimize_loop(dev->compiler, &options, nir);
|
||||
|
||||
NIR_PASS_V(nir, nir_opt_conditional_discard);
|
||||
nir_opt_peephole_select_options peephole_select_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS_V(nir, nir_opt_peephole_select, &peephole_select_options);
|
||||
|
||||
return nir;
|
||||
}
|
||||
|
||||
@@ -3330,7 +3330,12 @@ ntt_optimize_nir(struct nir_shader *s, struct pipe_screen *screen,
|
||||
NIR_PASS(progress, s, nir_opt_algebraic);
|
||||
NIR_PASS(progress, s, nir_opt_constant_folding);
|
||||
NIR_PASS(progress, s, nir_opt_remove_phis);
|
||||
NIR_PASS(progress, s, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, s, nir_opt_peephole_select, &peephole_discard_options);
|
||||
NIR_PASS(progress, s, nir_opt_dce);
|
||||
NIR_PASS(progress, s, nir_opt_dead_cf);
|
||||
NIR_PASS(progress, s, nir_opt_cse);
|
||||
|
||||
@@ -2454,7 +2454,12 @@ ttn_optimize_nir(nir_shader *nir)
|
||||
}
|
||||
|
||||
NIR_PASS(progress, nir, nir_opt_undef);
|
||||
NIR_PASS(progress, nir, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, nir, nir_opt_peephole_select, &peephole_discard_options);
|
||||
if (nir->options->max_unroll_iterations) {
|
||||
NIR_PASS(progress, nir, nir_opt_loop_unroll);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,12 @@ i915_optimize_nir(struct nir_shader *s)
|
||||
NIR_PASS(progress, s, nir_opt_algebraic);
|
||||
NIR_PASS(progress, s, nir_opt_constant_folding);
|
||||
NIR_PASS(progress, s, nir_opt_remove_phis);
|
||||
NIR_PASS(progress, s, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, s, nir_opt_peephole_select, &peephole_discard_options);
|
||||
NIR_PASS(progress, s, nir_opt_dce);
|
||||
NIR_PASS(progress, s, nir_opt_dead_cf);
|
||||
NIR_PASS(progress, s, nir_opt_cse);
|
||||
|
||||
@@ -179,7 +179,12 @@ r300_optimize_nir(struct nir_shader *s, struct pipe_screen *screen)
|
||||
}
|
||||
NIR_PASS(progress, s, nir_opt_constant_folding);
|
||||
NIR_PASS(progress, s, nir_opt_remove_phis);
|
||||
NIR_PASS(progress, s, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, s, nir_opt_peephole_select, &peephole_discard_options);
|
||||
NIR_PASS(progress, s, nir_opt_dce);
|
||||
NIR_PASS(progress, s, nir_opt_dead_cf);
|
||||
NIR_PASS(progress, s, nir_opt_cse);
|
||||
|
||||
@@ -646,7 +646,11 @@ optimize_once(nir_shader *shader)
|
||||
};
|
||||
NIR_PASS(progress, shader, nir_opt_peephole_select, &peephole_select_options);
|
||||
|
||||
NIR_PASS(progress, shader, nir_opt_conditional_discard);
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, shader, nir_opt_peephole_select, &peephole_discard_options);
|
||||
NIR_PASS(progress, shader, nir_opt_dce);
|
||||
NIR_PASS(progress, shader, nir_opt_undef);
|
||||
NIR_PASS(progress, shader, nir_opt_loop_unroll);
|
||||
|
||||
@@ -130,7 +130,12 @@ void si_nir_opts(struct si_screen *sscreen, struct nir_shader *nir, bool has_arr
|
||||
}
|
||||
|
||||
NIR_PASS(progress, nir, nir_opt_undef);
|
||||
NIR_PASS(progress, nir, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, nir, nir_opt_peephole_select, &peephole_discard_options);
|
||||
if (nir->options->max_unroll_iterations) {
|
||||
NIR_PASS(progress, nir, nir_opt_loop_unroll);
|
||||
}
|
||||
|
||||
@@ -256,7 +256,12 @@ optimize(nir_shader *nir)
|
||||
}
|
||||
NIR_PASS(progress, nir, nir_opt_if, nir_opt_if_optimize_phi_true_false);
|
||||
NIR_PASS(progress, nir, nir_opt_dead_cf);
|
||||
NIR_PASS(progress, nir, nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
NIR_PASS(progress, nir, nir_opt_peephole_select, &peephole_discard_options);
|
||||
NIR_PASS(progress, nir, nir_opt_remove_phis);
|
||||
NIR_PASS(progress, nir, nir_opt_cse);
|
||||
NIR_PASS(progress, nir, nir_opt_undef);
|
||||
|
||||
@@ -920,7 +920,12 @@ brw_nir_optimize(nir_shader *nir,
|
||||
LOOP_OPT(nir_opt_dce);
|
||||
}
|
||||
LOOP_OPT_NOT_IDEMPOTENT(nir_opt_if, nir_opt_if_optimize_phi_true_false);
|
||||
LOOP_OPT(nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
LOOP_OPT(nir_opt_peephole_select, &peephole_discard_options);
|
||||
if (nir->options->max_unroll_iterations != 0) {
|
||||
LOOP_OPT_NOT_IDEMPOTENT(nir_opt_loop_unroll);
|
||||
}
|
||||
|
||||
@@ -710,7 +710,12 @@ elk_nir_optimize(nir_shader *nir, bool is_scalar,
|
||||
OPT(nir_opt_dce);
|
||||
}
|
||||
OPT(nir_opt_if, nir_opt_if_optimize_phi_true_false);
|
||||
OPT(nir_opt_conditional_discard);
|
||||
|
||||
nir_opt_peephole_select_options peephole_discard_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
OPT(nir_opt_peephole_select, &peephole_discard_options);
|
||||
if (nir->options->max_unroll_iterations != 0) {
|
||||
OPT(nir_opt_loop_unroll);
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ optimize_nir(nir_shader *nir, const struct nak_compiler *nak, bool allow_copies)
|
||||
|
||||
nir_opt_peephole_select_options peephole_select_options = {
|
||||
.limit = 0,
|
||||
.discard_ok = true,
|
||||
};
|
||||
OPT(nir, nir_opt_peephole_select, &peephole_select_options);
|
||||
OPT(nir, nir_opt_intrinsics);
|
||||
@@ -163,7 +164,6 @@ optimize_nir(nir_shader *nir, const struct nak_compiler *nak, bool allow_copies)
|
||||
OPT(nir, nir_opt_dce);
|
||||
}
|
||||
OPT(nir, nir_opt_if, nir_opt_if_optimize_phi_true_false);
|
||||
OPT(nir, nir_opt_conditional_discard);
|
||||
if (nir->options->max_unroll_iterations != 0) {
|
||||
OPT(nir, nir_opt_loop_unroll);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user