[Mesa-dev] [RFC PATCH 1/2] glsl: Transform pow(x, 4) into (x*x)*(x*x).

Matt Turner mattst88 at gmail.com
Tue Mar 17 16:23:16 PDT 2015


Without NIR:

total instructions in shared programs: 6190374 -> 6190153 (-0.00%)
instructions in affected programs:     61126 -> 60905 (-0.36%)
helped:                                156

With NIR:

total instructions in shared programs: 6271584 -> 6271471 (-0.00%)
instructions in affected programs:     47656 -> 47543 (-0.24%)
helped:                                113
GAINED:                                4
LOST:                                  41
---
The NIR gained/lost numbers look bad, but they're better than the next
patch alone. I wanted to send these out because Jason was doing
something that involved this.

The two shaders I poked at seemed to be doing

    saturate(pow(x, 4.0f) + 1e-7f)

Just want to ensure the result is >0.0f I guess?

After changing the pow(x, 4.0f) into a pair of multiplies, we're able
to combine the second multiply with an add. Not sure why this means
we lose SIMD16, but the shaders that we lose we couldn't get SIMD16
in the non-NIR case anyway.

 src/glsl/opt_algebraic.cpp | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index 69c03ea..7742f82 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -99,6 +99,12 @@ is_vec_two(ir_constant *ir)
 }
 
 static inline bool
+is_vec_four(ir_constant *ir)
+{
+   return (ir == NULL) ? false : ir->is_value(4.0, 4);
+}
+
+static inline bool
 is_vec_negative_one(ir_constant *ir)
 {
    return (ir == NULL) ? false : ir->is_negative_one();
@@ -742,6 +748,20 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
          return mul(x, x);
       }
 
+      if (is_vec_four(op_const[1])) {
+         ir_variable *x = new(ir) ir_variable(ir->operands[1]->type, "x",
+                                              ir_var_temporary);
+         base_ir->insert_before(x);
+         base_ir->insert_before(assign(x, ir->operands[0]));
+
+         ir_variable *squared = new(ir) ir_variable(ir->operands[1]->type,
+                                                    "squared",
+                                                    ir_var_temporary);
+         base_ir->insert_before(squared);
+         base_ir->insert_before(assign(squared, mul(x, x)));
+         return mul(squared, squared);
+      }
+
       break;
 
    case ir_binop_min:
-- 
2.0.5



More information about the mesa-dev mailing list