[Mesa-dev] [PATCH 2/5] nir: shuffle constants to the top
Jason Ekstrand
jason at jlekstrand.net
Thu Jan 19 01:22:08 UTC 2017
On Tue, Jan 17, 2017 at 6:12 PM, Timothy Arceri <
timothy.arceri at 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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170118/226a766f/attachment.html>
More information about the mesa-dev
mailing list