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