diff options
-rw-r--r-- | src/compiler/nir/nir_opt_algebraic.py | 8 | ||||
-rw-r--r-- | src/compiler/nir/nir_search_helpers.h | 12 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index bd65eff8b59..974345a17e5 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -343,8 +343,14 @@ optimizations = [ (('fmul', ('fneg', a), b), ('fneg', ('fmul', a, b))), (('imul', ('ineg', a), b), ('ineg', ('imul', a, b))), + # Propagate constants up multiplication chains + (('~fmul(is_used_once)', ('fmul(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c'), ('fmul', ('fmul', a, c), b)), + (('imul(is_used_once)', ('imul(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c'), ('imul', ('imul', a, c), b)), + (('~fadd(is_used_once)', ('fadd(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c'), ('fadd', ('fadd', a, c), b)), + (('iadd(is_used_once)', ('iadd(is_used_once)', 'a(is_not_const)', 'b(is_not_const)'), '#c'), ('iadd', ('iadd', a, c), b)), + # Reassociate constants in add/mul chains so they can be folded together. - # For now, we only handle cases where the constants are separated by + # For now, we mostly only handle cases where the constants are separated by # a single non-constant. We could do better eventually. (('~fmul', '#a', ('fmul', b, '#c')), ('fmul', ('fmul', a, c), b)), (('imul', '#a', ('imul', b, '#c')), ('imul', ('imul', a, c), b)), diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h index 7decf6582a7..200f2471f84 100644 --- a/src/compiler/nir/nir_search_helpers.h +++ b/src/compiler/nir/nir_search_helpers.h @@ -115,6 +115,18 @@ is_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components, } static inline bool +is_not_const(nir_alu_instr *instr, unsigned src, unsigned num_components, + const uint8_t *swizzle) +{ + nir_const_value *val = nir_src_as_const_value(instr->src[src].src); + + if (val) + return false; + + return true; +} + +static inline bool is_used_more_than_once(nir_alu_instr *instr) { bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses); |