diff options
author | Kenneth Graunke <[email protected]> | 2016-04-29 13:13:01 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2016-05-15 23:59:39 -0700 |
commit | 8e71ac731b53a755df37efe63cf49607276de2d4 (patch) | |
tree | 2f2fda1bdf3946f2c56ea13eb1e7d1a58aa2fec1 /src | |
parent | db8fcbbaf940cdf690878f204f17d8bc90a6768e (diff) |
glsl: Don't do constant propagation in opt_constant_folding.
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 <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/glsl/opt_constant_folding.cpp | 9 | ||||
-rw-r--r-- | src/compiler/glsl/opt_constant_propagation.cpp | 12 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp index ee67420adf8..97dcc7e1acb 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 4b82bd13f9f..fbc22b0e50f 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 |