summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2010-09-01 10:13:21 -0700
committerIan Romanick <[email protected]>2010-09-01 10:25:11 -0700
commita35faa6a41eb8a240f8e6086853653e9a21e75bd (patch)
tree769ddc591cb6f645449c2ac7334470b27d66902e /src/glsl
parenta4262874f84e25412cb9bc53b3f1771e4017e27c (diff)
glsl2: Perform algebraic simplifications on logical binary operators
Reduces glsl-vs-all-01 from 42 Mesa IR instructions (including the END) to 17.
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ir_algebraic.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/glsl/ir_algebraic.cpp b/src/glsl/ir_algebraic.cpp
index b731ba05be9..ff81563f196 100644
--- a/src/glsl/ir_algebraic.cpp
+++ b/src/glsl/ir_algebraic.cpp
@@ -366,6 +366,58 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
}
break;
+ case ir_binop_logic_and:
+ /* FINISHME: Also simplify (a && a) to (a). */
+ if (is_vec_one(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir_constant::zero(mem_ctx, ir->type);
+ }
+ break;
+
+ case ir_binop_logic_xor:
+ /* FINISHME: Also simplify (a ^^ a) to (false). */
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_one(op_const[0])) {
+ this->progress = true;
+ return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
+ ir->operands[1], NULL);
+ } else if (is_vec_one(op_const[1])) {
+ this->progress = true;
+ return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
+ ir->operands[0], NULL);
+ }
+ break;
+
+ case ir_binop_logic_or:
+ /* FINISHME: Also simplify (a || a) to (a). */
+ if (is_vec_zero(op_const[0])) {
+ this->progress = true;
+ return ir->operands[1];
+ } else if (is_vec_zero(op_const[1])) {
+ this->progress = true;
+ return ir->operands[0];
+ } else if (is_vec_one(op_const[0]) || is_vec_one(op_const[1])) {
+ ir_constant_data data;
+
+ for (unsigned i = 0; i < 16; i++)
+ data.b[i] = true;
+
+ this->progress = true;
+ return new(mem_ctx) ir_constant(ir->type, &data);
+ }
+ break;
+
case ir_unop_rcp:
if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) {
this->progress = true;