glsl: Speed up constant folding for swizzles.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 12 Sep 2014 22:16:57 +0000 (15:16 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 12 Sep 2014 23:35:39 +0000 (16:35 -0700)
ir_rvalue::constant_expression_value() recursively walks down an IR
tree, attempting to reduce it to a single constant value.  This is
useful when you want to know whether a variable has a constant
expression value at all, and if so, what it is.

The constant folding optimization pass attempts to replace rvalues with
their constant expression value from the bottom up.  That way, we can
optimize subexpressions, and ideally stop as soon as we find a
non-constant subexpression.

In order to obtain the actual value of an expression, the optimization
pass calls constant_expression_value().  But it should only do so if it
knows the value can be combined into a constant.  Otherwise, at each
step of walking back up the tree, it will walk down the tree again, only
to discover what it already knew: it isn't constant.

We properly avoided this call for ir_expression nodes, but not for
ir_swizzle nodes.  This patch fixes that, drastically reducing compile
times on certain shaders where tree grafting has given us huge
expression trees.  It also fixes SuperTuxKart.

Thanks to Iago and Mike for help in tracking this down.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=78468
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Cc: mesa-stable@lists.freedesktop.org
src/glsl/opt_constant_folding.cpp

index d0e575460bdb5b0e4c7451b0e77e1cea97c067ef..74b855e5e948ebbc822d4d8b7413dde21517aa32 100644 (file)
@@ -79,6 +79,11 @@ ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue)
       }
    }
 
+   /* Ditto for swizzles. */
+   ir_swizzle *swiz = (*rvalue)->as_swizzle();
+   if (swiz && !swiz->val->as_constant())
+      return;
+
    ir_constant *constant = (*rvalue)->constant_expression_value();
    if (constant) {
       *rvalue = constant;