summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2011-08-01 13:55:46 -0700
committerIan Romanick <ian.d.romanick@intel.com>2011-08-15 11:44:26 -0700
commit4a026d6ba50034c326eb6cfd0b555f57d83ab609 (patch)
tree2f3d490115a5ce1efbed52d0214d0b99c3e7a5d2
parent13df36ecb6c24ea36534fa0dfea917aca8233710 (diff)
glsl: Slight change to the code generated by if-flattening
Now the condition (for the then-clause) and the inverse condition (for the else-clause) get written to separate temporary variables. In the presence of complex conditions, this shouldn't result in more code being generated. If the original if-statement was if (a && b && c && d && e) { ... } else { ... } The lowered code will be if_to_cond_assign_then = a && b && c && d && e; ... if_to_cond_assign_else = !if_to_cond_assign_then; ... Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/glsl/lower_if_to_cond_assign.cpp60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp
index 5c74bc1816c..a7097556c14 100644
--- a/src/glsl/lower_if_to_cond_assign.cpp
+++ b/src/glsl/lower_if_to_cond_assign.cpp
@@ -136,7 +136,6 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
return visit_continue;
bool found_control_flow = false;
- ir_variable *cond_var;
ir_assignment *assign;
ir_dereference_variable *deref;
@@ -154,31 +153,50 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
void *mem_ctx = ralloc_parent(ir);
- /* Store the condition to a variable so the assignment conditions are
- * simpler.
+ /* Store the condition to a variable. Move all of the instructions from
+ * the then-clause of the if-statement. Use the condition variable as a
+ * condition for all assignments.
*/
- cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type,
- "if_to_cond_assign_condition",
- ir_var_temporary);
- ir->insert_before(cond_var);
-
- deref = new(mem_ctx) ir_dereference_variable(cond_var);
- assign = new(mem_ctx) ir_assignment(deref,
- ir->condition, NULL);
+ ir_variable *const then_var =
+ new(mem_ctx) ir_variable(glsl_type::bool_type,
+ "if_to_cond_assign_then",
+ ir_var_temporary);
+ ir->insert_before(then_var);
+
+ ir_dereference_variable *then_cond =
+ new(mem_ctx) ir_dereference_variable(then_var);
+
+ assign = new(mem_ctx) ir_assignment(then_cond, ir->condition);
ir->insert_before(assign);
- /* Now, move all of the instructions out of the if blocks, putting
- * conditions on assignments.
- */
- move_block_to_cond_assign(mem_ctx, ir, deref,
+ move_block_to_cond_assign(mem_ctx, ir, then_cond,
&ir->then_instructions);
- ir_rvalue *inverse =
- new(mem_ctx) ir_expression(ir_unop_logic_not,
- glsl_type::bool_type,
- deref->clone(mem_ctx, NULL),
- NULL);
- move_block_to_cond_assign(mem_ctx, ir, inverse, &ir->else_instructions);
+ /* If there are instructions in the else-clause, store the inverse of the
+ * condition to a variable. Move all of the instructions from the
+ * else-clause if the if-statement. Use the (inverse) condition variable
+ * as a condition for all assignments.
+ */
+ if (!ir->else_instructions.is_empty()) {
+ ir_variable *const else_var =
+ new(mem_ctx) ir_variable(glsl_type::bool_type,
+ "if_to_cond_assign_else",
+ ir_var_temporary);
+ ir->insert_before(else_var);
+
+ ir_dereference_variable *else_cond =
+ new(mem_ctx) ir_dereference_variable(else_var);
+
+ ir_rvalue *inverse =
+ new(mem_ctx) ir_expression(ir_unop_logic_not,
+ then_cond->clone(mem_ctx, NULL));
+
+ assign = new(mem_ctx) ir_assignment(else_cond, inverse);
+ ir->insert_before(assign);
+
+ move_block_to_cond_assign(mem_ctx, ir, else_cond,
+ &ir->else_instructions);
+ }
ir->remove();