[Mesa-dev] [PATCH 5/5] glsl: Don't do constant propagation in opt_constant_folding.

Kenneth Graunke kenneth at whitecape.org
Mon May 9 06:50:14 UTC 2016


opt_constant_folding is supposed to fold trees of constants into a
single constant.  Surprisingly, it was also propagating constant values
from variables into expression trees - even when the result couldn't be
folded together.  This is opt_constant_propagation's job.

The ir_dereference_variable::constant_expression_value() method returns
a clone of var->constant_value.  So we would replace the dereference
with a constant, propagating it into the tree.

Skip over ir_dereference_variable to avoid this surprising behavior.
However, add code to explicitly continue doing it in the constant
propagation pass, as it's useful to do so.

shader-db statistics on Broadwell:

total instructions in shared programs: 8905349 -> 8905126 (-0.00%)
instructions in affected programs: 30100 -> 29877 (-0.74%)
helped: 93
HURT: 20

total cycles in shared programs: 71017030 -> 71015944 (-0.00%)
cycles in affected programs: 132456 -> 131370 (-0.82%)
helped: 54
HURT: 45

The only hurt programs are by a single instruction, while the helped
ones are helped by 1-4 instructions.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/compiler/glsl/opt_constant_folding.cpp     |  9 +++++++++
 src/compiler/glsl/opt_constant_propagation.cpp | 12 ++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp
index ee67420..97dcc7e 100644
--- a/src/compiler/glsl/opt_constant_folding.cpp
+++ b/src/compiler/glsl/opt_constant_folding.cpp
@@ -91,6 +91,15 @@ ir_constant_fold(ir_rvalue **rvalue)
                      !array_ref->array_index->as_constant()))
       return false;
 
+   /* No constant folding can be performed on variable dereferences.  We need
+    * to explicitly avoid them, as calling constant_expression_value() on a
+    * variable dereference will return a clone of var->constant_value.  This
+    * would make us propagate the value into the tree, which isn't our job.
+    */
+   ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable();
+   if (var_ref)
+      return false;
+
    ir_constant *constant = (*rvalue)->constant_expression_value();
    if (constant) {
       *rvalue = constant;
diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp
index 4b82bd1..fbc22b0 100644
--- a/src/compiler/glsl/opt_constant_propagation.cpp
+++ b/src/compiler/glsl/opt_constant_propagation.cpp
@@ -138,8 +138,20 @@ public:
 void
 ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue)
 {
+   if (*rvalue == NULL)
+      return;
+
    if (ir_constant_fold(rvalue))
       this->progress = true;
+
+   ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable();
+   if (var_ref) {
+      ir_constant *constant = var_ref->constant_expression_value();
+      if (constant) {
+         *rvalue = constant;
+         this->progress = true;
+      }
+   }
 }
 
 void
-- 
2.8.2



More information about the mesa-dev mailing list