glsl: Fix handling of function calls inside nested loops.
[mesa.git] / src / glsl / ir_hierarchical_visitor.cpp
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
27 ir_hierarchical_visitor::ir_hierarchical_visitor()
28 {
29 this->base_ir = NULL;
30 this->callback = NULL;
31 this->data = NULL;
32 this->in_assignee = false;
33 }
34
35 ir_visitor_status
36 ir_hierarchical_visitor::visit(ir_rvalue *ir)
37 {
38 if (this->callback != NULL)
39 this->callback(ir, this->data);
40
41 return visit_continue;
42 }
43
44 ir_visitor_status
45 ir_hierarchical_visitor::visit(ir_variable *ir)
46 {
47 if (this->callback != NULL)
48 this->callback(ir, this->data);
49
50 return visit_continue;
51 }
52
53 ir_visitor_status
54 ir_hierarchical_visitor::visit(ir_constant *ir)
55 {
56 if (this->callback != NULL)
57 this->callback(ir, this->data);
58
59 return visit_continue;
60 }
61
62 ir_visitor_status
63 ir_hierarchical_visitor::visit(ir_loop_jump *ir)
64 {
65 if (this->callback != NULL)
66 this->callback(ir, this->data);
67
68 return visit_continue;
69 }
70
71 ir_visitor_status
72 ir_hierarchical_visitor::visit(ir_emit_vertex *ir)
73 {
74 if (this->callback != NULL)
75 this->callback(ir, this->data);
76
77 return visit_continue;
78 }
79
80 ir_visitor_status
81 ir_hierarchical_visitor::visit(ir_end_primitive *ir)
82 {
83 if (this->callback != NULL)
84 this->callback(ir, this->data);
85
86 return visit_continue;
87 }
88
89 ir_visitor_status
90 ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
91 {
92 if (this->callback != NULL)
93 this->callback(ir, this->data);
94
95 return visit_continue;
96 }
97
98 ir_visitor_status
99 ir_hierarchical_visitor::visit_enter(ir_loop *ir)
100 {
101 if (this->callback != NULL)
102 this->callback(ir, this->data);
103
104 return visit_continue;
105 }
106
107 ir_visitor_status
108 ir_hierarchical_visitor::visit_leave(ir_loop *ir)
109 {
110 (void) ir;
111 return visit_continue;
112 }
113
114 ir_visitor_status
115 ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
116 {
117 if (this->callback != NULL)
118 this->callback(ir, this->data);
119
120 return visit_continue;
121 }
122
123 ir_visitor_status
124 ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
125 {
126 (void) ir;
127 return visit_continue;
128 }
129
130 ir_visitor_status
131 ir_hierarchical_visitor::visit_enter(ir_function *ir)
132 {
133 if (this->callback != NULL)
134 this->callback(ir, this->data);
135
136 return visit_continue;
137 }
138
139 ir_visitor_status
140 ir_hierarchical_visitor::visit_leave(ir_function *ir)
141 {
142 (void) ir;
143 return visit_continue;
144 }
145
146 ir_visitor_status
147 ir_hierarchical_visitor::visit_enter(ir_expression *ir)
148 {
149 if (this->callback != NULL)
150 this->callback(ir, this->data);
151
152 return visit_continue;
153 }
154
155 ir_visitor_status
156 ir_hierarchical_visitor::visit_leave(ir_expression *ir)
157 {
158 (void) ir;
159 return visit_continue;
160 }
161
162 ir_visitor_status
163 ir_hierarchical_visitor::visit_enter(ir_texture *ir)
164 {
165 if (this->callback != NULL)
166 this->callback(ir, this->data);
167
168 return visit_continue;
169 }
170
171 ir_visitor_status
172 ir_hierarchical_visitor::visit_leave(ir_texture *ir)
173 {
174 (void) ir;
175 return visit_continue;
176 }
177
178 ir_visitor_status
179 ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
180 {
181 if (this->callback != NULL)
182 this->callback(ir, this->data);
183
184 return visit_continue;
185 }
186
187 ir_visitor_status
188 ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
189 {
190 (void) ir;
191 return visit_continue;
192 }
193
194 ir_visitor_status
195 ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
196 {
197 if (this->callback != NULL)
198 this->callback(ir, this->data);
199
200 return visit_continue;
201 }
202
203 ir_visitor_status
204 ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
205 {
206 (void) ir;
207 return visit_continue;
208 }
209
210 ir_visitor_status
211 ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
212 {
213 if (this->callback != NULL)
214 this->callback(ir, this->data);
215
216 return visit_continue;
217 }
218
219 ir_visitor_status
220 ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
221 {
222 (void) ir;
223 return visit_continue;
224 }
225
226 ir_visitor_status
227 ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
228 {
229 if (this->callback != NULL)
230 this->callback(ir, this->data);
231
232 return visit_continue;
233 }
234
235 ir_visitor_status
236 ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
237 {
238 (void) ir;
239 return visit_continue;
240 }
241
242 ir_visitor_status
243 ir_hierarchical_visitor::visit_enter(ir_call *ir)
244 {
245 if (this->callback != NULL)
246 this->callback(ir, this->data);
247
248 return visit_continue;
249 }
250
251 ir_visitor_status
252 ir_hierarchical_visitor::visit_leave(ir_call *ir)
253 {
254 (void) ir;
255 return visit_continue;
256 }
257
258 ir_visitor_status
259 ir_hierarchical_visitor::visit_enter(ir_return *ir)
260 {
261 if (this->callback != NULL)
262 this->callback(ir, this->data);
263
264 return visit_continue;
265 }
266
267 ir_visitor_status
268 ir_hierarchical_visitor::visit_leave(ir_return *ir)
269 {
270 (void) ir;
271 return visit_continue;
272 }
273
274 ir_visitor_status
275 ir_hierarchical_visitor::visit_enter(ir_discard *ir)
276 {
277 if (this->callback != NULL)
278 this->callback(ir, this->data);
279
280 return visit_continue;
281 }
282
283 ir_visitor_status
284 ir_hierarchical_visitor::visit_leave(ir_discard *ir)
285 {
286 (void) ir;
287 return visit_continue;
288 }
289
290 ir_visitor_status
291 ir_hierarchical_visitor::visit_enter(ir_if *ir)
292 {
293 if (this->callback != NULL)
294 this->callback(ir, this->data);
295
296 return visit_continue;
297 }
298
299 ir_visitor_status
300 ir_hierarchical_visitor::visit_leave(ir_if *ir)
301 {
302 (void) ir;
303 return visit_continue;
304 }
305
306 void
307 ir_hierarchical_visitor::run(exec_list *instructions)
308 {
309 visit_list_elements(this, instructions);
310 }
311
312
313 void
314 visit_tree(ir_instruction *ir,
315 void (*callback)(class ir_instruction *ir, void *data),
316 void *data)
317 {
318 ir_hierarchical_visitor v;
319
320 v.callback = callback;
321 v.data = data;
322
323 ir->accept(&v);
324 }