1 /*
2 * Copyright © 2010 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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "ir.h"
25 #include "ir_hierarchical_visitor.h"
26
ir_hierarchical_visitor()27 ir_hierarchical_visitor::ir_hierarchical_visitor()
28 {
29 this->base_ir = NULL;
30 this->callback_enter = NULL;
31 this->callback_leave = NULL;
32 this->data_enter = NULL;
33 this->data_leave = NULL;
34 this->in_assignee = false;
35 }
36
37 ir_visitor_status
visit(ir_rvalue * ir)38 ir_hierarchical_visitor::visit(ir_rvalue *ir)
39 {
40 if (this->callback_enter != NULL)
41 this->callback_enter(ir, this->data_enter);
42
43 return visit_continue;
44 }
45
46 ir_visitor_status
visit(ir_variable * ir)47 ir_hierarchical_visitor::visit(ir_variable *ir)
48 {
49 if (this->callback_enter != NULL)
50 this->callback_enter(ir, this->data_enter);
51
52 return visit_continue;
53 }
54
55 ir_visitor_status
visit(ir_constant * ir)56 ir_hierarchical_visitor::visit(ir_constant *ir)
57 {
58 if (this->callback_enter != NULL)
59 this->callback_enter(ir, this->data_enter);
60
61 return visit_continue;
62 }
63
64 ir_visitor_status
visit(ir_loop_jump * ir)65 ir_hierarchical_visitor::visit(ir_loop_jump *ir)
66 {
67 if (this->callback_enter != NULL)
68 this->callback_enter(ir, this->data_enter);
69
70 return visit_continue;
71 }
72
73 ir_visitor_status
visit(ir_dereference_variable * ir)74 ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
75 {
76 if (this->callback_enter != NULL)
77 this->callback_enter(ir, this->data_enter);
78
79 return visit_continue;
80 }
81
82 ir_visitor_status
visit(ir_barrier * ir)83 ir_hierarchical_visitor::visit(ir_barrier *ir)
84 {
85 if (this->callback_enter != NULL)
86 this->callback_enter(ir, this->data_enter);
87
88 return visit_continue;
89 }
90
91 ir_visitor_status
visit_enter(ir_loop * ir)92 ir_hierarchical_visitor::visit_enter(ir_loop *ir)
93 {
94 if (this->callback_enter != NULL)
95 this->callback_enter(ir, this->data_enter);
96
97 return visit_continue;
98 }
99
100 ir_visitor_status
visit_leave(ir_loop * ir)101 ir_hierarchical_visitor::visit_leave(ir_loop *ir)
102 {
103 if (this->callback_leave != NULL)
104 this->callback_leave(ir, this->data_leave);
105
106 return visit_continue;
107 }
108
109 ir_visitor_status
visit_enter(ir_function_signature * ir)110 ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
111 {
112 if (this->callback_enter != NULL)
113 this->callback_enter(ir, this->data_enter);
114
115 return visit_continue;
116 }
117
118 ir_visitor_status
visit_leave(ir_function_signature * ir)119 ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
120 {
121 if (this->callback_leave != NULL)
122 this->callback_leave(ir, this->data_leave);
123
124 return visit_continue;
125 }
126
127 ir_visitor_status
visit_enter(ir_function * ir)128 ir_hierarchical_visitor::visit_enter(ir_function *ir)
129 {
130 if (this->callback_enter != NULL)
131 this->callback_enter(ir, this->data_enter);
132
133 return visit_continue;
134 }
135
136 ir_visitor_status
visit_leave(ir_function * ir)137 ir_hierarchical_visitor::visit_leave(ir_function *ir)
138 {
139 if (this->callback_leave != NULL)
140 this->callback_leave(ir, this->data_leave);
141
142 return visit_continue;
143 }
144
145 ir_visitor_status
visit_enter(ir_expression * ir)146 ir_hierarchical_visitor::visit_enter(ir_expression *ir)
147 {
148 if (this->callback_enter != NULL)
149 this->callback_enter(ir, this->data_enter);
150
151 return visit_continue;
152 }
153
154 ir_visitor_status
visit_leave(ir_expression * ir)155 ir_hierarchical_visitor::visit_leave(ir_expression *ir)
156 {
157 if (this->callback_leave != NULL)
158 this->callback_leave(ir, this->data_leave);
159
160 return visit_continue;
161 }
162
163 ir_visitor_status
visit_enter(ir_texture * ir)164 ir_hierarchical_visitor::visit_enter(ir_texture *ir)
165 {
166 if (this->callback_enter != NULL)
167 this->callback_enter(ir, this->data_enter);
168
169 return visit_continue;
170 }
171
172 ir_visitor_status
visit_leave(ir_texture * ir)173 ir_hierarchical_visitor::visit_leave(ir_texture *ir)
174 {
175 if (this->callback_leave != NULL)
176 this->callback_leave(ir, this->data_leave);
177
178 return visit_continue;
179 }
180
181 ir_visitor_status
visit_enter(ir_swizzle * ir)182 ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
183 {
184 if (this->callback_enter != NULL)
185 this->callback_enter(ir, this->data_enter);
186
187 return visit_continue;
188 }
189
190 ir_visitor_status
visit_leave(ir_swizzle * ir)191 ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
192 {
193 if (this->callback_leave != NULL)
194 this->callback_leave(ir, this->data_leave);
195
196 return visit_continue;
197 }
198
199 ir_visitor_status
visit_enter(ir_dereference_array * ir)200 ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
201 {
202 if (this->callback_enter != NULL)
203 this->callback_enter(ir, this->data_enter);
204
205 return visit_continue;
206 }
207
208 ir_visitor_status
visit_leave(ir_dereference_array * ir)209 ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
210 {
211 if (this->callback_leave != NULL)
212 this->callback_leave(ir, this->data_leave);
213
214 return visit_continue;
215 }
216
217 ir_visitor_status
visit_enter(ir_dereference_record * ir)218 ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
219 {
220 if (this->callback_enter != NULL)
221 this->callback_enter(ir, this->data_enter);
222
223 return visit_continue;
224 }
225
226 ir_visitor_status
visit_leave(ir_dereference_record * ir)227 ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
228 {
229 if (this->callback_leave != NULL)
230 this->callback_leave(ir, this->data_leave);
231
232 return visit_continue;
233 }
234
235 ir_visitor_status
visit_enter(ir_assignment * ir)236 ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
237 {
238 if (this->callback_enter != NULL)
239 this->callback_enter(ir, this->data_enter);
240
241 return visit_continue;
242 }
243
244 ir_visitor_status
visit_leave(ir_assignment * ir)245 ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
246 {
247 if (this->callback_leave != NULL)
248 this->callback_leave(ir, this->data_leave);
249
250 return visit_continue;
251 }
252
253 ir_visitor_status
visit_enter(ir_call * ir)254 ir_hierarchical_visitor::visit_enter(ir_call *ir)
255 {
256 if (this->callback_enter != NULL)
257 this->callback_enter(ir, this->data_enter);
258
259 return visit_continue;
260 }
261
262 ir_visitor_status
visit_leave(ir_call * ir)263 ir_hierarchical_visitor::visit_leave(ir_call *ir)
264 {
265 if (this->callback_leave != NULL)
266 this->callback_leave(ir, this->data_leave);
267
268 return visit_continue;
269 }
270
271 ir_visitor_status
visit_enter(ir_return * ir)272 ir_hierarchical_visitor::visit_enter(ir_return *ir)
273 {
274 if (this->callback_enter != NULL)
275 this->callback_enter(ir, this->data_enter);
276
277 return visit_continue;
278 }
279
280 ir_visitor_status
visit_leave(ir_return * ir)281 ir_hierarchical_visitor::visit_leave(ir_return *ir)
282 {
283 if (this->callback_leave != NULL)
284 this->callback_leave(ir, this->data_leave);
285
286 return visit_continue;
287 }
288
289 ir_visitor_status
visit_enter(ir_discard * ir)290 ir_hierarchical_visitor::visit_enter(ir_discard *ir)
291 {
292 if (this->callback_enter != NULL)
293 this->callback_enter(ir, this->data_enter);
294
295 return visit_continue;
296 }
297
298 ir_visitor_status
visit_leave(ir_discard * ir)299 ir_hierarchical_visitor::visit_leave(ir_discard *ir)
300 {
301 if (this->callback_leave != NULL)
302 this->callback_leave(ir, this->data_leave);
303
304 return visit_continue;
305 }
306
307 ir_visitor_status
visit_enter(ir_if * ir)308 ir_hierarchical_visitor::visit_enter(ir_if *ir)
309 {
310 if (this->callback_enter != NULL)
311 this->callback_enter(ir, this->data_enter);
312
313 return visit_continue;
314 }
315
316 ir_visitor_status
visit_leave(ir_if * ir)317 ir_hierarchical_visitor::visit_leave(ir_if *ir)
318 {
319 if (this->callback_leave != NULL)
320 this->callback_leave(ir, this->data_leave);
321
322 return visit_continue;
323 }
324
325 ir_visitor_status
visit_enter(ir_emit_vertex * ir)326 ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
327 {
328 if (this->callback_enter != NULL)
329 this->callback_enter(ir, this->data_enter);
330
331 return visit_continue;
332 }
333
334 ir_visitor_status
visit_leave(ir_emit_vertex * ir)335 ir_hierarchical_visitor::visit_leave(ir_emit_vertex *ir)
336 {
337 if (this->callback_leave != NULL)
338 this->callback_leave(ir, this->data_leave);
339
340 return visit_continue;
341 }
342
343 ir_visitor_status
visit_enter(ir_end_primitive * ir)344 ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
345 {
346 if (this->callback_enter != NULL)
347 this->callback_enter(ir, this->data_enter);
348
349 return visit_continue;
350 }
351
352 ir_visitor_status
visit_leave(ir_end_primitive * ir)353 ir_hierarchical_visitor::visit_leave(ir_end_primitive *ir)
354 {
355 if (this->callback_leave != NULL)
356 this->callback_leave(ir, this->data_leave);
357
358 return visit_continue;
359 }
360
361 void
run(exec_list * instructions)362 ir_hierarchical_visitor::run(exec_list *instructions)
363 {
364 visit_list_elements(this, instructions);
365 }
366
367
368 void
visit_tree(ir_instruction * ir,void (* callback_enter)(class ir_instruction * ir,void * data),void * data_enter,void (* callback_leave)(class ir_instruction * ir,void * data),void * data_leave)369 visit_tree(ir_instruction *ir,
370 void (*callback_enter)(class ir_instruction *ir, void *data),
371 void *data_enter,
372 void (*callback_leave)(class ir_instruction *ir, void *data),
373 void *data_leave)
374 {
375 ir_hierarchical_visitor v;
376
377 v.callback_enter = callback_enter;
378 v.callback_leave = callback_leave;
379 v.data_enter = data_enter;
380 v.data_leave = data_leave;
381
382 ir->accept(&v);
383 }
384