[Mesa-dev] [PATCH 14/23] glsl: Distribute unary operations over ir_triop_csel
Ian Romanick
idr at freedesktop.org
Fri Mar 20 13:58:14 PDT 2015
From: Ian Romanick <ian.d.romanick at intel.com>
If the both result operands of the ir_triop_csel are constants,
distributing the unary operation allows constant folding to eliminate
it.
This change fixes may of the shaders most hurt by "glsl: Optimize
certain if-statements to ir_triop_csel".
Shader-db results:
GM45 (0x2A42):
total instructions in shared programs: 3545712 -> 3545351 (-0.01%)
instructions in affected programs: 95123 -> 94762 (-0.38%)
helped: 301
Iron Lake (0x0046):
total instructions in shared programs: 4976067 -> 4975577 (-0.01%)
instructions in affected programs: 127925 -> 127435 (-0.38%)
helped: 430
Sandy Bridge (0x0116):
total instructions in shared programs: 6803288 -> 6802556 (-0.01%)
instructions in affected programs: 160949 -> 160217 (-0.45%)
helped: 606
Sandy Bridge (0x0116) NIR:
total instructions in shared programs: 6817171 -> 6815965 (-0.02%)
instructions in affected programs: 176431 -> 175225 (-0.68%)
helped: 658
HURT: 5
Ivy Bridge (0x0166):
total instructions in shared programs: 6278318 -> 6277594 (-0.01%)
instructions in affected programs: 148462 -> 147738 (-0.49%)
helped: 596
Ivy Bridge (0x0166) NIR:
total instructions in shared programs: 6324604 -> 6323362 (-0.02%)
instructions in affected programs: 164896 -> 163654 (-0.75%)
helped: 652
HURT: 5
Haswell (0x0426):
total instructions in shared programs: 5763779 -> 5763055 (-0.01%)
instructions in affected programs: 131140 -> 130416 (-0.55%)
helped: 596
Haswell (0x0426) NIR:
total instructions in shared programs: 5800334 -> 5799128 (-0.02%)
instructions in affected programs: 146551 -> 145345 (-0.82%)
helped: 652
HURT: 8
Broadwell (0x162E):
total instructions in shared programs: 6811805 -> 6811079 (-0.01%)
instructions in affected programs: 132390 -> 131664 (-0.55%)
helped: 600
Broadwell (0x162E) NIR:
total instructions in shared programs: 7015106 -> 7013948 (-0.02%)
instructions in affected programs: 146168 -> 145010 (-0.79%)
helped: 652
HURT: 8
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
src/glsl/opt_algebraic.cpp | 68 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 60 insertions(+), 8 deletions(-)
diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index deedc9c..b1f0fa9 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -283,25 +283,77 @@ ir_algebraic_visitor::swizzle_if_required(ir_expression *expr,
return operand;
}
-ir_rvalue *
-ir_algebraic_visitor::handle_expression(ir_expression *ir)
+static bool
+preprocess_operands(ir_expression *ir, ir_constant *op_const[4],
+ ir_expression *op_expr[4])
{
- ir_constant *op_const[4] = {NULL, NULL, NULL, NULL};
- ir_expression *op_expr[4] = {NULL, NULL, NULL, NULL};
- unsigned int i;
-
assert(ir->get_num_operands() <= 4);
- for (i = 0; i < ir->get_num_operands(); i++) {
+ for (unsigned i = 0; i < ir->get_num_operands(); i++) {
if (ir->operands[i]->type->is_matrix())
- return ir;
+ return false;
op_const[i] = ir->operands[i]->constant_expression_value();
op_expr[i] = ir->operands[i]->as_expression();
}
+ return true;
+}
+
+ir_rvalue *
+ir_algebraic_visitor::handle_expression(ir_expression *ir)
+{
+ ir_constant *op_const[4] = {NULL, NULL, NULL, NULL};
+ ir_expression *op_expr[4] = {NULL, NULL, NULL, NULL};
+ unsigned int i;
+
+ if (!preprocess_operands(ir, op_const, op_expr))
+ return ir;
+
if (this->mem_ctx == NULL)
this->mem_ctx = ralloc_parent(ir);
+
+ /* If the expression is a unary operation over an ir_triop_csel with
+ * constant results, distribute the unary operation over the ir_triop_csel
+ * results. Constant folding will do the rest.
+ *
+ * Example: -mix(0, 57, condition) becomes mix(0, -57, condition).
+ */
+ if (ir->get_num_operands() == 1 &&
+ op_expr[0] != NULL &&
+ op_expr[0]->operation == ir_triop_csel) {
+ if (op_expr[0]->operands[1]->as_constant() &&
+ op_expr[0]->operands[2]->as_constant()) {
+ ir_expression *const tmp_expr[2] = {
+ new(mem_ctx) ir_expression(ir->operation, op_expr[0]->operands[1]),
+ new(mem_ctx) ir_expression(ir->operation, op_expr[0]->operands[2])
+ };
+
+ /* Constant-fold the expressions now to (possibly) save an
+ * interation through the optimization loop.
+ */
+ op_expr[0]->operands[1] = tmp_expr[0]->constant_expression_value();
+ op_expr[0]->operands[2] = tmp_expr[1]->constant_expression_value();
+ assert(op_expr[0]->operands[1] != NULL);
+ assert(op_expr[0]->operands[2] != NULL);
+
+ /* The type of the ir_triop_csel is now whatever the type of the
+ * distributed expression was.
+ */
+ assert(ir->type == op_expr[0]->operands[1]->type);
+ assert(ir->type == op_expr[0]->operands[2]->type);
+ op_expr[0]->type = ir->type;
+
+ /* Now let the rest of the algebraic optimization operate on the
+ * ir_triop_csel expression that replace the original unary
+ * expression.
+ */
+ ir = op_expr[0];
+ if (!preprocess_operands(ir, op_const, op_expr))
+ return ir;
+ }
+ }
+
switch (ir->operation) {
case ir_unop_bit_not:
if (op_expr[0] && op_expr[0]->operation == ir_unop_bit_not)
--
2.1.0
More information about the mesa-dev
mailing list