nir: Add a new memory_barrier_tcs_patch intrinsic
[mesa.git] / src / compiler / nir / nir_gather_ssa_types.c
1 /*
2 * Copyright © 2019 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 "util/bitset.h"
26
27 static void
28 set_type(unsigned idx, nir_alu_type type, BITSET_WORD *float_types,
29 BITSET_WORD *int_types, bool *progress)
30 {
31 switch (nir_alu_type_get_base_type(type)) {
32 case nir_type_bool:
33 case nir_type_int:
34 case nir_type_uint:
35 if (int_types && !BITSET_TEST(int_types, idx)) {
36 *progress = true;
37 BITSET_SET(int_types, idx);
38 }
39 break;
40
41 case nir_type_float:
42 if (float_types && !BITSET_TEST(float_types, idx)) {
43 *progress = true;
44 BITSET_SET(float_types, idx);
45 }
46 break;
47
48 default:
49 unreachable("Invalid base nir_alu_type");
50 }
51 }
52
53 static void
54 copy_type(unsigned src, unsigned dst, bool src_is_sink,
55 BITSET_WORD *types, bool *progress)
56 {
57 if (!types)
58 return;
59
60 if (BITSET_TEST(types, dst)) {
61 if (BITSET_TEST(types, src))
62 return;
63 BITSET_SET(types, src);
64 *progress = true;
65 } else if (BITSET_TEST(types, src) && !src_is_sink) {
66 BITSET_SET(types, dst);
67 *progress = true;
68 }
69 }
70
71 static void
72 copy_types(nir_src src, nir_dest *dest, BITSET_WORD *float_types,
73 BITSET_WORD *int_types, bool *progress)
74 {
75 bool src_is_sink = nir_src_is_const(src) ||
76 src.ssa->parent_instr->type == nir_instr_type_ssa_undef;
77 copy_type(src.ssa->index, dest->ssa.index, src_is_sink, float_types, progress);
78 copy_type(src.ssa->index, dest->ssa.index, src_is_sink, int_types, progress);
79 }
80
81 /** Gather up ALU types for SSA values
82 *
83 * This pass attempts to determine, for each SSA value, the type of data (int
84 * or float) that will be stored in it. The pass is greedy in the sense that
85 * it just assigns intness or floatness to types without any attempt to sort
86 * out the interesting cases where a given type may be both.
87 *
88 * The output of the pass is a pair of bitsets which has the intness or
89 * floatness of each SSA value recorded by index. It is the responsibility of
90 * the caller to index the SSA defs using nir_index_ssa_defs and allocate the
91 * bitsets. Either bitset is allowed to be NULL in which case no data is
92 * recorded for that type.
93 */
94 void
95 nir_gather_ssa_types(nir_function_impl *impl,
96 BITSET_WORD *float_types,
97 BITSET_WORD *int_types)
98 {
99 bool progress;
100 do {
101 progress = false;
102
103 nir_foreach_block(block, impl) {
104 nir_foreach_instr(instr, block) {
105 switch (instr->type) {
106 case nir_instr_type_alu: {
107 nir_alu_instr *alu = nir_instr_as_alu(instr);
108 assert(alu->dest.dest.is_ssa);
109 const nir_op_info *info = &nir_op_infos[alu->op];
110 switch (alu->op) {
111 case nir_op_mov:
112 case nir_op_vec2:
113 case nir_op_vec3:
114 case nir_op_vec4:
115 for (unsigned i = 0; i < info->num_inputs; i++) {
116 copy_types(alu->src[i].src, &alu->dest.dest,
117 float_types, int_types, &progress);
118 }
119 break;
120
121 case nir_op_bcsel:
122 case nir_op_b32csel:
123 set_type(alu->src[0].src.ssa->index, nir_type_bool,
124 float_types, int_types, &progress);
125 copy_types(alu->src[1].src, &alu->dest.dest,
126 float_types, int_types, &progress);
127 copy_types(alu->src[2].src, &alu->dest.dest,
128 float_types, int_types, &progress);
129 break;
130
131 default:
132 for (unsigned i = 0; i < info->num_inputs; i++) {
133 assert(alu->src[i].src.is_ssa);
134 set_type(alu->src[i].src.ssa->index, info->input_types[i],
135 float_types, int_types, &progress);
136 }
137 set_type(alu->dest.dest.ssa.index, info->output_type,
138 float_types, int_types, &progress);
139 }
140 break;
141 }
142
143 case nir_instr_type_tex: {
144 nir_tex_instr *tex = nir_instr_as_tex(instr);
145 for (unsigned i = 0; i < tex->num_srcs; i++) {
146 assert(tex->src[i].src.is_ssa);
147 set_type(tex->src[i].src.ssa->index,
148 nir_tex_instr_src_type(tex, i),
149 float_types, int_types, &progress);
150 }
151 assert(tex->dest.is_ssa);
152 set_type(tex->dest.ssa.index, tex->dest_type,
153 float_types, int_types, &progress);
154 break;
155 }
156
157 case nir_instr_type_intrinsic: {
158 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
159 /* We could go nuts here, but we'll just handle a few simple
160 * cases and let everything else be untyped.
161 */
162 switch (intrin->intrinsic) {
163 case nir_intrinsic_load_deref: {
164 nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
165
166 assert(intrin->dest.is_ssa);
167 set_type(intrin->dest.ssa.index,
168 nir_get_nir_type_for_glsl_type(deref->type),
169 float_types, int_types, &progress);
170 break;
171 }
172
173 case nir_intrinsic_store_deref: {
174 nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
175
176 assert(intrin->src[1].is_ssa);
177 set_type(intrin->src[1].ssa->index,
178 nir_get_nir_type_for_glsl_type(deref->type),
179 float_types, int_types, &progress);
180 break;
181 }
182
183 case nir_intrinsic_load_input:
184 case nir_intrinsic_load_uniform:
185 assert(intrin->dest.is_ssa);
186 set_type(intrin->dest.ssa.index,
187 nir_intrinsic_type(intrin),
188 float_types, int_types, &progress);
189 break;
190
191 case nir_intrinsic_store_output:
192 assert(intrin->src[0].is_ssa);
193 set_type(intrin->src[0].ssa->index,
194 nir_intrinsic_type(intrin),
195 float_types, int_types, &progress);
196 break;
197
198 default:
199 break;
200 }
201
202 /* For the most part, we leave other intrinsics alone. Most
203 * of them don't matter in OpenGL ES 2.0 drivers anyway.
204 * However, we should at least check if this is some sort of
205 * IO intrinsic and flag it's offset and index sources.
206 */
207 nir_src *offset_src = nir_get_io_offset_src(intrin);
208 if (offset_src) {
209 assert(offset_src->is_ssa);
210 set_type(offset_src->ssa->index, nir_type_int,
211 float_types, int_types, &progress);
212 }
213 break;
214 }
215
216 case nir_instr_type_phi: {
217 nir_phi_instr *phi = nir_instr_as_phi(instr);
218 assert(phi->dest.is_ssa);
219 nir_foreach_phi_src(src, phi) {
220 copy_types(src->src, &phi->dest,
221 float_types, int_types, &progress);
222 }
223 break;
224 }
225
226 default:
227 break;
228 }
229 }
230 }
231 } while (progress);
232 }