1 /*
2 * Copyright 2023 Intel Corporation
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "nir.h"
7 #include "nir_instr_set.h"
8
9 bool
nir_opt_reuse_constants(nir_shader * shader)10 nir_opt_reuse_constants(nir_shader *shader)
11 {
12 bool progress = false;
13
14 struct set *consts = nir_instr_set_create(NULL);
15 nir_foreach_function_impl(impl, shader) {
16 _mesa_set_clear(consts, NULL);
17
18 nir_block *start_block = nir_start_block(impl);
19 bool func_progress = false;
20
21 nir_foreach_block_safe(block, impl) {
22 const bool in_start_block = start_block == block;
23 nir_foreach_instr_safe(instr, block) {
24 if (instr->type != nir_instr_type_load_const)
25 continue;
26
27 struct set_entry *entry = _mesa_set_search(consts, instr);
28 if (!entry) {
29 if (!in_start_block)
30 nir_instr_move(nir_after_block_before_jump(start_block), instr);
31 _mesa_set_add(consts, instr);
32 }
33
34 if (nir_instr_set_add_or_rewrite(consts, instr, nir_instrs_equal)) {
35 func_progress = true;
36 nir_instr_remove(instr);
37 }
38 }
39 }
40
41 if (func_progress) {
42 nir_metadata_preserve(impl, nir_metadata_control_flow);
43 progress = true;
44 } else {
45 nir_metadata_preserve(impl, nir_metadata_all);
46 }
47 }
48
49 nir_instr_set_destroy(consts);
50 return progress;
51 }
52