summaryrefslogtreecommitdiffstats
path: root/src/glsl/opt_algebraic.cpp
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2013-10-15 23:42:19 -0700
committerMatt Turner <[email protected]>2013-10-16 20:49:43 -0700
commita360ca7476a967d12c6622bbe4e5e65e74fccd50 (patch)
treefa24019ff4edc5ef0df14bb049631a1957f6b9e7 /src/glsl/opt_algebraic.cpp
parent197f3a33fbce525e8f7799466935304d9e24c0f1 (diff)
glsl: Optimize mul(a, -1) into neg(a).
Two extra instructions in some heroesofnewerth shaders, but a win for everything else. total instructions in shared programs: 1531352 -> 1530815 (-0.04%) instructions in affected programs: 121898 -> 121361 (-0.44%) Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl/opt_algebraic.cpp')
-rw-r--r--src/glsl/opt_algebraic.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index d706a6ad13c..3e5802e1818 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -85,6 +85,12 @@ is_vec_one(ir_constant *ir)
}
static inline bool
+is_vec_negative_one(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_negative_one();
+}
+
+static inline bool
is_vec_basis(ir_constant *ir)
{
return (ir == NULL) ? false : ir->is_basis();
@@ -287,6 +293,23 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
this->progress = true;
return ir_constant::zero(ir, ir->type);
}
+ if (is_vec_negative_one(op_const[0])) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_neg,
+ ir->operands[1]->type,
+ ir->operands[1],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+ if (is_vec_negative_one(op_const[1])) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_neg,
+ ir->operands[0]->type,
+ ir->operands[0],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+
/* Reassociate multiplication of constants so that we can do
* constant folding.