summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-08-08 21:04:26 -0700
committerMatt Turner <[email protected]>2014-08-18 18:35:53 -0700
commitcc60a487d1bd2b34a07ce6cbe5161684772ecd70 (patch)
tree24e5c2543a191ee608a2a1b7280d12d9523e0199
parent2a6b6621d83b83f4ce499cd0c5b8eb824f07d25d (diff)
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 <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp141
1 files 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 1245c8a7667..fa2c2269356 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");
+ }
}
/**