1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file lower_if_to_cond_assign.cpp 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This attempts to flatten if-statements to conditional assignments for 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GPUs with limited or no flow control support. 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It can't handle other control flow being inside of its block, such 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as calls or loops. Hopefully loop unrolling and inlining will take 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * care of those. 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Drivers for GPUs with no control flow support should simply call 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lower_if_to_cond_assign(instructions) 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to attempt to flatten all if-statements. 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some GPUs (such as i965 prior to gen6) do support control flow, but have a 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * maximum nesting depth N. Drivers for such hardware can call 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lower_if_to_cond_assign(instructions, N) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to attempt to flatten any if-statements appearing at depth > N. 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h" 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h" 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h" 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor { 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if_to_cond_assign_visitor(unsigned max_depth) 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->progress = false; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->max_depth = max_depth; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->depth = 0; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->condition_variables = hash_table_ctor(0, hash_table_pointer_hash, 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_pointer_compare); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~ir_if_to_cond_assign_visitor() 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_dtor(this->condition_variables); 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_visitor_status visit_enter(ir_if *); 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_visitor_status visit_leave(ir_if *); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool progress; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned max_depth; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned depth; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct hash_table *condition_variables; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglower_if_to_cond_assign(exec_list *instructions, unsigned max_depth) 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (max_depth == UINT_MAX) 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if_to_cond_assign_visitor v(max_depth); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_list_elements(&v, instructions); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return v.progress; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcheck_control_flow(ir_instruction *ir, void *data) 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool *found_control_flow = (bool *)data; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->ir_type) { 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_type_call: 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_type_discard: 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_type_loop: 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_type_loop_jump: 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_type_return: 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *found_control_flow = true; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmove_block_to_cond_assign(void *mem_ctx, 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *if_ir, ir_rvalue *cond_expr, 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *instructions, 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct hash_table *ht) 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_safe(node, instructions) { 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *ir = (ir_instruction *) node; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->ir_type == ir_type_assignment) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *assign = (ir_assignment *)ir; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (hash_table_find(ht, assign) == NULL) { 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_insert(ht, assign, assign); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the LHS of the assignment is a condition variable that was 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * previously added, insert an additional assignment of false to 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the variable. 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool assign_to_cv = 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_find(ht, assign->lhs->variable_referenced()) != NULL; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!assign->condition) { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (assign_to_cv) { 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign->rhs = 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_expression(ir_binop_logic_and, 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::bool_type, 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond_expr->clone(mem_ctx, NULL), 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign->rhs); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign->condition = cond_expr->clone(mem_ctx, NULL); 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign->condition = 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_expression(ir_binop_logic_and, 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::bool_type, 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond_expr->clone(mem_ctx, NULL), 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign->condition); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now, move from the if block to the block surrounding it. */ 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->remove(); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_ir->insert_before(ir); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_if_to_cond_assign_visitor::visit_enter(ir_if *ir) 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) ir; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->depth++; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Only flatten when beyond the GPU's maximum supported nesting depth. */ 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->depth-- <= this->max_depth) 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool found_control_flow = false; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *assign; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check that both blocks don't contain anything we can't support. */ 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *then_ir = (ir_instruction *)then_iter.get(); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_tree(then_ir, check_control_flow, &found_control_flow); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) { 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *else_ir = (ir_instruction *)else_iter.get(); 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_tree(else_ir, check_control_flow, &found_control_flow); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (found_control_flow) 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx = ralloc_parent(ir); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Store the condition to a variable. Move all of the instructions from 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the then-clause of the if-statement. Use the condition variable as a 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * condition for all assignments. 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const then_var = 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_variable(glsl_type::bool_type, 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "if_to_cond_assign_then", 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->insert_before(then_var); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *then_cond = 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_dereference_variable(then_var); 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign = new(mem_ctx) ir_assignment(then_cond, ir->condition); 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->insert_before(assign); 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_block_to_cond_assign(mem_ctx, ir, then_cond, 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ir->then_instructions, 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->condition_variables); 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add the new condition variable to the hash table. This allows us to 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * find this variable when lowering other (enclosing) if-statements. 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_insert(this->condition_variables, then_var, then_var); 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there are instructions in the else-clause, store the inverse of the 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * condition to a variable. Move all of the instructions from the 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * else-clause if the if-statement. Use the (inverse) condition variable 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as a condition for all assignments. 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ir->else_instructions.is_empty()) { 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const else_var = 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_variable(glsl_type::bool_type, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "if_to_cond_assign_else", 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->insert_before(else_var); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *else_cond = 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_dereference_variable(else_var); 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *inverse = 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_expression(ir_unop_logic_not, 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org then_cond->clone(mem_ctx, NULL)); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assign = new(mem_ctx) ir_assignment(else_cond, inverse); 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->insert_before(assign); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org move_block_to_cond_assign(mem_ctx, ir, else_cond, 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ir->else_instructions, 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->condition_variables); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add the new condition variable to the hash table. This allows us to 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * find this variable when lowering other (enclosing) if-statements. 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_insert(this->condition_variables, else_var, else_var); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->remove(); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->progress = true; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return visit_continue; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 253