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