1 /* 2 * Copyright 2016 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #include "nir.h" 25 #include "nir_builder.h" 26 27 static bool 28 deref_apply_constant_initializer(nir_deref_var *deref, void *state) 29 { 30 struct nir_builder *b = state; 31 32 nir_load_const_instr *initializer = 33 nir_deref_get_const_initializer_load(b->shader, deref); 34 nir_builder_instr_insert(b, &initializer->instr); 35 36 nir_store_deref_var(b, deref, &initializer->def, 0xf); 37 38 return true; 39 } 40 41 static bool 42 lower_const_initializer(struct nir_builder *b, struct exec_list *var_list) 43 { 44 bool progress = false; 45 46 b->cursor = nir_before_cf_list(&b->impl->body); 47 48 nir_foreach_variable(var, var_list) { 49 if (!var->constant_initializer) 50 continue; 51 52 progress = true; 53 54 nir_deref_var deref; 55 deref.deref.deref_type = nir_deref_type_var, 56 deref.deref.child = NULL; 57 deref.deref.type = var->type, 58 deref.var = var; 59 60 nir_deref_foreach_leaf(&deref, deref_apply_constant_initializer, b); 61 62 var->constant_initializer = NULL; 63 } 64 65 return progress; 66 } 67 68 bool 69 nir_lower_constant_initializers(nir_shader *shader, nir_variable_mode modes) 70 { 71 bool progress = false; 72 73 nir_builder builder; 74 if (modes & ~nir_var_local) 75 nir_builder_init(&builder, nir_shader_get_entrypoint(shader)); 76 77 if (modes & nir_var_shader_out) 78 progress |= lower_const_initializer(&builder, &shader->outputs); 79 80 if (modes & nir_var_global) 81 progress |= lower_const_initializer(&builder, &shader->globals); 82 83 if (modes & nir_var_system_value) 84 progress |= lower_const_initializer(&builder, &shader->system_values); 85 86 if (progress) { 87 nir_foreach_function(function, shader) { 88 if (function->impl) { 89 nir_metadata_preserve(function->impl, nir_metadata_block_index | 90 nir_metadata_dominance | 91 nir_metadata_live_ssa_defs); 92 } 93 } 94 } 95 96 if (modes & nir_var_local) { 97 nir_foreach_function(function, shader) { 98 if (!function->impl) 99 continue; 100 101 nir_builder_init(&builder, function->impl); 102 if (lower_const_initializer(&builder, &function->impl->locals)) { 103 nir_metadata_preserve(function->impl, nir_metadata_block_index | 104 nir_metadata_dominance | 105 nir_metadata_live_ssa_defs); 106 progress = true; 107 } 108 } 109 } 110 111 return progress; 112 } 113