1 #include "ir/lima_ir.h"
2 
3 #include "nir.h"
4 #include "nir_builder.h"
5 #include "nir_search.h"
6 #include "nir_search_helpers.h"
7 
8 /* What follows is NIR algebraic transform code for the following 2
9  * transforms:
10  *    ('fsin', 'a') => ('fsin', ('fmul', 'a', 0.15915494309189535))
11  *    ('fcos', 'a') => ('fcos', ('fmul', 'a', 0.15915494309189535))
12  */
13 
14 
15    static const nir_search_variable search0_0 = {
16    { nir_search_value_variable, -1 },
17    0, /* a */
18    false,
19    nir_type_invalid,
20    NULL,
21    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
22 };
23 static const nir_search_expression search0 = {
24    { nir_search_value_expression, -1 },
25    false, false,
26    -1, 0,
27    nir_op_fsin,
28    { &search0_0.value },
29    NULL,
30 };
31 
32    /* replace0_0_0 -> search0_0 in the cache */
33 
34 static const nir_search_constant replace0_0_1 = {
35    { nir_search_value_constant, -1 },
36    nir_type_float, { 0x3fc45f306dc9c883 /* 0.159154943092 */ },
37 };
38 static const nir_search_expression replace0_0 = {
39    { nir_search_value_expression, -1 },
40    false, false,
41    0, 1,
42    nir_op_fmul,
43    { &search0_0.value, &replace0_0_1.value },
44    NULL,
45 };
46 static const nir_search_expression replace0 = {
47    { nir_search_value_expression, -1 },
48    false, false,
49    -1, 1,
50    nir_op_fsin,
51    { &replace0_0.value },
52    NULL,
53 };
54 
55    /* search1_0 -> search0_0 in the cache */
56 static const nir_search_expression search1 = {
57    { nir_search_value_expression, -1 },
58    false, false,
59    -1, 0,
60    nir_op_fcos,
61    { &search0_0.value },
62    NULL,
63 };
64 
65    /* replace1_0_0 -> search0_0 in the cache */
66 
67 /* replace1_0_1 -> replace0_0_1 in the cache */
68 /* replace1_0 -> replace0_0 in the cache */
69 static const nir_search_expression replace1 = {
70    { nir_search_value_expression, -1 },
71    false, false,
72    -1, 1,
73    nir_op_fcos,
74    { &replace0_0.value },
75    NULL,
76 };
77 
78 
79 static const struct transform lima_nir_scale_trig_state2_xforms[] = {
80   { &search0, &replace0.value, 0 },
81 };
82 static const struct transform lima_nir_scale_trig_state3_xforms[] = {
83   { &search1, &replace1.value, 0 },
84 };
85 
86 static const struct per_op_table lima_nir_scale_trig_table[nir_num_search_ops] = {
87    [nir_op_fsin] = {
88       .filter = (uint16_t []) {
89          0,
90          0,
91          0,
92          0,
93       },
94 
95       .num_filtered_states = 1,
96       .table = (uint16_t []) {
97 
98          2,
99       },
100    },
101    [nir_op_fcos] = {
102       .filter = (uint16_t []) {
103          0,
104          0,
105          0,
106          0,
107       },
108 
109       .num_filtered_states = 1,
110       .table = (uint16_t []) {
111 
112          3,
113       },
114    },
115 };
116 
117 const struct transform *lima_nir_scale_trig_transforms[] = {
118    NULL,
119    NULL,
120    lima_nir_scale_trig_state2_xforms,
121    lima_nir_scale_trig_state3_xforms,
122 };
123 
124 const uint16_t lima_nir_scale_trig_transform_counts[] = {
125    0,
126    0,
127    (uint16_t)ARRAY_SIZE(lima_nir_scale_trig_state2_xforms),
128    (uint16_t)ARRAY_SIZE(lima_nir_scale_trig_state3_xforms),
129 };
130 
131 bool
lima_nir_scale_trig(nir_shader * shader)132 lima_nir_scale_trig(nir_shader *shader)
133 {
134    bool progress = false;
135    bool condition_flags[1];
136    const nir_shader_compiler_options *options = shader->options;
137    const shader_info *info = &shader->info;
138    (void) options;
139    (void) info;
140 
141    condition_flags[0] = true;
142 
143    nir_foreach_function(function, shader) {
144       if (function->impl) {
145          progress |= nir_algebraic_impl(function->impl, condition_flags,
146                                         lima_nir_scale_trig_transforms,
147                                         lima_nir_scale_trig_transform_counts,
148                                         lima_nir_scale_trig_table);
149       }
150    }
151 
152    return progress;
153 }
154 
155 
156 #include "nir.h"
157 #include "nir_builder.h"
158 #include "nir_search.h"
159 #include "nir_search_helpers.h"
160 
161 /* What follows is NIR algebraic transform code for the following 1
162  * transforms:
163  *    ('ftrunc', 'a') => ('fmul', ('fsign', 'a'), ('ffloor', ('fmax', 'a', ('fneg', 'a'))))
164  */
165 
166 
167    static const nir_search_variable search2_0 = {
168    { nir_search_value_variable, -1 },
169    0, /* a */
170    false,
171    nir_type_invalid,
172    NULL,
173    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
174 };
175 static const nir_search_expression search2 = {
176    { nir_search_value_expression, -1 },
177    false, false,
178    -1, 0,
179    nir_op_ftrunc,
180    { &search2_0.value },
181    NULL,
182 };
183 
184    /* replace2_0_0 -> search2_0 in the cache */
185 static const nir_search_expression replace2_0 = {
186    { nir_search_value_expression, -1 },
187    false, false,
188    -1, 0,
189    nir_op_fsign,
190    { &search2_0.value },
191    NULL,
192 };
193 
194 /* replace2_1_0_0 -> search2_0 in the cache */
195 
196 /* replace2_1_0_1_0 -> search2_0 in the cache */
197 static const nir_search_expression replace2_1_0_1 = {
198    { nir_search_value_expression, -1 },
199    false, false,
200    -1, 0,
201    nir_op_fneg,
202    { &search2_0.value },
203    NULL,
204 };
205 static const nir_search_expression replace2_1_0 = {
206    { nir_search_value_expression, -1 },
207    false, false,
208    1, 1,
209    nir_op_fmax,
210    { &search2_0.value, &replace2_1_0_1.value },
211    NULL,
212 };
213 static const nir_search_expression replace2_1 = {
214    { nir_search_value_expression, -1 },
215    false, false,
216    -1, 1,
217    nir_op_ffloor,
218    { &replace2_1_0.value },
219    NULL,
220 };
221 static const nir_search_expression replace2 = {
222    { nir_search_value_expression, -1 },
223    false, false,
224    0, 2,
225    nir_op_fmul,
226    { &replace2_0.value, &replace2_1.value },
227    NULL,
228 };
229 
230 
231 static const struct transform lima_nir_lower_ftrunc_state2_xforms[] = {
232   { &search2, &replace2.value, 0 },
233 };
234 
235 static const struct per_op_table lima_nir_lower_ftrunc_table[nir_num_search_ops] = {
236    [nir_op_ftrunc] = {
237       .filter = (uint16_t []) {
238          0,
239          0,
240          0,
241       },
242 
243       .num_filtered_states = 1,
244       .table = (uint16_t []) {
245 
246          2,
247       },
248    },
249 };
250 
251 const struct transform *lima_nir_lower_ftrunc_transforms[] = {
252    NULL,
253    NULL,
254    lima_nir_lower_ftrunc_state2_xforms,
255 };
256 
257 const uint16_t lima_nir_lower_ftrunc_transform_counts[] = {
258    0,
259    0,
260    (uint16_t)ARRAY_SIZE(lima_nir_lower_ftrunc_state2_xforms),
261 };
262 
263 bool
lima_nir_lower_ftrunc(nir_shader * shader)264 lima_nir_lower_ftrunc(nir_shader *shader)
265 {
266    bool progress = false;
267    bool condition_flags[1];
268    const nir_shader_compiler_options *options = shader->options;
269    const shader_info *info = &shader->info;
270    (void) options;
271    (void) info;
272 
273    condition_flags[0] = true;
274 
275    nir_foreach_function(function, shader) {
276       if (function->impl) {
277          progress |= nir_algebraic_impl(function->impl, condition_flags,
278                                         lima_nir_lower_ftrunc_transforms,
279                                         lima_nir_lower_ftrunc_transform_counts,
280                                         lima_nir_lower_ftrunc_table);
281       }
282    }
283 
284    return progress;
285 }
286 
287