Previously each time we saw a variable we just created a duplicate
entry in the list. This is particularly bad for loops were we add
everything twice, and then throw nested loops into the mix and the
list was growing expoentially.
This stops the glsl-vs-unroll-explosion test which has 16 nested
loops from reaching the tests mem usage limit in this pass. The
test now hits the mem limit in opt_copy_propagation_elements()
instead.
I suspect this was also part of the reason this pass can be so
slow with some shaders.
Reviewed-by: Thomas Helland <thomashelland90@gmail.com>
A number of games have large arrays of constants, which we promote to
uniforms. This introduces copies from the uniform array to the original
temporary array. Normally, copy propagation eliminates those copies,
making everything refer to the uniform array directly.
A number of shaders in "Deus Ex: Mankind Divided" recently exposed a
limitation of copy propagation - if we had any intrinsics (i.e. image
access in a compute shader), we weren't able to get rid of these copies.
That meant that any variable indexing remained on the temporary array
rather being moved to the uniform array. i965's scalar backend
currently doesn't support indirect addressing of temporary arrays,
which meant lowering it to if-ladders. This was horrible.
According to Marek, on radeonsi/GCN, "F1 2015" uses 64% less
spilled-temp-array memory.
On i965/Skylake:
total instructions in shared programs: 13362954 -> 13329878 (-0.25%)
instructions in affected programs: 43745 -> 10669 (-75.61%)
helped: 12
HURT: 0
total cycles in shared programs: 248081010 -> 245949178 (-0.86%)
cycles in affected programs: 4597930 -> 2466098 (-46.37%)
helped: 12
HURT: 0
total spills in shared programs: 9493 -> 9507 (0.15%)
spills in affected programs: 25 -> 39 (56.00%)
helped: 0
HURT: 1
total fills in shared programs: 12127 -> 12197 (0.58%)
fills in affected programs: 110 -> 180 (63.64%)
helped: 0
HURT: 1
Helps Deus Ex: Mankind Divided. The one shader with hurt spills/fills
is from Tomb Raider at Ultra settings, but that same shader has a
-39.55% reduction in instructions and -14.09% reduction in cycle counts,
so it seems like a win there as well.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
This change makes copy propagation pass faster. Complete link time
spent in test case attached to bug 94477 goes down to ~400 secs from
over 500 secs on my HSW machine. Does not fix the actual issue but
brings down the total. No regressions seen in CI.
v2: do not leak hash_table structure
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
We've had a FINISHME here since Eric originally wrote the code in 2010.
This patch implements his suggested approach, which makes us actually
able to copy propagate into the loops, at the unfortunate cost of making
this pass even more expensive.
The shader-db statistics are not terribly impressive:
total instructions in shared programs: 9008589 -> 9008613 (0.00%)
instructions in affected programs: 4293 -> 4317 (0.56%)
helped: 0
HURT: 10
total cycles in shared programs: 78550978 -> 78575760 (0.03%)
cycles in affected programs: 655426 -> 680208 (3.78%)
helped: 75
HURT: 88
GAINED: 2
Most of the "regressions" appear to be us successfully copy propagating
uniforms, which i965 is loading as pull constants instead of push, so we
occasionally have two pulls instead of one. That doesn't seem like this
pass's job - it's propagating correctly, and we should be smarter about
pull loads in the backend.
This patch is also useful for a couple of reasons:
1. It can clean up copies created by varying packing (previously, we
couldn't if the uses were inside a loop).
This fixes a bug when interpolateAt*() is used on a packed varying
inside a loop: glsl_to_nir struggles to see through the extra copy
and mistakenly believed the variable was not an input.
2. It will help propagate uniform array access created by
lower_const_array_to_uniforms().
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
This is kind of a hack. We currently track precise requirements
by decorating ir_variables. Propagating or grafting the RHS of an
assignment to a precise value into some other expression tree can
lose those decorations.
In the long run, it might be better to replace these ir_variable
decorations with an "exact" decoration on ir_expression nodes,
similar to what NIR does.
In the short run, this is probably good enough. It preserves
enough information for glsl_to_nir to generate "exact" decorations,
and NIR will then handle optimizing these expressions reasonably.
Fixes ES31-CTS.gpu_shader5.precise_qualifier.
v2: Drop invariant handling, as it shouldn't be necessary (caught
by Jason Ekstrand).
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>