glsl: Recognize open-coded pow(x, y).
authorMatt Turner <mattst88@gmail.com>
Sun, 7 Sep 2014 07:41:41 +0000 (00:41 -0700)
committerMatt Turner <mattst88@gmail.com>
Sat, 27 Sep 2014 19:18:37 +0000 (12:18 -0700)
pow(x, y) is equivalent to exp(log(x) * y).

instructions in affected programs:     578 -> 458 (-20.76%)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/opt_algebraic.cpp

index 447618f9ef9db10986378ee68949bf84f208982e..0cdb8ecfc0ac979b35f906d167aa77c7e8a62e24 100644 (file)
@@ -357,6 +357,20 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
       if (op_expr[0]->operation == ir_unop_log2) {
          return op_expr[0]->operands[0];
       }
+
+      if (!options->EmitNoPow && op_expr[0]->operation == ir_binop_mul) {
+         for (int log2_pos = 0; log2_pos < 2; log2_pos++) {
+            ir_expression *log2_expr =
+               op_expr[0]->operands[log2_pos]->as_expression();
+
+            if (log2_expr && log2_expr->operation == ir_unop_log2) {
+               return new(mem_ctx) ir_expression(ir_binop_pow,
+                                                 ir->type,
+                                                 log2_expr->operands[0],
+                                                 op_expr[0]->operands[1 - log2_pos]);
+            }
+         }
+      }
       break;
 
    case ir_unop_log2: