11591693c7b415e9869157c711fe11263c95d74eDavid Li/* 21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation 31591693c7b415e9869157c711fe11263c95d74eDavid Li * 41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"), 61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation 71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the 91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions: 101591693c7b415e9869157c711fe11263c95d74eDavid Li * 111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next 121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the 131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software. 141591693c7b415e9869157c711fe11263c95d74eDavid Li * 151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE. 221591693c7b415e9869157c711fe11263c95d74eDavid Li */ 231591693c7b415e9869157c711fe11263c95d74eDavid Li 241591693c7b415e9869157c711fe11263c95d74eDavid Li#include <climits> 251591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/compiler.h" 261591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h" 271591693c7b415e9869157c711fe11263c95d74eDavid Li#include "loop_analysis.h" 281591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_hierarchical_visitor.h" 291591693c7b415e9869157c711fe11263c95d74eDavid Li 301591693c7b415e9869157c711fe11263c95d74eDavid Li/** 311591693c7b415e9869157c711fe11263c95d74eDavid Li * Find an initializer of a variable outside a loop 321591693c7b415e9869157c711fe11263c95d74eDavid Li * 331591693c7b415e9869157c711fe11263c95d74eDavid Li * Works backwards from the loop to find the pre-loop value of the variable. 341591693c7b415e9869157c711fe11263c95d74eDavid Li * This is used, for example, to find the initial value of loop induction 351591693c7b415e9869157c711fe11263c95d74eDavid Li * variables. 361591693c7b415e9869157c711fe11263c95d74eDavid Li * 371591693c7b415e9869157c711fe11263c95d74eDavid Li * \param loop Loop where \c var is an induction variable 381591693c7b415e9869157c711fe11263c95d74eDavid Li * \param var Variable whose initializer is to be found 391591693c7b415e9869157c711fe11263c95d74eDavid Li * 401591693c7b415e9869157c711fe11263c95d74eDavid Li * \return 411591693c7b415e9869157c711fe11263c95d74eDavid Li * The \c ir_rvalue assigned to the variable outside the loop. May return 421591693c7b415e9869157c711fe11263c95d74eDavid Li * \c NULL if no initializer can be found. 431591693c7b415e9869157c711fe11263c95d74eDavid Li */ 441591693c7b415e9869157c711fe11263c95d74eDavid Liir_rvalue * 451591693c7b415e9869157c711fe11263c95d74eDavid Lifind_initial_value(ir_loop *loop, ir_variable *var) 461591693c7b415e9869157c711fe11263c95d74eDavid Li{ 471591693c7b415e9869157c711fe11263c95d74eDavid Li for (exec_node *node = loop->prev; 481591693c7b415e9869157c711fe11263c95d74eDavid Li !node->is_head_sentinel(); 491591693c7b415e9869157c711fe11263c95d74eDavid Li node = node->prev) { 501591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *ir = (ir_instruction *) node; 511591693c7b415e9869157c711fe11263c95d74eDavid Li 521591693c7b415e9869157c711fe11263c95d74eDavid Li switch (ir->ir_type) { 531591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_call: 541591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_loop: 551591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_loop_jump: 561591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_return: 571591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_if: 581591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 591591693c7b415e9869157c711fe11263c95d74eDavid Li 601591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_function: 611591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_function_signature: 621591693c7b415e9869157c711fe11263c95d74eDavid Li assert(!"Should not get here."); 631591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 641591693c7b415e9869157c711fe11263c95d74eDavid Li 651591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_type_assignment: { 661591693c7b415e9869157c711fe11263c95d74eDavid Li ir_assignment *assign = ir->as_assignment(); 671591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *assignee = assign->lhs->whole_variable_referenced(); 681591693c7b415e9869157c711fe11263c95d74eDavid Li 691591693c7b415e9869157c711fe11263c95d74eDavid Li if (assignee == var) 701591693c7b415e9869157c711fe11263c95d74eDavid Li return (assign->condition != NULL) ? NULL : assign->rhs; 711591693c7b415e9869157c711fe11263c95d74eDavid Li 721591693c7b415e9869157c711fe11263c95d74eDavid Li break; 731591693c7b415e9869157c711fe11263c95d74eDavid Li } 741591693c7b415e9869157c711fe11263c95d74eDavid Li 751591693c7b415e9869157c711fe11263c95d74eDavid Li default: 761591693c7b415e9869157c711fe11263c95d74eDavid Li break; 771591693c7b415e9869157c711fe11263c95d74eDavid Li } 781591693c7b415e9869157c711fe11263c95d74eDavid Li } 791591693c7b415e9869157c711fe11263c95d74eDavid Li 801591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 811591693c7b415e9869157c711fe11263c95d74eDavid Li} 821591693c7b415e9869157c711fe11263c95d74eDavid Li 831591693c7b415e9869157c711fe11263c95d74eDavid Li 841591693c7b415e9869157c711fe11263c95d74eDavid Liint 851591693c7b415e9869157c711fe11263c95d74eDavid Licalculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment, 861591693c7b415e9869157c711fe11263c95d74eDavid Li enum ir_expression_operation op) 871591693c7b415e9869157c711fe11263c95d74eDavid Li{ 881591693c7b415e9869157c711fe11263c95d74eDavid Li if (from == NULL || to == NULL || increment == NULL) 891591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 901591693c7b415e9869157c711fe11263c95d74eDavid Li 91d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *mem_ctx = hieralloc_init(__func__); 921591693c7b415e9869157c711fe11263c95d74eDavid Li 931591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *const sub = 941591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from); 951591693c7b415e9869157c711fe11263c95d74eDavid Li 961591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *const div = 971591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment); 981591693c7b415e9869157c711fe11263c95d74eDavid Li 991591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant *iter = div->constant_expression_value(); 1001591693c7b415e9869157c711fe11263c95d74eDavid Li 1011591693c7b415e9869157c711fe11263c95d74eDavid Li if (iter == NULL) 1021591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 1031591693c7b415e9869157c711fe11263c95d74eDavid Li 1041591693c7b415e9869157c711fe11263c95d74eDavid Li if (!iter->type->is_integer()) { 1051591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *cast = 1061591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(ir_unop_f2i, glsl_type::int_type, iter, 1071591693c7b415e9869157c711fe11263c95d74eDavid Li NULL); 1081591693c7b415e9869157c711fe11263c95d74eDavid Li 1091591693c7b415e9869157c711fe11263c95d74eDavid Li iter = cast->constant_expression_value(); 1101591693c7b415e9869157c711fe11263c95d74eDavid Li } 1111591693c7b415e9869157c711fe11263c95d74eDavid Li 1121591693c7b415e9869157c711fe11263c95d74eDavid Li int iter_value = iter->get_int_component(0); 1131591693c7b415e9869157c711fe11263c95d74eDavid Li 1141591693c7b415e9869157c711fe11263c95d74eDavid Li /* Make sure that the calculated number of iterations satisfies the exit 1151591693c7b415e9869157c711fe11263c95d74eDavid Li * condition. This is needed to catch off-by-one errors and some types of 1161591693c7b415e9869157c711fe11263c95d74eDavid Li * ill-formed loops. For example, we need to detect that the following 1171591693c7b415e9869157c711fe11263c95d74eDavid Li * loop does not have a maximum iteration count. 1181591693c7b415e9869157c711fe11263c95d74eDavid Li * 1191591693c7b415e9869157c711fe11263c95d74eDavid Li * for (float x = 0.0; x != 0.9; x += 0.2) 1201591693c7b415e9869157c711fe11263c95d74eDavid Li * ; 1211591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1221591693c7b415e9869157c711fe11263c95d74eDavid Li const int bias[] = { -1, 0, 1 }; 1231591693c7b415e9869157c711fe11263c95d74eDavid Li bool valid_loop = false; 1241591693c7b415e9869157c711fe11263c95d74eDavid Li 1251591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < Elements(bias); i++) { 1261591693c7b415e9869157c711fe11263c95d74eDavid Li iter = (increment->type->is_integer()) 1271591693c7b415e9869157c711fe11263c95d74eDavid Li ? new(mem_ctx) ir_constant(iter_value + bias[i]) 1281591693c7b415e9869157c711fe11263c95d74eDavid Li : new(mem_ctx) ir_constant(float(iter_value + bias[i])); 1291591693c7b415e9869157c711fe11263c95d74eDavid Li 1301591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *const mul = 1311591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter, 1321591693c7b415e9869157c711fe11263c95d74eDavid Li increment); 1331591693c7b415e9869157c711fe11263c95d74eDavid Li 1341591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *const add = 1351591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from); 1361591693c7b415e9869157c711fe11263c95d74eDavid Li 1371591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *const cmp = 1381591693c7b415e9869157c711fe11263c95d74eDavid Li new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to); 1391591693c7b415e9869157c711fe11263c95d74eDavid Li 1401591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant *const cmp_result = cmp->constant_expression_value(); 1411591693c7b415e9869157c711fe11263c95d74eDavid Li 1421591693c7b415e9869157c711fe11263c95d74eDavid Li assert(cmp_result != NULL); 1431591693c7b415e9869157c711fe11263c95d74eDavid Li if (cmp_result->get_bool_component(0)) { 1441591693c7b415e9869157c711fe11263c95d74eDavid Li iter_value += bias[i]; 1451591693c7b415e9869157c711fe11263c95d74eDavid Li valid_loop = true; 1461591693c7b415e9869157c711fe11263c95d74eDavid Li break; 1471591693c7b415e9869157c711fe11263c95d74eDavid Li } 1481591693c7b415e9869157c711fe11263c95d74eDavid Li } 1491591693c7b415e9869157c711fe11263c95d74eDavid Li 150d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(mem_ctx); 1511591693c7b415e9869157c711fe11263c95d74eDavid Li return (valid_loop) ? iter_value : -1; 1521591693c7b415e9869157c711fe11263c95d74eDavid Li} 1531591693c7b415e9869157c711fe11263c95d74eDavid Li 1541591693c7b415e9869157c711fe11263c95d74eDavid Li 1551591693c7b415e9869157c711fe11263c95d74eDavid Liclass loop_control_visitor : public ir_hierarchical_visitor { 1561591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 1571591693c7b415e9869157c711fe11263c95d74eDavid Li loop_control_visitor(loop_state *state) 1581591693c7b415e9869157c711fe11263c95d74eDavid Li { 1591591693c7b415e9869157c711fe11263c95d74eDavid Li this->state = state; 1601591693c7b415e9869157c711fe11263c95d74eDavid Li this->progress = false; 1611591693c7b415e9869157c711fe11263c95d74eDavid Li } 1621591693c7b415e9869157c711fe11263c95d74eDavid Li 1631591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_leave(ir_loop *ir); 1641591693c7b415e9869157c711fe11263c95d74eDavid Li 1651591693c7b415e9869157c711fe11263c95d74eDavid Li loop_state *state; 1661591693c7b415e9869157c711fe11263c95d74eDavid Li 1671591693c7b415e9869157c711fe11263c95d74eDavid Li bool progress; 1681591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1691591693c7b415e9869157c711fe11263c95d74eDavid Li 1701591693c7b415e9869157c711fe11263c95d74eDavid Li 1711591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status 1721591693c7b415e9869157c711fe11263c95d74eDavid Liloop_control_visitor::visit_leave(ir_loop *ir) 1731591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1741591693c7b415e9869157c711fe11263c95d74eDavid Li loop_variable_state *const ls = this->state->get(ir); 1751591693c7b415e9869157c711fe11263c95d74eDavid Li 1761591693c7b415e9869157c711fe11263c95d74eDavid Li /* If we've entered a loop that hasn't been analyzed, something really, 1771591693c7b415e9869157c711fe11263c95d74eDavid Li * really bad has happened. 1781591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1791591693c7b415e9869157c711fe11263c95d74eDavid Li if (ls == NULL) { 1801591693c7b415e9869157c711fe11263c95d74eDavid Li assert(ls != NULL); 1811591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1821591693c7b415e9869157c711fe11263c95d74eDavid Li } 1831591693c7b415e9869157c711fe11263c95d74eDavid Li 1841591693c7b415e9869157c711fe11263c95d74eDavid Li /* Search the loop terminating conditions for one of the form 'i < c' where 1851591693c7b415e9869157c711fe11263c95d74eDavid Li * i is a loop induction variable, c is a constant, and < is any relative 1861591693c7b415e9869157c711fe11263c95d74eDavid Li * operator. 1871591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1881591693c7b415e9869157c711fe11263c95d74eDavid Li int max_iterations = ls->max_iterations; 1891591693c7b415e9869157c711fe11263c95d74eDavid Li 1901591693c7b415e9869157c711fe11263c95d74eDavid Li if(ir->from && ir->to && ir->increment) 1911591693c7b415e9869157c711fe11263c95d74eDavid Li max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp); 1921591693c7b415e9869157c711fe11263c95d74eDavid Li 1931591693c7b415e9869157c711fe11263c95d74eDavid Li if(max_iterations < 0) 1941591693c7b415e9869157c711fe11263c95d74eDavid Li max_iterations = INT_MAX; 1951591693c7b415e9869157c711fe11263c95d74eDavid Li 1961591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, &ls->terminators) { 1971591693c7b415e9869157c711fe11263c95d74eDavid Li loop_terminator *t = (loop_terminator *) node; 1981591693c7b415e9869157c711fe11263c95d74eDavid Li ir_if *if_stmt = t->ir; 1991591693c7b415e9869157c711fe11263c95d74eDavid Li 2001591693c7b415e9869157c711fe11263c95d74eDavid Li /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care 2011591693c7b415e9869157c711fe11263c95d74eDavid Li * about the former here. 2021591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2031591693c7b415e9869157c711fe11263c95d74eDavid Li ir_expression *cond = if_stmt->condition->as_expression(); 2041591693c7b415e9869157c711fe11263c95d74eDavid Li if (cond == NULL) 2051591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 2061591693c7b415e9869157c711fe11263c95d74eDavid Li 2071591693c7b415e9869157c711fe11263c95d74eDavid Li switch (cond->operation) { 2081591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_less: 2091591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_greater: 2101591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_lequal: 2111591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_gequal: { 2121591693c7b415e9869157c711fe11263c95d74eDavid Li /* The expressions that we care about will either be of the form 2131591693c7b415e9869157c711fe11263c95d74eDavid Li * 'counter < limit' or 'limit < counter'. Figure out which is 2141591693c7b415e9869157c711fe11263c95d74eDavid Li * which. 2151591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2161591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *counter = cond->operands[0]->as_dereference_variable(); 2171591693c7b415e9869157c711fe11263c95d74eDavid Li ir_constant *limit = cond->operands[1]->as_constant(); 2181591693c7b415e9869157c711fe11263c95d74eDavid Li enum ir_expression_operation cmp = cond->operation; 2191591693c7b415e9869157c711fe11263c95d74eDavid Li 2201591693c7b415e9869157c711fe11263c95d74eDavid Li if (limit == NULL) { 2211591693c7b415e9869157c711fe11263c95d74eDavid Li counter = cond->operands[1]->as_dereference_variable(); 2221591693c7b415e9869157c711fe11263c95d74eDavid Li limit = cond->operands[0]->as_constant(); 2231591693c7b415e9869157c711fe11263c95d74eDavid Li 2241591693c7b415e9869157c711fe11263c95d74eDavid Li switch (cmp) { 2251591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_less: cmp = ir_binop_gequal; break; 2261591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_greater: cmp = ir_binop_lequal; break; 2271591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_lequal: cmp = ir_binop_greater; break; 2281591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_binop_gequal: cmp = ir_binop_less; break; 2291591693c7b415e9869157c711fe11263c95d74eDavid Li default: assert(!"Should not get here."); 2301591693c7b415e9869157c711fe11263c95d74eDavid Li } 2311591693c7b415e9869157c711fe11263c95d74eDavid Li } 2321591693c7b415e9869157c711fe11263c95d74eDavid Li 2331591693c7b415e9869157c711fe11263c95d74eDavid Li if ((counter == NULL) || (limit == NULL)) 2341591693c7b415e9869157c711fe11263c95d74eDavid Li break; 2351591693c7b415e9869157c711fe11263c95d74eDavid Li 2361591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = counter->variable_referenced(); 2371591693c7b415e9869157c711fe11263c95d74eDavid Li 2381591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *init = find_initial_value(ir, var); 2391591693c7b415e9869157c711fe11263c95d74eDavid Li 2401591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(iv_node, &ls->induction_variables) { 2411591693c7b415e9869157c711fe11263c95d74eDavid Li loop_variable *lv = (loop_variable *) iv_node; 2421591693c7b415e9869157c711fe11263c95d74eDavid Li 2431591693c7b415e9869157c711fe11263c95d74eDavid Li if (lv->var == var) { 2441591693c7b415e9869157c711fe11263c95d74eDavid Li const int iterations = calculate_iterations(init, limit, 2451591693c7b415e9869157c711fe11263c95d74eDavid Li lv->increment, 2461591693c7b415e9869157c711fe11263c95d74eDavid Li cmp); 2471591693c7b415e9869157c711fe11263c95d74eDavid Li if (iterations >= 0) { 2481591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the new iteration count is lower than the previously 2491591693c7b415e9869157c711fe11263c95d74eDavid Li * believed iteration count, update the loop control values. 2501591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2511591693c7b415e9869157c711fe11263c95d74eDavid Li if (iterations < max_iterations) { 2521591693c7b415e9869157c711fe11263c95d74eDavid Li ir->from = init->clone(ir, NULL); 2531591693c7b415e9869157c711fe11263c95d74eDavid Li ir->to = limit->clone(ir, NULL); 2541591693c7b415e9869157c711fe11263c95d74eDavid Li ir->increment = lv->increment->clone(ir, NULL); 2551591693c7b415e9869157c711fe11263c95d74eDavid Li ir->counter = lv->var; 2561591693c7b415e9869157c711fe11263c95d74eDavid Li ir->cmp = cmp; 2571591693c7b415e9869157c711fe11263c95d74eDavid Li 2581591693c7b415e9869157c711fe11263c95d74eDavid Li max_iterations = iterations; 2591591693c7b415e9869157c711fe11263c95d74eDavid Li } 2601591693c7b415e9869157c711fe11263c95d74eDavid Li 2611591693c7b415e9869157c711fe11263c95d74eDavid Li /* Remove the conditional break statement. The loop 2621591693c7b415e9869157c711fe11263c95d74eDavid Li * controls are now set such that the exit condition will be 2631591693c7b415e9869157c711fe11263c95d74eDavid Li * satisfied. 2641591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2651591693c7b415e9869157c711fe11263c95d74eDavid Li if_stmt->remove(); 2661591693c7b415e9869157c711fe11263c95d74eDavid Li 2671591693c7b415e9869157c711fe11263c95d74eDavid Li assert(ls->num_loop_jumps > 0); 2681591693c7b415e9869157c711fe11263c95d74eDavid Li ls->num_loop_jumps--; 2691591693c7b415e9869157c711fe11263c95d74eDavid Li 2701591693c7b415e9869157c711fe11263c95d74eDavid Li this->progress = true; 2711591693c7b415e9869157c711fe11263c95d74eDavid Li } 2721591693c7b415e9869157c711fe11263c95d74eDavid Li 2731591693c7b415e9869157c711fe11263c95d74eDavid Li break; 2741591693c7b415e9869157c711fe11263c95d74eDavid Li } 2751591693c7b415e9869157c711fe11263c95d74eDavid Li } 2761591693c7b415e9869157c711fe11263c95d74eDavid Li break; 2771591693c7b415e9869157c711fe11263c95d74eDavid Li } 2781591693c7b415e9869157c711fe11263c95d74eDavid Li 2791591693c7b415e9869157c711fe11263c95d74eDavid Li default: 2801591693c7b415e9869157c711fe11263c95d74eDavid Li break; 2811591693c7b415e9869157c711fe11263c95d74eDavid Li } 2821591693c7b415e9869157c711fe11263c95d74eDavid Li } 2831591693c7b415e9869157c711fe11263c95d74eDavid Li 2841591693c7b415e9869157c711fe11263c95d74eDavid Li /* If we have proven the one of the loop exit conditions is satisifed before 2851591693c7b415e9869157c711fe11263c95d74eDavid Li * running the loop once, remove the loop. 2861591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2871591693c7b415e9869157c711fe11263c95d74eDavid Li if (max_iterations == 0) 2881591693c7b415e9869157c711fe11263c95d74eDavid Li ir->remove(); 2891591693c7b415e9869157c711fe11263c95d74eDavid Li else 2901591693c7b415e9869157c711fe11263c95d74eDavid Li ls->max_iterations = max_iterations; 2911591693c7b415e9869157c711fe11263c95d74eDavid Li 2921591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 2931591693c7b415e9869157c711fe11263c95d74eDavid Li} 2941591693c7b415e9869157c711fe11263c95d74eDavid Li 2951591693c7b415e9869157c711fe11263c95d74eDavid Li 2961591693c7b415e9869157c711fe11263c95d74eDavid Libool 2971591693c7b415e9869157c711fe11263c95d74eDavid Liset_loop_controls(exec_list *instructions, loop_state *ls) 2981591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2991591693c7b415e9869157c711fe11263c95d74eDavid Li loop_control_visitor v(ls); 3001591693c7b415e9869157c711fe11263c95d74eDavid Li 3011591693c7b415e9869157c711fe11263c95d74eDavid Li v.run(instructions); 3021591693c7b415e9869157c711fe11263c95d74eDavid Li 3031591693c7b415e9869157c711fe11263c95d74eDavid Li return v.progress; 3041591693c7b415e9869157c711fe11263c95d74eDavid Li} 305