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};
23static 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
34static const nir_search_constant replace0_0_1 = {
35   { nir_search_value_constant, -1 },
36   nir_type_float, { 0x3fc45f306dc9c883 /* 0.15915494309189535 */ },
37};
38static 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};
46static 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 */
56static 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 */
69static 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
79static const struct transform lima_nir_scale_trig_state2_xforms[] = {
80  { &search0, &replace0.value, 0 },
81};
82static const struct transform lima_nir_scale_trig_state3_xforms[] = {
83  { &search1, &replace1.value, 0 },
84};
85
86static 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
117const 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
124const 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
131bool
132lima_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};
175static 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 */
185static 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 */
197static 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};
205static 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};
213static 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};
221static 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
231static const struct transform lima_nir_lower_ftrunc_state2_xforms[] = {
232  { &search2, &replace2.value, 0 },
233};
234
235static 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
251const struct transform *lima_nir_lower_ftrunc_transforms[] = {
252   NULL,
253   NULL,
254   lima_nir_lower_ftrunc_state2_xforms,
255};
256
257const 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
263bool
264lima_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