On Tue, Jan 17, 2017 at 6:12 PM, Timothy Arceri < timothy.arc...@collabora.com> wrote:
> If one of the inputs to and mul/add is the result of an another > mul/add there is a chance that we can reuse the result of that > mul/add in other calls if we do the multiplication in the right > order. > > Also by attempting to move all constants to the top we increase > the chance of constant folding. > > For example it is a fairly common pattern for shaders to do something > similar to this: > > const float a = 0.5; > in vec4 b; > in float c; > > ... > > b.x = b.x * c; > b.y = b.y * c; > > ... > > b.x = b.x * a + a; > b.y = b.y * a + a; > > So by simply detecting that constant a is part of the multiplication > in ffma and switching it with previous fmul that updates b we end up > with: > > ... > > c = a * c; > > ... > > b.x = b.x * c + a; > b.y = b.y * c + a; > > Shader-db results BDW: > > total instructions in shared programs: 13007456 -> 12964294 (-0.33%) > instructions in affected programs: 4117749 -> 4074587 (-1.05%) > helped: 17740 > HURT: 1342 > > total cycles in shared programs: 246765094 -> 246454280 (-0.13%) > cycles in affected programs: 167300168 -> 166989354 (-0.19%) > helped: 18541 > HURT: 7955 > > total spills in shared programs: 14937 -> 14560 (-2.52%) > spills in affected programs: 9331 -> 8954 (-4.04%) > helped: 284 > HURT: 33 > > total fills in shared programs: 20211 -> 19671 (-2.67%) > fills in affected programs: 12586 -> 12046 (-4.29%) > helped: 286 > HURT: 33 > > LOST: 40 > GAINED: 34 > > Some of the hurt will go away when we shuffle things back down to the > bottom in the following patch. It's also noteworthy that almost all of the > spill changes as in Deus Ex both hurt and helped. > --- > src/compiler/nir/nir_opt_algebraic.py | 8 +++++++- > src/compiler/nir/nir_search_helpers.h | 12 ++++++++++++ > 2 files changed, 19 insertions(+), 1 deletion(-) > > diff --git a/src/compiler/nir/nir_opt_algebraic.py > b/src/compiler/nir/nir_opt_algebraic.py > index 2c8ad64..797fc4b 100644 > --- a/src/compiler/nir/nir_opt_algebraic.py > +++ b/src/compiler/nir/nir_opt_algebraic.py > @@ -326,8 +326,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)), > This needs to be tagged as an inexact optimization. Do so by prefixing the first fmul with "~" > + (('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)), > Same here. That will fix your dEQP and CTS regressions. :-) > + (('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 05bd317..09ae137 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); > -- > 2.9.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev