Mesa (master): i965/fs: Optimize emit_bool_to_cond_code for logical exprs.

Matt Turner mattst88 at kemper.freedesktop.org
Tue Aug 19 01:34:29 UTC 2014


Module: Mesa
Branch: master
Commit: cc60a487d1bd2b34a07ce6cbe5161684772ecd70
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cc60a487d1bd2b34a07ce6cbe5161684772ecd70

Author: Matt Turner <mattst88 at gmail.com>
Date:   Fri Aug  8 21:04:26 2014 -0700

i965/fs: Optimize emit_bool_to_cond_code for logical exprs.

AND, OR, and XOR can generate the conditional code directly.

total instructions in shared programs: 4293335 -> 4292303 (-0.02%)
instructions in affected programs:     121408 -> 120376 (-0.85%)

Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>

---

 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |  141 ++++++++++++++++----------
 1 file changed, 87 insertions(+), 54 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 1245c8a..fa2c226 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2228,72 +2228,105 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
 {
    ir_expression *expr = ir->as_expression();
 
-   if (expr &&
-       expr->operation != ir_binop_logic_and &&
-       expr->operation != ir_binop_logic_or &&
-       expr->operation != ir_binop_logic_xor) {
-      fs_reg op[2];
-      fs_inst *inst;
+   if (!expr) {
+      ir->accept(this);
 
-      assert(expr->get_num_operands() <= 2);
-      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
-	 assert(expr->operands[i]->type->is_scalar());
+      fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
+      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      return;
+   }
 
-	 expr->operands[i]->accept(this);
-	 op[i] = this->result;
+   fs_reg op[2];
+   fs_inst *inst;
 
-	 resolve_ud_negate(&op[i]);
-      }
+   assert(expr->get_num_operands() <= 2);
+   for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
+      assert(expr->operands[i]->type->is_scalar());
 
-      switch (expr->operation) {
-      case ir_unop_logic_not:
-	 inst = emit(AND(reg_null_d, op[0], fs_reg(1)));
-	 inst->conditional_mod = BRW_CONDITIONAL_Z;
-	 break;
+      expr->operands[i]->accept(this);
+      op[i] = this->result;
 
-      case ir_unop_f2b:
-	 if (brw->gen >= 6) {
-	    emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
-	 } else {
-	    inst = emit(MOV(reg_null_f, op[0]));
-            inst->conditional_mod = BRW_CONDITIONAL_NZ;
-	 }
-	 break;
+      resolve_ud_negate(&op[i]);
+   }
 
-      case ir_unop_i2b:
-	 if (brw->gen >= 6) {
-	    emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
-	 } else {
-	    inst = emit(MOV(reg_null_d, op[0]));
-            inst->conditional_mod = BRW_CONDITIONAL_NZ;
-	 }
-	 break;
+   switch (expr->operation) {
+   case ir_unop_logic_not:
+      inst = emit(AND(reg_null_d, op[0], fs_reg(1)));
+      inst->conditional_mod = BRW_CONDITIONAL_Z;
+      break;
 
-      case ir_binop_greater:
-      case ir_binop_gequal:
-      case ir_binop_less:
-      case ir_binop_lequal:
-      case ir_binop_equal:
-      case ir_binop_all_equal:
-      case ir_binop_nequal:
-      case ir_binop_any_nequal:
-	 resolve_bool_comparison(expr->operands[0], &op[0]);
-	 resolve_bool_comparison(expr->operands[1], &op[1]);
+   case ir_binop_logic_xor:
+      if (ctx->Const.UniformBooleanTrue == 1) {
+         fs_reg dst = fs_reg(this, glsl_type::uint_type);
+         emit(XOR(dst, op[0], op[1]));
+         inst = emit(AND(reg_null_d, dst, fs_reg(1)));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      } else {
+         inst = emit(XOR(reg_null_d, op[0], op[1]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      }
+      break;
 
-	 emit(CMP(reg_null_d, op[0], op[1],
-                  brw_conditional_for_comparison(expr->operation)));
-	 break;
+   case ir_binop_logic_or:
+      if (ctx->Const.UniformBooleanTrue == 1) {
+         fs_reg dst = fs_reg(this, glsl_type::uint_type);
+         emit(OR(dst, op[0], op[1]));
+         inst = emit(AND(reg_null_d, dst, fs_reg(1)));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      } else {
+         inst = emit(OR(reg_null_d, op[0], op[1]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      }
+      break;
 
-      default:
-	 unreachable("not reached");
+   case ir_binop_logic_and:
+      if (ctx->Const.UniformBooleanTrue == 1) {
+         fs_reg dst = fs_reg(this, glsl_type::uint_type);
+         emit(AND(dst, op[0], op[1]));
+         inst = emit(AND(reg_null_d, dst, fs_reg(1)));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      } else {
+         inst = emit(AND(reg_null_d, op[0], op[1]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
       }
-      return;
-   }
+      break;
 
-   ir->accept(this);
+   case ir_unop_f2b:
+      if (brw->gen >= 6) {
+         emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+      } else {
+         inst = emit(MOV(reg_null_f, op[0]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      }
+      break;
 
-   fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
-   inst->conditional_mod = BRW_CONDITIONAL_NZ;
+   case ir_unop_i2b:
+      if (brw->gen >= 6) {
+         emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
+      } else {
+         inst = emit(MOV(reg_null_d, op[0]));
+         inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      }
+      break;
+
+   case ir_binop_greater:
+   case ir_binop_gequal:
+   case ir_binop_less:
+   case ir_binop_lequal:
+   case ir_binop_equal:
+   case ir_binop_all_equal:
+   case ir_binop_nequal:
+   case ir_binop_any_nequal:
+      resolve_bool_comparison(expr->operands[0], &op[0]);
+      resolve_bool_comparison(expr->operands[1], &op[1]);
+
+      emit(CMP(reg_null_d, op[0], op[1],
+               brw_conditional_for_comparison(expr->operation)));
+      break;
+
+   default:
+      unreachable("not reached");
+   }
 }
 
 /**




More information about the mesa-commit mailing list