[Mesa-dev] [PATCH 5/8] i965/fs: Optimize emit_bool_to_cond_code for logical exprs.

Matt Turner mattst88 at gmail.com
Sun Aug 10 16:18:35 PDT 2014


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%)
---
Viewing this patch with git show -w should make review a lot easier.

 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 120 +++++++++++++++------------
 1 file changed, 66 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 7f463c2..869c1e3 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2146,72 +2146,84 @@ 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:
+      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:
+      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:
+      inst = emit(AND(reg_null_d, op[0], op[1]));
+      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+      break;
+
+   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;
       }
-      return;
-   }
+      break;
+
+   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;
 
-   ir->accept(this);
+   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;
 
-   fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
-   inst->conditional_mod = BRW_CONDITIONAL_NZ;
+   default:
+      unreachable("not reached");
+   }
 }
 
 /**
-- 
1.8.5.5



More information about the mesa-dev mailing list