1370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott/*
2370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * Copyright © 2014 Intel Corporation
3370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *
4370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * Permission is hereby granted, free of charge, to any person obtaining a
5370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * copy of this software and associated documentation files (the "Software"),
6370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * to deal in the Software without restriction, including without limitation
7370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * and/or sell copies of the Software, and to permit persons to whom the
9370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * Software is furnished to do so, subject to the following conditions:
10370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *
11370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * The above copyright notice and this permission notice (including the next
12370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * paragraph) shall be included in all copies or substantial portions of the
13370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * Software.
14370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *
15370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * IN THE SOFTWARE.
22370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *
23370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott * Authors:
24370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *    Connor Abbott (cwabbott0@gmail.com)
25370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott *
26370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott */
27370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
28370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott#include "nir.h"
29370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
30370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottstatic void
31370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottadd_var_use_intrinsic(nir_intrinsic_instr *instr, struct set *live)
32370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
33370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   unsigned num_vars = nir_intrinsic_infos[instr->intrinsic].num_variables;
3413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
3513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   switch (instr->intrinsic) {
3613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   case nir_intrinsic_copy_var:
3713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      _mesa_set_add(live, instr->variables[1]->var);
3813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      /* Fall through */
3913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   case nir_intrinsic_store_var: {
4013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      /* The first source in both copy_var and store_var is the destination.
4113a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand       * If the variable is a local that never escapes the shader, then we
4213a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand       * don't mark it as live for just a store.
4313a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand       */
4413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      nir_variable_mode mode = instr->variables[0]->var->data.mode;
4513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      if (!(mode & (nir_var_local | nir_var_global | nir_var_shared)))
4613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         _mesa_set_add(live, instr->variables[0]->var);
4713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      break;
4813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   }
4913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
5013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   default:
5113a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      for (unsigned i = 0; i < num_vars; i++) {
5213a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         _mesa_set_add(live, instr->variables[i]->var);
5313a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      }
5413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      break;
55370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
56370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
57370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
58370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottstatic void
59370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottadd_var_use_call(nir_call_instr *instr, struct set *live)
60370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
61370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   if (instr->return_deref != NULL) {
62370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott      nir_variable *var = instr->return_deref->var;
63153b8b35257fb5d68735b5e43e48b0cdb8b15170Jason Ekstrand      _mesa_set_add(live, var);
64370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
65370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
66370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   for (unsigned i = 0; i < instr->num_params; i++) {
67370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott      nir_variable *var = instr->params[i]->var;
68153b8b35257fb5d68735b5e43e48b0cdb8b15170Jason Ekstrand      _mesa_set_add(live, var);
69370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
70370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
71370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
72370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottstatic void
73370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottadd_var_use_tex(nir_tex_instr *instr, struct set *live)
74370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
75ee85014b90af1d94d637ec763a803479e9bac5dcJason Ekstrand   if (instr->texture != NULL) {
76ee85014b90af1d94d637ec763a803479e9bac5dcJason Ekstrand      nir_variable *var = instr->texture->var;
77153b8b35257fb5d68735b5e43e48b0cdb8b15170Jason Ekstrand      _mesa_set_add(live, var);
78370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
795ec456375e4fdd0b6c7d797f99191044e19ead74Jason Ekstrand
805ec456375e4fdd0b6c7d797f99191044e19ead74Jason Ekstrand   if (instr->sampler != NULL) {
815ec456375e4fdd0b6c7d797f99191044e19ead74Jason Ekstrand      nir_variable *var = instr->sampler->var;
825ec456375e4fdd0b6c7d797f99191044e19ead74Jason Ekstrand      _mesa_set_add(live, var);
835ec456375e4fdd0b6c7d797f99191044e19ead74Jason Ekstrand   }
84370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
85370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
86370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottstatic void
87370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbottadd_var_use_shader(nir_shader *shader, struct set *live)
88370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
899464d8c49813aba77285e7465b96e92a91ed327cJason Ekstrand   nir_foreach_function(function, shader) {
90237f2f2d8b45d9d956102eec6f9be63193e5269bJason Ekstrand      if (function->impl) {
91db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott         nir_foreach_block(block, function->impl) {
92707e72f13bb78869ee95d3286980bf1709cba6cfJason Ekstrand            nir_foreach_instr(instr, block) {
93db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               switch(instr->type) {
94db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               case nir_instr_type_intrinsic:
95db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  add_var_use_intrinsic(nir_instr_as_intrinsic(instr), live);
96db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  break;
97db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott
98db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               case nir_instr_type_call:
99db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  add_var_use_call(nir_instr_as_call(instr), live);
100db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  break;
101db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott
102db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               case nir_instr_type_tex:
103db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  add_var_use_tex(nir_instr_as_tex(instr), live);
104db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  break;
105db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott
106db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               default:
107db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott                  break;
108db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott               }
109db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott            }
110db3517777254fe82413d3bf5b70a328a37222c8bConnor Abbott         }
111370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott      }
112370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
113370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
114370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
11513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrandstatic void
11613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrandremove_dead_var_writes(nir_shader *shader, struct set *live)
11713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand{
11813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   nir_foreach_function(function, shader) {
11913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      if (!function->impl)
12013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         continue;
12113a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
12213a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      nir_foreach_block(block, function->impl) {
12313a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         nir_foreach_instr_safe(instr, block) {
12413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            if (instr->type != nir_instr_type_intrinsic)
12513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand               continue;
12613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
12713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
12813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            if (intrin->intrinsic != nir_intrinsic_copy_var &&
12913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand                intrin->intrinsic != nir_intrinsic_store_var)
13013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand               continue;
13113a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
13213a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            /* Stores to dead variables need to be removed */
13313a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            if (intrin->variables[0]->var->data.mode == 0)
13413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand               nir_instr_remove(instr);
13513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         }
13613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      }
13713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   }
13813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand}
13913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
1401adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunkestatic bool
141f4e449108060dcaea1b4e1e445b76a8ef43d3a05Kenneth Graunkeremove_dead_vars(struct exec_list *var_list, struct set *live)
142370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
1431adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke   bool progress = false;
1441adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke
145f4e449108060dcaea1b4e1e445b76a8ef43d3a05Kenneth Graunke   foreach_list_typed_safe(nir_variable, var, node, var_list) {
146153b8b35257fb5d68735b5e43e48b0cdb8b15170Jason Ekstrand      struct set_entry *entry = _mesa_set_search(live, var);
147f61b6c3e48071991c098aa588ee86473f419d5c0Kenneth Graunke      if (entry == NULL) {
14813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         /* Mark this variable as used by setting the mode to 0 */
14913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         var->data.mode = 0;
150370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott         exec_node_remove(&var->node);
1511adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke         progress = true;
152f61b6c3e48071991c098aa588ee86473f419d5c0Kenneth Graunke      }
153370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
1541adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke
1551adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke   return progress;
156370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
157370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
1581adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunkebool
159b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrandnir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes)
160370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott{
1611adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke   bool progress = false;
162370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   struct set *live =
163153b8b35257fb5d68735b5e43e48b0cdb8b15170Jason Ekstrand      _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
164370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
165370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   add_var_use_shader(shader, live);
166370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
167b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_uniform)
168b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand      progress = remove_dead_vars(&shader->uniforms, live) || progress;
169370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
170b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_shader_in)
171b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand      progress = remove_dead_vars(&shader->inputs, live) || progress;
172b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand
173b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_shader_out)
174b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand      progress = remove_dead_vars(&shader->outputs, live) || progress;
175b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand
176b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_global)
177b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand      progress = remove_dead_vars(&shader->globals, live) || progress;
178b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand
179b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_system_value)
180b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand      progress = remove_dead_vars(&shader->system_values, live) || progress;
181b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand
18258fe5c57cd424889fd0a655cc4c19569ad7ba960Jason Ekstrand   if (modes & nir_var_shared)
18358fe5c57cd424889fd0a655cc4c19569ad7ba960Jason Ekstrand      progress = remove_dead_vars(&shader->shared, live) || progress;
18458fe5c57cd424889fd0a655cc4c19569ad7ba960Jason Ekstrand
185b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand   if (modes & nir_var_local) {
1869464d8c49813aba77285e7465b96e92a91ed327cJason Ekstrand      nir_foreach_function(function, shader) {
187b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand         if (function->impl) {
18813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            if (remove_dead_vars(&function->impl->locals, live))
189b63a98b1211d22f759ae9c80b2270fe2d3b2639eJason Ekstrand               progress = true;
19013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         }
19113a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      }
19213a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   }
19313a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
19413a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand   if (progress) {
19513a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      remove_dead_var_writes(shader, live);
19613a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand
19713a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand      nir_foreach_function(function, shader) {
19813a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand         if (function->impl) {
19913a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand            nir_metadata_preserve(function->impl, nir_metadata_block_index |
20013a2f207408442fcfe13396d6f218701a66a487cJason Ekstrand                                                  nir_metadata_dominance);
2014cb7546066f3f06b8030b8fce78f82469b0c6980Kenneth Graunke         }
2024cb7546066f3f06b8030b8fce78f82469b0c6980Kenneth Graunke      }
203370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   }
204370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott
205370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott   _mesa_set_destroy(live, NULL);
2061adde5b87e43b1512c0744c412d51cbc0078329bKenneth Graunke   return progress;
207370e875b32ebc7b2989fbc590b29e2d8dcb74913Connor Abbott}
208