glsl: Avoid extra if statements for logic and/or with no side effects.
authorEric Anholt <eric@anholt.net>
Wed, 8 Feb 2012 06:59:24 +0000 (22:59 -0800)
committerEric Anholt <eric@anholt.net>
Tue, 13 Mar 2012 20:50:08 +0000 (13:50 -0700)
This avoids extra if statements in the common case of just comparing
two expressions that don't involve assignments or function calls,
along with simplifying the handling of constant expressions.  Reduces
i965 instructions generated in unigine tropics and sanctuary,
yofrankie, warsow, gstreamer shaders, and the weston compositor.

shader-db results:
Total instructions: 213052 -> 212752
38/1246 programs affected (3.0%)
14309 -> 14009 instructions in affected programs (2.1% reduction)

src/glsl/ast_to_hir.cpp

index c580359fdd0a41f74ba031a4df04ef0fa5c25ce0..75d7e9d5793079b5c5917c87323a6e13edb0628c 100644 (file)
@@ -1199,15 +1199,9 @@ ast_expression::hir(exec_list *instructions,
       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
                                         "RHS", &error_emitted);
 
-      ir_constant *op0_const = op[0]->constant_expression_value();
-      if (op0_const) {
-        if (op0_const->value.b[0]) {
-           instructions->append_list(&rhs_instructions);
-           result = op[1];
-        } else {
-           result = op0_const;
-        }
-        type = glsl_type::bool_type;
+      if (rhs_instructions.is_empty()) {
+        result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
+        type = result->type;
       } else {
         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
                                                       "and_tmp",
@@ -1241,14 +1235,9 @@ ast_expression::hir(exec_list *instructions,
       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
                                         "RHS", &error_emitted);
 
-      ir_constant *op0_const = op[0]->constant_expression_value();
-      if (op0_const) {
-        if (op0_const->value.b[0]) {
-           result = op0_const;
-        } else {
-           result = op[1];
-        }
-        type = glsl_type::bool_type;
+      if (rhs_instructions.is_empty()) {
+        result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
+        type = result->type;
       } else {
         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
                                                       "or_tmp",