aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_search_helpers.h
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2018-05-22 18:19:16 -0700
committerIan Romanick <[email protected]>2019-03-28 15:35:53 -0700
commit2cf59861a8128a91bfdd6fe62bf69cb4593373e3 (patch)
tree33daec3329c0ccb028e108649ffbdc6dc5881879 /src/compiler/nir/nir_search_helpers.h
parentc6ee46a7532291fc8583400e174e77b1833daf23 (diff)
nir: Add partial redundancy elimination for compares
This pass attempts to dectect code sequences like if (x < y) { z = y - x; ... } and replace them with sequences like t = x - y; if (t < 0) { z = -t; ... } On architectures where the subtract can generate the flags used by the if-statement, this saves an instruction. It's also possible that moving an instruction out of the if-statement will allow nir_opt_peephole_select to convert the whole thing to a bcsel. Currently only floating point compares and adds are supported. Adding support for integer will be a challenge due to integer overflow. There are a couple possible solutions, but they may not apply to all architectures. v2: Fix a typo in the commit message and a couple typos in comments. Fix possible NULL pointer deref from result of push_block(). Add missing (-A + B) case. Suggested by Caio. v3: Fix is_not_const_zero to work correctly with types other than nir_type_float32. Suggested by Ken. v4: Add some comments explaining how this works. Suggested by Ken. Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/compiler/nir/nir_search_helpers.h')
-rw-r--r--src/compiler/nir/nir_search_helpers.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h
index 456de81e175..1624508993d 100644
--- a/src/compiler/nir/nir_search_helpers.h
+++ b/src/compiler/nir/nir_search_helpers.h
@@ -110,6 +110,33 @@ is_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components,
}
static inline bool
+is_not_const_zero(nir_alu_instr *instr, unsigned src, unsigned num_components,
+ const uint8_t *swizzle)
+{
+ if (nir_src_as_const_value(instr->src[src].src) == NULL)
+ return true;
+
+ for (unsigned i = 0; i < num_components; i++) {
+ switch (nir_op_infos[instr->op].input_types[src]) {
+ case nir_type_float:
+ if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
+ return false;
+ break;
+ case nir_type_bool:
+ case nir_type_int:
+ case nir_type_uint:
+ if (nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) == 0)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static inline bool
is_not_const(nir_alu_instr *instr, unsigned src, UNUSED unsigned num_components,
UNUSED const uint8_t *swizzle)
{