160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt/*
260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * Copyright © 2010 Intel Corporation
360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt *
460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * copy of this software and associated documentation files (the "Software"),
660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * to deal in the Software without restriction, including without limitation
760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * Software is furnished to do so, subject to the following conditions:
1060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt *
1160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * The above copyright notice and this permission notice (including the next
1260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * Software.
1460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt *
1560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * DEALINGS IN THE SOFTWARE.
2260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt */
2360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
2460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt/**
2560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * \file opt_array_splitting.cpp
2660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt *
2760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * If an array is always dereferenced with a constant index, then
2860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * split it apart into its elements, making it more amenable to other
2960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * optimization passes.
3060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt *
3160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * This skips uniform/varying arrays, which would need careful
3260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * handling due to their ir->location fields tying them to the GL API
3360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * and other shader stages.
3460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt */
3560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
3660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt#include "ir.h"
3760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt#include "ir_visitor.h"
3860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt#include "ir_rvalue_visitor.h"
3924f984f64ae58c274f79eaf9148aea37df67131cEmil Velikov#include "compiler/glsl_types.h"
4060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
4160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtstatic bool debug = false;
4260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
4310ef949424809d51c627008bb2feab5a067f8e08Eric Anholtnamespace {
4410ef949424809d51c627008bb2feab5a067f8e08Eric Anholt
4560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtnamespace opt_array_splitting {
4660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
4760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtclass variable_entry : public exec_node
4860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
4960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtpublic:
5060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry(ir_variable *var)
5160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   {
5260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->var = var;
53538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt      this->split = true;
5460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->declaration = false;
5560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->components = NULL;
5660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->mem_ctx = NULL;
573bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      if (var->type->is_array())
58283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         this->size = var->type->length;
593bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      else
60283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         this->size = var->type->matrix_columns;
6160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
6260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
6360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_variable *var; /* The key: the variable's pointer. */
643bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt   unsigned size; /* array length or matrix columns */
6560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
66538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt   /** Whether this array should be split or not. */
67538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt   bool split;
6860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
696de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   /* If the variable had a decl we can work with in the instruction
706de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    * stream.  We can't do splitting on function arguments, which
716de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    * don't get this variable set.
726de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    */
736de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   bool declaration;
7460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
7560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_variable **components;
7660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
7760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /** ralloc_parent(this->var) -- the shader's talloc context. */
7860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   void *mem_ctx;
7960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt};
8060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
8160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt} /* namespace */
8210ef949424809d51c627008bb2feab5a067f8e08Eric Anholt
8360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtusing namespace opt_array_splitting;
8460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
8560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt/**
8660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * This class does a walk over the tree, coming up with the set of
8760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * variables that could be split by looking to see if they are arrays
8860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt * that are only ever constant-index dereferenced.
8960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt */
9060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtclass ir_array_reference_visitor : public ir_hierarchical_visitor {
9160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtpublic:
9260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_array_reference_visitor(void)
9360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   {
9460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->mem_ctx = ralloc_context(NULL);
9560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->variable_list.make_empty();
96c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      this->in_whole_array_copy = false;
9760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
9860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
9960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ~ir_array_reference_visitor(void)
10060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   {
10160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      ralloc_free(mem_ctx);
10260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
10360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
10460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   bool get_split_list(exec_list *instructions, bool linked);
10560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
10660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   virtual ir_visitor_status visit(ir_variable *);
10760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   virtual ir_visitor_status visit(ir_dereference_variable *);
108c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   virtual ir_visitor_status visit_enter(ir_assignment *);
109c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   virtual ir_visitor_status visit_leave(ir_assignment *);
11060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   virtual ir_visitor_status visit_enter(ir_dereference_array *);
1116de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   virtual ir_visitor_status visit_enter(ir_function_signature *);
11260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
11360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *get_variable_entry(ir_variable *var);
11460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
11560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* List of variable_entry */
11660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   exec_list variable_list;
11760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
11860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   void *mem_ctx;
119c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
120c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   bool in_whole_array_copy;
12160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt};
12260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
12310ef949424809d51c627008bb2feab5a067f8e08Eric Anholt} /* namespace */
12410ef949424809d51c627008bb2feab5a067f8e08Eric Anholt
12560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtvariable_entry *
12660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_reference_visitor::get_variable_entry(ir_variable *var)
12760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
12860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   assert(var);
12960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
13033ee2c67c0a4e8f2fefbf37dacabd14918060af5Tapani Pälli   if (var->data.mode != ir_var_auto &&
13133ee2c67c0a4e8f2fefbf37dacabd14918060af5Tapani Pälli       var->data.mode != ir_var_temporary)
13260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return NULL;
13360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
1343bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt   if (!(var->type->is_array() || var->type->is_matrix()))
13560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return NULL;
13660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
13760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* If the array hasn't been sized yet, we can't split it.  After
13860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    * linking, this should be resolved.
13960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    */
140b59c5926cb0a5981a2e553c68e36312be7f122f9Timothy Arceri   if (var->type->is_unsized_array())
14160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return NULL;
14260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
1434d78446d782e2d942b4cd0cd00a27bf922ccd479Matt Turner   foreach_in_list(variable_entry, entry, &this->variable_list) {
14460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      if (entry->var == var)
145283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         return entry;
14660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
14760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
14860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *entry = new(mem_ctx) variable_entry(var);
14960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   this->variable_list.push_tail(entry);
15060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return entry;
15160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
15260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
15360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
15460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_visitor_status
15560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_reference_visitor::visit(ir_variable *ir)
15660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
15760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *entry = this->get_variable_entry(ir);
15860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
15960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (entry)
16060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      entry->declaration = true;
16160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
16260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return visit_continue;
16360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
16460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
16560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_visitor_status
166c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunkeir_array_reference_visitor::visit_enter(ir_assignment *ir)
167c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke{
168c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   in_whole_array_copy =
169c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      ir->lhs->type->is_array() && ir->whole_variable_written();
170c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
171c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   return visit_continue;
172c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke}
173c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
174c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunkeir_visitor_status
175c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunkeir_array_reference_visitor::visit_leave(ir_assignment *ir)
176c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke{
177c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   in_whole_array_copy = false;
178c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
179c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   return visit_continue;
180c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke}
181c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
182c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunkeir_visitor_status
18360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_reference_visitor::visit(ir_dereference_variable *ir)
18460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
18560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *entry = this->get_variable_entry(ir->var);
18660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
187c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   /* Allow whole-array assignments on the LHS.  We can split those
188c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke    * by "unrolling" the assignment into component-wise assignments.
189c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke    */
190c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   if (in_assignee && in_whole_array_copy)
191c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      return visit_continue;
192c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
193538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt   /* If we made it to here without seeing an ir_dereference_array,
194538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt    * then the dereference of this array didn't have a constant index
195538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt    * (see the visit_continue_with_parent below), so we can't split
196538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt    * the variable.
19760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    */
19860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (entry)
199538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt      entry->split = false;
20060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
20160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return visit_continue;
20260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
20360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
20460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_visitor_status
20560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
20660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
20760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_dereference_variable *deref = ir->array->as_dereference_variable();
20860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!deref)
20960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return visit_continue;
21060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
21160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *entry = this->get_variable_entry(deref->var);
21260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
213538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt   /* If the access to the array has a variable index, we wouldn't
214538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt    * know which split variable this dereference should go to.
215538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt    */
2164a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga   if (!ir->array_index->as_constant()) {
2174a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga      if (entry)
2184a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga         entry->split = false;
2194a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga      /* This variable indexing could come from a different array dereference
2204a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       * that also has variable indexing, that is, something like a[b[a[b[0]]]].
2214a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       * If we return visit_continue_with_parent here for the first appearence
2224a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       * of a, then we can miss that b also has indirect indexing (if this is
2234a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       * the only place in the program where such indirect indexing into b
2244a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       * happens), so keep going.
2254a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga       */
2264a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga      return visit_continue;
2274a600024242be2b8684ab2cc215171f31db594b0Iago Toral Quiroga   }
22860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
229315c4c315e311674c840069174244eef97c92705Tapani Pälli   /* If the index is also array dereference, visit index. */
230315c4c315e311674c840069174244eef97c92705Tapani Pälli   if (ir->array_index->as_dereference_array())
231315c4c315e311674c840069174244eef97c92705Tapani Pälli      visit_enter(ir->array_index->as_dereference_array());
232315c4c315e311674c840069174244eef97c92705Tapani Pälli
23360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return visit_continue_with_parent;
23460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
23560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
2366de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholtir_visitor_status
2376de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholtir_array_reference_visitor::visit_enter(ir_function_signature *ir)
2386de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt{
2396de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   /* We don't have logic for array-splitting function arguments,
2406de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    * so just look at the body instructions and not the parameter
2416de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    * declarations.
2426de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt    */
2436de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   visit_list_elements(this, &ir->body);
2446de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt   return visit_continue_with_parent;
2456de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt}
2466de5da079682efd3f8887d3e0a7add7e70a5433dEric Anholt
24760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtbool
24860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_reference_visitor::get_split_list(exec_list *instructions,
249283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                                           bool linked)
25060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
25160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   visit_list_elements(this, instructions);
25260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
25360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* If the shaders aren't linked yet, we can't mess with global
25460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    * declarations, which need to be matched by name across shaders.
25560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    */
25660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!linked) {
2574d78446d782e2d942b4cd0cd00a27bf922ccd479Matt Turner      foreach_in_list(ir_instruction, node, instructions) {
258283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         ir_variable *var = node->as_variable();
259283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         if (var) {
260283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga            variable_entry *entry = get_variable_entry(var);
261283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga            if (entry)
262283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga               entry->remove();
263283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         }
26460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      }
26560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
26660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
26760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* Trim out variables we found that we can't split. */
268c6a16f6d0e489e6d2a1a75bcf34be00e892b3120Matt Turner   foreach_in_list_safe(variable_entry, entry, &variable_list) {
26960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      if (debug) {
270283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         printf("array %s@%p: decl %d, split %d\n",
271283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                entry->var->name, (void *) entry->var, entry->declaration,
272283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                entry->split);
27360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      }
27460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
275538ba0a36373d7d0bd047e6fc4ef4e6e8d8bb8d7Eric Anholt      if (!(entry->declaration && entry->split)) {
276283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         entry->remove();
27760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      }
27860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
27960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
28060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return !variable_list.is_empty();
28160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
28260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
28336a8c9caafef79524920120286649a0f53fe5228Eric Anholt/**
28436a8c9caafef79524920120286649a0f53fe5228Eric Anholt * This class rewrites the dereferences of arrays that have been split
28536a8c9caafef79524920120286649a0f53fe5228Eric Anholt * to use the newly created ir_variables for each component.
28636a8c9caafef79524920120286649a0f53fe5228Eric Anholt */
28760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtclass ir_array_splitting_visitor : public ir_rvalue_visitor {
28860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtpublic:
28960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_array_splitting_visitor(exec_list *vars)
29060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   {
29160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      this->variable_list = vars;
29260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
29360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
29460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   virtual ~ir_array_splitting_visitor()
29560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   {
29660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
29760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
29860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   virtual ir_visitor_status visit_leave(ir_assignment *);
29960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
30060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   void split_deref(ir_dereference **deref);
30160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   void handle_rvalue(ir_rvalue **rvalue);
30260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *get_splitting_entry(ir_variable *var);
30360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
30460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   exec_list *variable_list;
30560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt};
30660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
30760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtvariable_entry *
30860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
30960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
31060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   assert(var);
31160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
3124d78446d782e2d942b4cd0cd00a27bf922ccd479Matt Turner   foreach_in_list(variable_entry, entry, this->variable_list) {
31360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      if (entry->var == var) {
314283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         return entry;
31560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      }
31660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
31760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
31860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return NULL;
31960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
32060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
32160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtvoid
32260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_splitting_visitor::split_deref(ir_dereference **deref)
32360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
32460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_dereference_array *deref_array = (*deref)->as_dereference_array();
32560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!deref_array)
32660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return;
32760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
32860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_dereference_variable *deref_var = deref_array->array->as_dereference_variable();
32960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!deref_var)
33060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return;
33160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_variable *var = deref_var->var;
33260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
33360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   variable_entry *entry = get_splitting_entry(var);
33460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!entry)
33560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return;
33660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
33760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_constant *constant = deref_array->array_index->as_constant();
33860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   assert(constant);
33960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
3406f0089e92e9a3b096b978bb09a87db6a38acb7b2Anuj Phogat   if (constant->value.i[0] >= 0 && constant->value.i[0] < (int)entry->size) {
34160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      *deref = new(entry->mem_ctx)
342283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga               ir_dereference_variable(entry->components[constant->value.i[0]]);
34360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   } else {
34460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      /* There was a constant array access beyond the end of the
34560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt       * array.  This might have happened due to constant folding
34660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt       * after the initial parse.  This produces an undefined value,
34760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt       * but shouldn't crash.  Just give them an uninitialized
34860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt       * variable.
34960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt       */
35060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      ir_variable *temp = new(entry->mem_ctx) ir_variable(deref_array->type,
351283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                                                          "undef",
352283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                                                          ir_var_temporary);
35360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      entry->components[0]->insert_before(temp);
35460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      *deref = new(entry->mem_ctx) ir_dereference_variable(temp);
35560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
35660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
35760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
35860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtvoid
35960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
36060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
36160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!*rvalue)
36260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return;
36360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
36460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_dereference *deref = (*rvalue)->as_dereference();
36560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
36660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!deref)
36760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return;
36860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
36960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   split_deref(&deref);
37060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   *rvalue = deref;
37160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
37260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
37360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_visitor_status
37460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtir_array_splitting_visitor::visit_leave(ir_assignment *ir)
37560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
37660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* The normal rvalue visitor skips the LHS of assignments, but we
37760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    * need to process those just the same.
37860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    */
37960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_rvalue *lhs = ir->lhs;
38060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
381c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   /* "Unroll" any whole array assignments, creating assignments for
382c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke    * each array element.  Then, do splitting on each new assignment.
383c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke    */
384c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   if (lhs->type->is_array() && ir->whole_variable_written() &&
385c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke       get_splitting_entry(ir->whole_variable_written())) {
386c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      void *mem_ctx = ralloc_parent(ir);
387c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
388c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      for (unsigned i = 0; i < lhs->type->length; i++) {
389c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         ir_rvalue *lhs_i =
390c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke            new(mem_ctx) ir_dereference_array(ir->lhs->clone(mem_ctx, NULL),
391c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke                                              new(mem_ctx) ir_constant(i));
392c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         ir_rvalue *rhs_i =
393c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke            new(mem_ctx) ir_dereference_array(ir->rhs->clone(mem_ctx, NULL),
394c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke                                              new(mem_ctx) ir_constant(i));
395c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         ir_rvalue *condition_i =
396c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke            ir->condition ? ir->condition->clone(mem_ctx, NULL) : NULL;
397c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
398c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         ir_assignment *assign_i =
399c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke            new(mem_ctx) ir_assignment(lhs_i, rhs_i, condition_i);
400c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
401c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         ir->insert_before(assign_i);
402c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke         assign_i->accept(this);
403c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      }
404c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      ir->remove();
405c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke      return visit_continue;
406c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke   }
407c264fdbc073a0dfc393f53a8be880f535fd4b988Kenneth Graunke
40860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   handle_rvalue(&lhs);
40960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir->lhs = lhs->as_dereference();
41060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
41160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir->lhs->accept(this);
41260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
41360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   handle_rvalue(&ir->rhs);
41460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir->rhs->accept(this);
41560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
41660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (ir->condition) {
41760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      handle_rvalue(&ir->condition);
41860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      ir->condition->accept(this);
41960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
42060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
42160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return visit_continue;
42260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
42360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
42460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtbool
42560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholtoptimize_split_arrays(exec_list *instructions, bool linked)
42660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt{
42760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_array_reference_visitor refs;
42860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (!refs.get_split_list(instructions, linked))
42960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      return false;
43060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
43160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   void *mem_ctx = ralloc_context(NULL);
43260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
43360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   /* Replace the decls of the arrays to be split with their split
43460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    * components.
43560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt    */
4364d78446d782e2d942b4cd0cd00a27bf922ccd479Matt Turner   foreach_in_list(variable_entry, entry, &refs.variable_list) {
43760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      const struct glsl_type *type = entry->var->type;
4383bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      const struct glsl_type *subtype;
4393bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt
4403bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      if (type->is_matrix())
441283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         subtype = type->column_type();
4423bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      else
443283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         subtype = type->fields.array;
44460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
44560177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      entry->mem_ctx = ralloc_parent(entry->var);
44660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
447283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga      entry->components = ralloc_array(mem_ctx, ir_variable *, entry->size);
44860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
4493bdccbc3e0185fbca16eada2a76f55c6e3f867b5Eric Anholt      for (unsigned int i = 0; i < entry->size; i++) {
450283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
451283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga                                            entry->var->name, i);
45260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
453283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         entry->components[i] =
454283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga            new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
455283c8372cb74c3728c7837a85480251313cf002bIago Toral Quiroga         entry->var->insert_before(entry->components[i]);
45660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      }
45760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
45860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt      entry->var->remove();
45960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   }
46060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
46160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ir_array_splitting_visitor split(&refs.variable_list);
46260177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   visit_list_elements(&split, instructions);
46360177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
46460177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   if (debug)
4651e3bd9f9a5af90295788c5d71ea27c61eb7bd984Eric Anholt      _mesa_print_ir(stdout, instructions, NULL);
46660177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
46760177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   ralloc_free(mem_ctx);
46860177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
46960177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt   return true;
47060177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt
47160177d5e2aec07ed6386a6935b118a356d58c4ecEric Anholt}
472