diff options
author | Kenneth Graunke <[email protected]> | 2013-09-23 13:37:00 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2013-09-26 16:55:18 -0700 |
commit | aac75f877da1d106f6fd7bbd238d1d1d35a0c8e8 (patch) | |
tree | a212f3b66ca6aed8cdfceeede761215e39f2b4ff /src/mesa/drivers | |
parent | e5c49bc25b07b76dbcf577186484ab271114c48a (diff) |
i965/fs: Don't double-accept operands of logical and/or/xor operations.
If the argument to emit_bool_to_cond_code() is an ir_expression, we
loop over the operands, calling accept() on each of them, which
generates assembly code to compute that subexpression. We then emit
one or two final instruction that perform the top-level operation on
those operands.
If it's not an expression (say, a boolean-valued variable), we simply
call accept() on the whole value.
In commit 80ecb8f1 (i965/fs: Avoid generating extra AND instructions on
bool logic ops), Eric made logic operations jump out of the expression
path to the non-expression path.
Unfortunately, this meant that we would first accept() the two operands,
skip generating any code that used them, then accept() the whole
expression, generating code for the operands a second time.
Dead code elimination would always remove the first set of redundant
operand assembly, since nothing actually used them. But we shouldn't
generate it in the first place.
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 3d25fe3eca5..72c379a20c3 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1724,7 +1724,10 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) { ir_expression *expr = ir->as_expression(); - if (expr) { + 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; @@ -1744,11 +1747,6 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) inst->conditional_mod = BRW_CONDITIONAL_Z; break; - case ir_binop_logic_xor: - case ir_binop_logic_or: - case ir_binop_logic_and: - goto out; - case ir_unop_f2b: if (brw->gen >= 6) { emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ)); @@ -1790,7 +1788,6 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) return; } -out: ir->accept(this); fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1))); |