From 4bba280937aa62244bf242034a6cdfd01667d3c1 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 12 Nov 2018 09:17:34 +0100 Subject: [PATCH] nir: Allow to skip integer ops in nir_lower_to_source_mods Some hardware supports source mods only for float operations. Make it possible to skip lowering to source mods in these cases. v2: use option flags instead of a boolean (Jason Ekstrand) Signed-off-by: Gert Wollny Reviewed-by: Jason Ekstrand --- src/compiler/nir/nir.h | 10 ++- src/compiler/nir/nir_lower_to_source_mods.c | 78 +++++++++++++-------- src/intel/compiler/brw_nir.c | 2 +- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index c469e111b2c..e542e08759d 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3017,7 +3017,15 @@ typedef struct nir_lower_bitmap_options { void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options); bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset); -bool nir_lower_to_source_mods(nir_shader *shader); + +typedef enum { + nir_lower_int_source_mods = 1 << 0, + nir_lower_float_source_mods = 1 << 1, + nir_lower_all_source_mods = (1 << 2) - 1 +} nir_lower_to_source_mods_flags; + + +bool nir_lower_to_source_mods(nir_shader *shader, nir_lower_to_source_mods_flags options); bool nir_lower_gs_intrinsics(nir_shader *shader); diff --git a/src/compiler/nir/nir_lower_to_source_mods.c b/src/compiler/nir/nir_lower_to_source_mods.c index 077ca53704f..657bf8a3d71 100644 --- a/src/compiler/nir/nir_lower_to_source_mods.c +++ b/src/compiler/nir/nir_lower_to_source_mods.c @@ -34,7 +34,8 @@ */ static bool -nir_lower_to_source_mods_block(nir_block *block) +nir_lower_to_source_mods_block(nir_block *block, + nir_lower_to_source_mods_flags options) { bool progress = false; @@ -58,10 +59,14 @@ nir_lower_to_source_mods_block(nir_block *block) switch (nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[i])) { case nir_type_float: + if (!(options & nir_lower_float_source_mods)) + continue; if (parent->op != nir_op_fmov) continue; break; case nir_type_int: + if (!(options & nir_lower_int_source_mods)) + continue; if (parent->op != nir_op_imov) continue; break; @@ -97,33 +102,41 @@ nir_lower_to_source_mods_block(nir_block *block) progress = true; } - switch (alu->op) { - case nir_op_fsat: - alu->op = nir_op_fmov; - alu->dest.saturate = true; - break; - case nir_op_ineg: - alu->op = nir_op_imov; - alu->src[0].negate = !alu->src[0].negate; - break; - case nir_op_fneg: - alu->op = nir_op_fmov; - alu->src[0].negate = !alu->src[0].negate; - break; - case nir_op_iabs: - alu->op = nir_op_imov; - alu->src[0].abs = true; - alu->src[0].negate = false; - break; - case nir_op_fabs: - alu->op = nir_op_fmov; - alu->src[0].abs = true; - alu->src[0].negate = false; - break; - default: - break; + if (options & nir_lower_float_source_mods) { + switch (alu->op) { + case nir_op_fsat: + alu->op = nir_op_fmov; + alu->dest.saturate = true; + break; + case nir_op_fneg: + alu->op = nir_op_fmov; + alu->src[0].negate = !alu->src[0].negate; + break; + case nir_op_fabs: + alu->op = nir_op_fmov; + alu->src[0].abs = true; + alu->src[0].negate = false; + break; + default: + break; + } } + if (options & nir_lower_int_source_mods) { + switch (alu->op) { + case nir_op_ineg: + alu->op = nir_op_imov; + alu->src[0].negate = !alu->src[0].negate; + break; + case nir_op_iabs: + alu->op = nir_op_imov; + alu->src[0].abs = true; + alu->src[0].negate = false; + break; + default: + break; + } + } /* We've covered sources. Now we're going to try and saturate the * destination if we can. */ @@ -136,6 +149,9 @@ nir_lower_to_source_mods_block(nir_block *block) nir_type_float) continue; + if (!(options & nir_lower_float_source_mods)) + continue; + if (!list_empty(&alu->dest.dest.ssa.if_uses)) continue; @@ -185,12 +201,13 @@ nir_lower_to_source_mods_block(nir_block *block) } static bool -nir_lower_to_source_mods_impl(nir_function_impl *impl) +nir_lower_to_source_mods_impl(nir_function_impl *impl, + nir_lower_to_source_mods_flags options) { bool progress = false; nir_foreach_block(block, impl) { - progress |= nir_lower_to_source_mods_block(block); + progress |= nir_lower_to_source_mods_block(block, options); } if (progress) @@ -201,13 +218,14 @@ nir_lower_to_source_mods_impl(nir_function_impl *impl) } bool -nir_lower_to_source_mods(nir_shader *shader) +nir_lower_to_source_mods(nir_shader *shader, + nir_lower_to_source_mods_flags options) { bool progress = false; nir_foreach_function(function, shader) { if (function->impl) { - progress |= nir_lower_to_source_mods_impl(function->impl); + progress |= nir_lower_to_source_mods_impl(function->impl, options); } } diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c index 80fa5a1a81f..10b03ef2fba 100644 --- a/src/intel/compiler/brw_nir.c +++ b/src/intel/compiler/brw_nir.c @@ -796,7 +796,7 @@ brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler, OPT(nir_opt_algebraic_late); - OPT(nir_lower_to_source_mods); + OPT(nir_lower_to_source_mods, nir_lower_all_source_mods); OPT(nir_copy_prop); OPT(nir_opt_dce); OPT(nir_opt_move_comparisons); -- 2.30.2