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 <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -91,6 +91,15 @@ ir_constant_fold(ir_rvalue **rvalue)
|
|||||||
!array_ref->array_index->as_constant()))
|
!array_ref->array_index->as_constant()))
|
||||||
return false;
|
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();
|
ir_constant *constant = (*rvalue)->constant_expression_value();
|
||||||
if (constant) {
|
if (constant) {
|
||||||
*rvalue = constant;
|
*rvalue = constant;
|
||||||
|
@@ -138,8 +138,20 @@ public:
|
|||||||
void
|
void
|
||||||
ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue)
|
ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue)
|
||||||
{
|
{
|
||||||
|
if (*rvalue == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ir_constant_fold(rvalue))
|
if (ir_constant_fold(rvalue))
|
||||||
this->progress = true;
|
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
|
void
|
||||||
|
Reference in New Issue
Block a user