glsl: Optimize min/max expression trees

Graphics / Mesa 3D Graphics Library / Mesa - Iago Toral Quiroga [igalia.com] - 7 October 2014 05:37 UTC

Original patch by Petri Latvala:

Add an optimization pass that drops min/max expression operands that can be proven to not contribute to the final result. The algorithm is similar to alpha-beta pruning on a minmax search, from the field of AI.

This optimization pass can optimize min/max expressions where operands are min/max expressions. Such code can appear in shaders by itself, or as the result of clamp() or AMD_shader_trinary_minmax functions.

This optimization pass improves the generated code for piglit's AMD_shader_trinary_minmax tests as follows:

total instructions in shared programs: 75 -> 67 (-10.67%) instructions in affected programs: 60 -> 52 (-13.33%) GAINED: 0 LOST: 0

All tests (max3, min3, mid3) improved.

A full shader-db run:

total instructions in shared programs: 4293603 -> 4293575 (-0.00%) instructions in affected programs: 1188 -> 1160 (-2.36%) GAINED: 0 LOST: 0

Improvements happen in Guacamelee and Serious Sam 3. One shader from Dungeon Defenders is hurt by shader-db metrics (26 -> 28), because of dropping of a (constant float (0.00000)) operand, which was compiled to a saturate modifier.

Version 2 by Iago Toral Quiroga:

Changes from review feedback:
- Squashed various cosmetic changes sent by Matt Turner.
- Make less_all_components return an enum rather than setting a class member. (Suggested by Mat Turner). Also, renamed it to compare_components.
- Make less_all_components, smaller_constant and larger_constant static. (Suggested by Mat Turner)- Change mixmax_range to call its limits "low" and "high" instead of "range[0]" and "range[1]". (Suggested by Connor Abbot).- Use ir_builder swizzle helpers in swizzle_if_required(). (Suggested by Connor Abbot).
- Make the logic more clearer by rearrenging the code and commenting. (Suggested by Connor Abbot).- Added comment to explain why we need to recurse twice. (Suggested by Connor Abbot).- If we cannot prune an expression, do not return early. Instead, attempt to prune its children. (Suggested by Connor Abbot).

Other changes:- Instead of having a global "valid" visitor member, let the various functions that can determine this status return a boolean and check for its value to decide what to do in each case. This is more flexible and allows to recurse into children of parents that could not be prunned due to invalid ranges (so related to the last bullet in the review feedback).- Make sure we always check if a range is valid before working with it. Since any use of get_range, combine_range or range_intersection can invalidate a range we should check for this situation every time we use any of these functions.

Version 3 by Iago Toral Quiroga:

Changes from review feedback:- Now we can make get_range, combine_range and range_intersection static too (suggested by Connor Abbot).- Do not return NULL when looking for the larger or greater constant into mixed vector constants. Instead, produce a new constant by doing a component-wise minmax. With this we can also remove of the validations when we call into these functions (suggested by Connor Abbot).- Add a comment explaining the meaning of the baserange argument in prune_expression (suggested by Connor Abbot).

Other changes:- Eliminate minmax expressions operating on constant vectors with mixed values by resolving them.

No piglit regressions observed with Version 3.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76861

fd31628 glsl: Optimize min/max expression trees
src/glsl/Makefile.sources | 1 +
src/glsl/glsl_parser_extras.cpp | 1 +
src/glsl/ir_optimization.h | 1 +
src/glsl/opt_minmax.cpp | 475 +++++++++++++++++++++++++++++++++++++++
4 files changed, 478 insertions(+)

Upstream: cgit.freedesktop.org


  • Share