1de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick/*
2de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * Copyright © 2010 Intel Corporation
3de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick *
4de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * copy of this software and associated documentation files (the "Software"),
6de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * to deal in the Software without restriction, including without limitation
7de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
9de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * Software is furnished to do so, subject to the following conditions:
10de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick *
11de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * The above copyright notice and this permission notice (including the next
12de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * paragraph) shall be included in all copies or substantial portions of the
13de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * Software.
14de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick *
15de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick * DEALINGS IN THE SOFTWARE.
22de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick */
23de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
24de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick#include "glsl_types.h"
25de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick#include "loop_analysis.h"
26de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick#include "ir_hierarchical_visitor.h"
27de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
28de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanickclass loop_unroll_visitor : public ir_hierarchical_visitor {
29de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanickpublic:
30e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri   loop_unroll_visitor(loop_state *state, unsigned max_iterations)
31de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   {
32de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      this->state = state;
33de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      this->progress = false;
34e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri      this->max_iterations = max_iterations;
35de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   }
36de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
37de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   virtual ir_visitor_status visit_leave(ir_loop *ir);
38de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
39de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   loop_state *state;
40de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
41de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   bool progress;
42e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri   unsigned max_iterations;
43de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick};
44de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
45de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
46528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunkestatic bool
47528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunkeis_break(ir_instruction *ir)
48528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke{
49528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke   return ir != NULL && ir->ir_type == ir_type_loop_jump
50528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke		     && ((ir_loop_jump *) ir)->is_break();
51528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke}
52528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke
53be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholtclass loop_unroll_count : public ir_hierarchical_visitor {
54be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholtpublic:
55be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   int nodes;
56be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   bool fail;
57be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
58be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   loop_unroll_count(exec_list *list)
59be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   {
60be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      nodes = 0;
61be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      fail = false;
62be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
63be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      run(list);
64be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   }
65be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
66be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   virtual ir_visitor_status visit_enter(ir_assignment *ir)
67be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   {
68be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      nodes++;
69be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      return visit_continue;
70be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   }
71be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
72be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   virtual ir_visitor_status visit_enter(ir_expression *ir)
73be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   {
74be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      nodes++;
75be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      return visit_continue;
76be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   }
77be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
78be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   virtual ir_visitor_status visit_enter(ir_loop *ir)
79be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   {
80be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      fail = true;
81be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      return visit_continue;
82be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   }
83be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt};
84be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
85528fa8ce329c22d6376d075c2afa69f177423bfaKenneth Graunke
86de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanickir_visitor_status
87de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanickloop_unroll_visitor::visit_leave(ir_loop *ir)
88de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick{
89de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   loop_variable_state *const ls = this->state->get(ir);
902cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   int iterations;
91de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
92de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   /* If we've entered a loop that hasn't been analyzed, something really,
93de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    * really bad has happened.
94de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    */
95de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   if (ls == NULL) {
96de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      assert(ls != NULL);
97de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      return visit_continue;
98de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   }
99de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
1002cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   iterations = ls->max_iterations;
1012cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
102de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   /* Don't try to unroll loops where the number of iterations is not known
103de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    * at compile-time.
104de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    */
1052cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   if (iterations < 0)
106de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      return visit_continue;
107de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
108de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   /* Don't try to unroll loops that have zillions of iterations either.
109de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    */
1103633e1f538e42ac04700aa98b48e3157b3406c14Brian Paul   if (iterations > (int) max_iterations)
111de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      return visit_continue;
112de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
11367007080b716c7e51039a381f407ababd68230f7Mathias Fröhlich   /* Don't try to unroll nested loops and loops with a huge body.
11467007080b716c7e51039a381f407ababd68230f7Mathias Fröhlich    */
115be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   loop_unroll_count count(&ir->body_instructions);
116be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt
117be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt   if (count.fail || count.nodes * iterations > (int)max_iterations * 5)
118be5f27a84d0d4efb57071d9d7ecda061223d03efEric Anholt      return visit_continue;
11967007080b716c7e51039a381f407ababd68230f7Mathias Fröhlich
1202cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   if (ls->num_loop_jumps > 1)
121de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      return visit_continue;
1222cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   else if (ls->num_loop_jumps) {
1230e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri      ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
1242cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri      assert(last_ir != NULL);
1252cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
1260e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri      if (is_break(last_ir)) {
1270e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         /* If the only loop-jump is a break at the end of the loop, the loop
1280e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri          * will execute exactly once.  Remove the break, set the iteration
1290e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri          * count, and fall through to the normal unroller.
1300e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri          */
1310e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         last_ir->remove();
1320e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         iterations = 1;
1330e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1340e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         this->progress = true;
1350e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri      } else {
1360e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         ir_if *ir_if = NULL;
1370e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         ir_instruction *break_ir = NULL;
1380e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         bool continue_from_then_branch = false;
1390e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1400e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         foreach_list(node, &ir->body_instructions) {
1410e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            /* recognize loops in the form produced by ir_lower_jumps */
1420e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            ir_instruction *cur_ir = (ir_instruction *) node;
1430e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1440e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            ir_if = cur_ir->as_if();
1450e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            if (ir_if != NULL) {
1460e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri	       /* Determine which if-statement branch, if any, ends with a
1470e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		* break.  The branch that did *not* have the break will get a
1480e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		* temporary continue inserted in each iteration of the loop
1490e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		* unroll.
1500e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		*
1510e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		* Note that since ls->num_loop_jumps is <= 1, it is impossible
1520e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		* for both branches to end with a break.
1532cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri		*/
1540e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               ir_instruction *ir_if_last =
1550e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  (ir_instruction *) ir_if->then_instructions.get_tail();
1560e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1570e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               if (is_break(ir_if_last)) {
1580e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  continue_from_then_branch = false;
1590e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  break_ir = ir_if_last;
1600e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  break;
1610e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               } else {
1620e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  ir_if_last =
1630e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri		     (ir_instruction *) ir_if->else_instructions.get_tail();
1640e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1650e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  if (is_break(ir_if_last)) {
1660e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                     break_ir = ir_if_last;
1670e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                     continue_from_then_branch = true;
1680e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                     break;
1690e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri                  }
1700e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               }
1710e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            }
1720e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         }
1730e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1740e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         if (break_ir == NULL)
1750e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            return visit_continue;
1762cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
1770e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         /* move instructions after then if in the continue branch */
1780e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         while (!ir_if->get_next()->is_tail_sentinel()) {
1790e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
1800e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1810e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            move_ir->remove();
1820e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            if (continue_from_then_branch)
1830e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               ir_if->then_instructions.push_tail(move_ir);
1840e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            else
1850e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               ir_if->else_instructions.push_tail(move_ir);
1860e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         }
1870e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri
1880e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         /* Remove the break from the if-statement.
1890e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri          */
1900e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri         break_ir->remove();
1912cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
192d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke         void *const mem_ctx = ralloc_parent(ir);
1932cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         ir_instruction *ir_to_replace = ir;
1942cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
1952cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         for (int i = 0; i < iterations; i++) {
1962cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            exec_list copy_list;
1972cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
1982cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            copy_list.make_empty();
1992cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
2002cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2010e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
2020e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri            assert(ir_if != NULL);
2032cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2042cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            ir_to_replace->insert_before(&copy_list);
2052cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            ir_to_replace->remove();
2062cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2072cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            /* placeholder that will be removed in the next iteration */
2082cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            ir_to_replace =
2092cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri	       new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
2102cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2112cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            exec_list *const list = (continue_from_then_branch)
2120e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri               ? &ir_if->then_instructions : &ir_if->else_instructions;
2132cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2142cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri            list->push_tail(ir_to_replace);
2152cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         }
2162cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2172cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         ir_to_replace->remove();
2182cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri
2192cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         this->progress = true;
2202cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri         return visit_continue;
2210e50c21e247b6d4246fcc2b583563a8f44bc4249Luca Barbieri      }
2222cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   }
223de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
224d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   void *const mem_ctx = ralloc_parent(ir);
225de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
2262cdbced10d98214616bcc5f960b21185c433d23bLuca Barbieri   for (int i = 0; i < iterations; i++) {
227de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      exec_list copy_list;
228de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
229de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      copy_list.make_empty();
230de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
231de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
232de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick      ir->insert_before(&copy_list);
233de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   }
234de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
235de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   /* The loop has been replaced by the unrolled copies.  Remove the original
236de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    * loop from the IR sequence.
237de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick    */
238de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   ir->remove();
239de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
240de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   this->progress = true;
241de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   return visit_continue;
242de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick}
243de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
244de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
245de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanickbool
246e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieriunroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations)
247de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick{
248e591c4625cae63660c5000fbab366e40fe154ab0Luca Barbieri   loop_unroll_visitor v(ls, max_iterations);
249de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
250de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   v.run(instructions);
251de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick
252de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick   return v.progress;
253de7c3fe31a7b88a5392dceee3b13b45ed78cdeaeIan Romanick}
254