2 * Copyright © 2015 Broadcom
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:
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
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
24 #include "util/macros.h"
26 #include "nir_builder.h"
28 /** @file nir_lower_load_const_to_scalar.c
30 * Replaces vector nir_load_const instructions with a series of loads and a
31 * vec[234] to reconstruct the original vector (on the assumption that
32 * nir_lower_alu_to_scalar() will then be used to split it up).
34 * This gives NIR a chance to CSE more operations on a scalar shader, when the
35 * same value was used in different vector contant loads.
39 lower_load_const_instr_scalar(nir_load_const_instr
*lower
)
41 if (lower
->def
.num_components
== 1)
45 nir_builder_init(&b
, nir_cf_node_get_function(&lower
->instr
.block
->cf_node
));
46 b
.cursor
= nir_before_instr(&lower
->instr
);
48 /* Emit the individual loads. */
49 nir_ssa_def
*loads
[NIR_MAX_VEC_COMPONENTS
];
50 for (unsigned i
= 0; i
< lower
->def
.num_components
; i
++) {
51 nir_load_const_instr
*load_comp
=
52 nir_load_const_instr_create(b
.shader
, 1, lower
->def
.bit_size
);
53 switch (lower
->def
.bit_size
) {
55 load_comp
->value
.u64
[0] = lower
->value
.u64
[i
];
58 load_comp
->value
.u32
[0] = lower
->value
.u32
[i
];
61 load_comp
->value
.u16
[0] = lower
->value
.u16
[i
];
64 load_comp
->value
.u8
[0] = lower
->value
.u8
[i
];
67 load_comp
->value
.b
[0] = lower
->value
.b
[i
];
70 assert(!"invalid bit size");
72 nir_builder_instr_insert(&b
, &load_comp
->instr
);
73 loads
[i
] = &load_comp
->def
;
76 /* Batch things back together into a vector. */
77 nir_ssa_def
*vec
= nir_vec(&b
, loads
, lower
->def
.num_components
);
79 /* Replace the old load with a reference to our reconstructed vector. */
80 nir_ssa_def_rewrite_uses(&lower
->def
, nir_src_for_ssa(vec
));
81 nir_instr_remove(&lower
->instr
);
86 nir_lower_load_const_to_scalar_impl(nir_function_impl
*impl
)
88 bool progress
= false;
90 nir_foreach_block(block
, impl
) {
91 nir_foreach_instr_safe(instr
, block
) {
92 if (instr
->type
== nir_instr_type_load_const
)
94 lower_load_const_instr_scalar(nir_instr_as_load_const(instr
));
99 nir_metadata_preserve(impl
, nir_metadata_block_index
|
100 nir_metadata_dominance
);
103 impl
->valid_metadata
&= ~nir_metadata_not_properly_reset
;
111 nir_lower_load_const_to_scalar(nir_shader
*shader
)
113 bool progress
= false;
115 nir_foreach_function(function
, shader
) {
117 progress
|= nir_lower_load_const_to_scalar_impl(function
->impl
);