1a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/*
2a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Copyright © 2010 Intel Corporation
3a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt *
4a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
5a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * copy of this software and associated documentation files (the "Software"),
6a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * to deal in the Software without restriction, including without limitation
7a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the
9a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Software is furnished to do so, subject to the following conditions:
10a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt *
11a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * The above copyright notice and this permission notice (including the next
12a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * paragraph) shall be included in all copies or substantial portions of the
13a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Software.
14a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt *
15a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * DEALINGS IN THE SOFTWARE.
22a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */
23a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
24a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/**
25df883eb1575a740bf91e01cbe2eaa4dbc1f9f154Chad Versace * \file lower_vec_index_to_cond_assign.cpp
26a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt *
27a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Turns indexing into vector types to a series of conditional moves
28a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * of each channel's swizzle into a temporary.
29a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt *
30a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Most GPUs don't have a native way to do this operation, and this
31a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * works around that.  For drivers using both this pass and
32a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * ir_vec_index_to_swizzle, there's a risk that this pass will happen
33a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * before sufficient constant folding to find that the array index is
34a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * constant.  However, we hope that other optimization passes,
35a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * particularly constant folding of assignment conditions and copy
36a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * propagation, will result in the same code in the end.
37a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */
38a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
39a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir.h"
40a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir_visitor.h"
41a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "ir_optimization.h"
42a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt#include "glsl_types.h"
43a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
44a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt/**
45a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * Visitor class for replacing expressions with ir_constant values.
46a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */
47a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
48a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtclass ir_vec_index_to_cond_assign_visitor : public ir_hierarchical_visitor {
49a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtpublic:
50a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_vec_index_to_cond_assign_visitor()
51a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   {
52a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      progress = false;
53a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   }
54a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
55a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val);
56a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
57a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   virtual ir_visitor_status visit_enter(ir_expression *);
58a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   virtual ir_visitor_status visit_enter(ir_swizzle *);
597b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   virtual ir_visitor_status visit_leave(ir_assignment *);
60a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   virtual ir_visitor_status visit_enter(ir_return *);
61a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   virtual ir_visitor_status visit_enter(ir_call *);
62a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   virtual ir_visitor_status visit_enter(ir_if *);
63a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
64a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   bool progress;
65a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt};
66a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
67a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_rvalue *
68a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir)
69a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
70a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_dereference_array *orig_deref = ir->as_dereference_array();
71a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_assignment *assign;
72a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_variable *index, *var;
73a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_dereference *deref;
74a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   int i;
75a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
76a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   if (!orig_deref)
77a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      return ir;
78a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
79a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   if (orig_deref->array->type->is_matrix() ||
80a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt       orig_deref->array->type->is_array())
81a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      return ir;
82a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
83d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   void *mem_ctx = ralloc_parent(ir);
848273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
85a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
86a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
876c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   exec_list list;
886c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick
89a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   /* Store the index to a temporary to avoid reusing its tree. */
90a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   index = new(base_ir) ir_variable(glsl_type::int_type,
917e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick				    "vec_index_tmp_i",
927e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick				    ir_var_temporary);
936c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   list.push_tail(index);
94a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   deref = new(base_ir) ir_dereference_variable(index);
95a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL);
966c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   list.push_tail(assign);
97a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
98a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   /* Temporary where we store whichever value we swizzle out. */
997e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick   var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v",
1007e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick				  ir_var_temporary);
1016c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   list.push_tail(var);
1026c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick
1036c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   /* Generate a single comparison condition "mask" for all of the components
1046c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    * in the vector.
1056c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    */
1066c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   ir_rvalue *const cond_deref =
1076c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      compare_index_block(&list, index, 0,
1086c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick			  orig_deref->array->type->vector_elements,
1096c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick			  mem_ctx);
110a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
111a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   /* Generate a conditional move of each vector element to the temp. */
112a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
1136c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      ir_rvalue *condition_swizzle =
1146c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick	 new(base_ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1);
115a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
116a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      /* Just clone the rest of the deref chain when trying to get at the
117a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt       * underlying variable.
118a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt       */
1196c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      ir_rvalue *swizzle =
1206c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick	 new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
1216c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick				 i, 0, 0, 0, 1);
122a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
123a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      deref = new(base_ir) ir_dereference_variable(var);
1246c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      assign = new(base_ir) ir_assignment(deref, swizzle, condition_swizzle);
1256c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      list.push_tail(assign);
126a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   }
127a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
1286c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   /* Put all of the new instructions in the IR stream before the old
1296c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    * instruction.
1306c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    */
1316c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   base_ir->insert_before(&list);
1326c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick
133a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   this->progress = true;
134a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return new(base_ir) ir_dereference_variable(var);
135a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
136a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
137a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
138a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir)
139a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
140a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   unsigned int i;
141a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
142a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   for (i = 0; i < ir->get_num_operands(); i++) {
143a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      ir->operands[i] = convert_vec_index_to_cond_assign(ir->operands[i]);
144a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   }
145a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
146a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
147a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
148a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
149a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
150a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir)
151a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
152a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which
153a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt    * the result of indexing a vector is.  But maybe at some point we'll end up
154a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt    * using swizzling of scalars for vector construction.
155a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt    */
156a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir->val = convert_vec_index_to_cond_assign(ir->val);
157a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
158a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
159a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
160a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
161a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
1627b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholtir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
163a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
1647b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   ir_variable *index, *var;
1657b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   ir_dereference_variable *deref;
1667b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   ir_assignment *assign;
1677b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   int i;
1687b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
169a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir->rhs = convert_vec_index_to_cond_assign(ir->rhs);
1707b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   if (ir->condition)
1717b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt      ir->condition = convert_vec_index_to_cond_assign(ir->condition);
1727b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
1737b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   /* Last, handle the LHS */
1747b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   ir_dereference_array *orig_deref = ir->lhs->as_dereference_array();
1757b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
1767b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   if (!orig_deref ||
1777b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt       orig_deref->array->type->is_matrix() ||
1787b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt       orig_deref->array->type->is_array())
1797b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt      return visit_continue;
1807b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
181d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   void *mem_ctx = ralloc_parent(ir);
1828273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
1837b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
1847b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
185601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   exec_list list;
186601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick
1877b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   /* Store the index to a temporary to avoid reusing its tree. */
1887e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick   index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i",
1897e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick			       ir_var_temporary);
190601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   list.push_tail(index);
1917b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   deref = new(ir) ir_dereference_variable(index);
1927b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL);
193601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   list.push_tail(assign);
1947b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
1957b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   /* Store the RHS to a temporary to avoid reusing its tree. */
1967e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick   var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v",
1977e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick			     ir_var_temporary);
198601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   list.push_tail(var);
1997b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   deref = new(ir) ir_dereference_variable(var);
2007b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   assign = new(ir) ir_assignment(deref, ir->rhs, NULL);
201601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   list.push_tail(assign);
2027b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
2036c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   /* Generate a single comparison condition "mask" for all of the components
2046c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    * in the vector.
2056c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick    */
2066c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick   ir_rvalue *const cond_deref =
2076c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      compare_index_block(&list, index, 0,
2086c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick			  orig_deref->array->type->vector_elements,
2096c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick			  mem_ctx);
2106c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick
2117b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   /* Generate a conditional move of each vector element to the temp. */
2127b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
2136c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      ir_rvalue *condition_swizzle =
2146c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick	 new(ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1);
2157b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
2167b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
2177b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt      /* Just clone the rest of the deref chain when trying to get at the
2187b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt       * underlying variable.
2197b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt       */
2206c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      ir_rvalue *swizzle =
2216c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick	 new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
2226c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick			    i, 0, 0, 0, 1);
2237b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
2247b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt      deref = new(ir) ir_dereference_variable(var);
2256c8f1f483a999005cae1da5b54cc8ca1904e7ce7Ian Romanick      assign = new(ir) ir_assignment(swizzle, deref, condition_swizzle);
226601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      list.push_tail(assign);
2277b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   }
228601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick
229601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   /* If the original assignment has a condition, respect that original
230601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick    * condition!  This is acomplished by wrapping the new conditional
231601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick    * assignments in an if-statement that uses the original condition.
232601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick    */
233601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   if (ir->condition != NULL) {
234601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      /* No need to clone the condition because the IR that it hangs on is
235601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick       * going to be removed from the instruction sequence.
236601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick       */
237601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      ir_if *if_stmt = new(mem_ctx) ir_if(ir->condition);
238601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick
239601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      list.move_nodes_to(&if_stmt->then_instructions);
240601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      ir->insert_before(if_stmt);
241601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   } else {
242601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick      ir->insert_before(&list);
243601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick   }
244601428d2bbcf650c746f7a10b47228948f0ea912Ian Romanick
2457b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   ir->remove();
2467b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt
2477b96b474e06f83bf4abec42b3a9cb2dee0ea1b68Eric Anholt   this->progress = true;
248a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
249a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
250a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
251a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
252a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
253a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir)
254a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
255a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
256a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      ir_rvalue *param = (ir_rvalue *)iter.get();
257a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      ir_rvalue *new_param = convert_vec_index_to_cond_assign(param);
258a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
259a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      if (new_param != param) {
260c7a18da69022d3f9b05c21ff2473e8ea390f77f1Kenneth Graunke	 param->replace_with(new_param);
261a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      }
262a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   }
263a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
264a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
265a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
266a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
267a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
268a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir)
269a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
270a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   if (ir->value) {
271a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt      ir->value = convert_vec_index_to_cond_assign(ir->value);
272a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   }
273a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
274a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
275a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
276a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
277a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_visitor_status
278a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir)
279a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
280a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir->condition = convert_vec_index_to_cond_assign(ir->condition);
281a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
282a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return visit_continue;
283a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
284a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
285a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtbool
286a36334be02cb0a2b834667116bfeb680bf365857Eric Anholtdo_vec_index_to_cond_assign(exec_list *instructions)
287a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt{
288a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   ir_vec_index_to_cond_assign_visitor v;
289a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
290a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   visit_list_elements(&v, instructions);
291a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
292a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt   return v.progress;
293a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt}
294