• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
deref_apply_constant_initializer(nir_deref_var * deref,void * state)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
lower_const_initializer(struct nir_builder * b,struct exec_list * var_list)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
nir_lower_constant_initializers(nir_shader * shader,nir_variable_mode modes)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