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