2 * Copyright © 2016 Intel Corporation
3 * Copyright © 2018 Valve Corporation
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * \file nir_opt_move_load_ubo.c
30 * This pass moves load UBO operations just before their first use inside
31 * the same basic block.
34 move_load_ubo_source(nir_src
*src
, nir_block
*block
, nir_instr
*before
)
39 nir_instr
*src_instr
= src
->ssa
->parent_instr
;
41 if (src_instr
->block
== block
&&
42 src_instr
->type
== nir_instr_type_intrinsic
&&
43 nir_instr_as_intrinsic(src_instr
)->intrinsic
== nir_intrinsic_load_ubo
) {
45 exec_node_remove(&src_instr
->node
);
48 exec_node_insert_node_before(&before
->node
, &src_instr
->node
);
50 exec_list_push_tail(&block
->instr_list
, &src_instr
->node
);
58 move_load_ubo_source_cb(nir_src
*src
, void *data
)
60 bool *progress
= data
;
62 nir_instr
*instr
= src
->parent_instr
;
63 if (move_load_ubo_source(src
, instr
->block
, instr
))
66 return true; /* nir_foreach_src should keep going */
70 move_load_ubo(nir_block
*block
)
72 bool progress
= false;
74 nir_if
*iff
= nir_block_get_following_if(block
);
76 progress
|= move_load_ubo_source(&iff
->condition
, block
, NULL
);
79 nir_foreach_instr_reverse(instr
, block
) {
81 if (instr
->type
== nir_instr_type_phi
) {
82 /* We're going backwards so everything else is a phi too */
83 } else if (instr
->type
== nir_instr_type_alu
) {
84 nir_alu_instr
*alu
= nir_instr_as_alu(instr
);
86 for (int i
= nir_op_infos
[alu
->op
].num_inputs
- 1; i
>= 0; i
--) {
87 progress
|= move_load_ubo_source(&alu
->src
[i
].src
, block
, instr
);
90 nir_foreach_src(instr
, move_load_ubo_source_cb
, &progress
);
98 nir_opt_move_load_ubo(nir_shader
*shader
)
100 bool progress
= false;
102 nir_foreach_function(func
, shader
) {
106 nir_foreach_block(block
, func
->impl
) {
107 if (move_load_ubo(block
)) {
108 nir_metadata_preserve(func
->impl
, nir_metadata_block_index
|
109 nir_metadata_dominance
|
110 nir_metadata_live_ssa_defs
);