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 /**
25  * \file ir_rvalue_visitor.cpp
26  *
27  * Generic class to implement the common pattern we have of wanting to
28  * visit each ir_rvalue * and possibly change that node to a different
29  * class.
30  */
31 
32 #include "ir.h"
33 #include "ir_visitor.h"
34 #include "ir_rvalue_visitor.h"
35 #include "compiler/glsl_types.h"
36 
37 ir_visitor_status
rvalue_visit(ir_expression * ir)38 ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir)
39 {
40    unsigned int operand;
41 
42    for (operand = 0; operand < ir->num_operands; operand++) {
43       handle_rvalue(&ir->operands[operand]);
44    }
45 
46    return visit_continue;
47 }
48 
49 ir_visitor_status
rvalue_visit(ir_texture * ir)50 ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
51 {
52    handle_rvalue(&ir->coordinate);
53    handle_rvalue(&ir->projector);
54    handle_rvalue(&ir->shadow_comparator);
55    handle_rvalue(&ir->offset);
56 
57    switch (ir->op) {
58    case ir_tex:
59    case ir_lod:
60    case ir_query_levels:
61    case ir_texture_samples:
62    case ir_samples_identical:
63       break;
64    case ir_txb:
65       handle_rvalue(&ir->lod_info.bias);
66       break;
67    case ir_txf:
68    case ir_txl:
69    case ir_txs:
70       handle_rvalue(&ir->lod_info.lod);
71       break;
72    case ir_txf_ms:
73       handle_rvalue(&ir->lod_info.sample_index);
74       break;
75    case ir_txd:
76       handle_rvalue(&ir->lod_info.grad.dPdx);
77       handle_rvalue(&ir->lod_info.grad.dPdy);
78       break;
79    case ir_tg4:
80       handle_rvalue(&ir->lod_info.component);
81       break;
82    }
83 
84    return visit_continue;
85 }
86 
87 ir_visitor_status
rvalue_visit(ir_swizzle * ir)88 ir_rvalue_base_visitor::rvalue_visit(ir_swizzle *ir)
89 {
90    handle_rvalue(&ir->val);
91    return visit_continue;
92 }
93 
94 ir_visitor_status
rvalue_visit(ir_dereference_array * ir)95 ir_rvalue_base_visitor::rvalue_visit(ir_dereference_array *ir)
96 {
97    /* The array index is not the target of the assignment, so clear the
98     * 'in_assignee' flag.  Restore it after returning from the array index.
99     */
100    const bool was_in_assignee = this->in_assignee;
101    this->in_assignee = false;
102    handle_rvalue(&ir->array_index);
103    this->in_assignee = was_in_assignee;
104 
105    handle_rvalue(&ir->array);
106    return visit_continue;
107 }
108 
109 ir_visitor_status
rvalue_visit(ir_dereference_record * ir)110 ir_rvalue_base_visitor::rvalue_visit(ir_dereference_record *ir)
111 {
112    handle_rvalue(&ir->record);
113    return visit_continue;
114 }
115 
116 ir_visitor_status
rvalue_visit(ir_assignment * ir)117 ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir)
118 {
119    handle_rvalue(&ir->rhs);
120    handle_rvalue(&ir->condition);
121 
122    return visit_continue;
123 }
124 
125 ir_visitor_status
rvalue_visit(ir_call * ir)126 ir_rvalue_base_visitor::rvalue_visit(ir_call *ir)
127 {
128    foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) {
129       ir_rvalue *new_param = param;
130       handle_rvalue(&new_param);
131 
132       if (new_param != param) {
133 	 param->replace_with(new_param);
134       }
135    }
136    return visit_continue;
137 }
138 
139 ir_visitor_status
rvalue_visit(ir_discard * ir)140 ir_rvalue_base_visitor::rvalue_visit(ir_discard *ir)
141 {
142    handle_rvalue(&ir->condition);
143    return visit_continue;
144 }
145 
146 ir_visitor_status
rvalue_visit(ir_return * ir)147 ir_rvalue_base_visitor::rvalue_visit(ir_return *ir)
148 {
149    handle_rvalue(&ir->value);
150    return visit_continue;
151 }
152 
153 ir_visitor_status
rvalue_visit(ir_if * ir)154 ir_rvalue_base_visitor::rvalue_visit(ir_if *ir)
155 {
156    handle_rvalue(&ir->condition);
157    return visit_continue;
158 }
159 
160 ir_visitor_status
rvalue_visit(ir_emit_vertex * ir)161 ir_rvalue_base_visitor::rvalue_visit(ir_emit_vertex *ir)
162 {
163    handle_rvalue(&ir->stream);
164    return visit_continue;
165 }
166 
167 ir_visitor_status
rvalue_visit(ir_end_primitive * ir)168 ir_rvalue_base_visitor::rvalue_visit(ir_end_primitive *ir)
169 {
170    handle_rvalue(&ir->stream);
171    return visit_continue;
172 }
173 
174 ir_visitor_status
visit_leave(ir_expression * ir)175 ir_rvalue_visitor::visit_leave(ir_expression *ir)
176 {
177    return rvalue_visit(ir);
178 }
179 
180 ir_visitor_status
visit_leave(ir_texture * ir)181 ir_rvalue_visitor::visit_leave(ir_texture *ir)
182 {
183    return rvalue_visit(ir);
184 }
185 
186 ir_visitor_status
visit_leave(ir_swizzle * ir)187 ir_rvalue_visitor::visit_leave(ir_swizzle *ir)
188 {
189    return rvalue_visit(ir);
190 }
191 
192 ir_visitor_status
visit_leave(ir_dereference_array * ir)193 ir_rvalue_visitor::visit_leave(ir_dereference_array *ir)
194 {
195    return rvalue_visit(ir);
196 }
197 
198 ir_visitor_status
visit_leave(ir_dereference_record * ir)199 ir_rvalue_visitor::visit_leave(ir_dereference_record *ir)
200 {
201    return rvalue_visit(ir);
202 }
203 
204 ir_visitor_status
visit_leave(ir_assignment * ir)205 ir_rvalue_visitor::visit_leave(ir_assignment *ir)
206 {
207    return rvalue_visit(ir);
208 }
209 
210 ir_visitor_status
visit_leave(ir_call * ir)211 ir_rvalue_visitor::visit_leave(ir_call *ir)
212 {
213    return rvalue_visit(ir);
214 }
215 
216 ir_visitor_status
visit_leave(ir_discard * ir)217 ir_rvalue_visitor::visit_leave(ir_discard *ir)
218 {
219    return rvalue_visit(ir);
220 }
221 
222 ir_visitor_status
visit_leave(ir_return * ir)223 ir_rvalue_visitor::visit_leave(ir_return *ir)
224 {
225    return rvalue_visit(ir);
226 }
227 
228 ir_visitor_status
visit_leave(ir_if * ir)229 ir_rvalue_visitor::visit_leave(ir_if *ir)
230 {
231    return rvalue_visit(ir);
232 }
233 
234 ir_visitor_status
visit_leave(ir_emit_vertex * ir)235 ir_rvalue_visitor::visit_leave(ir_emit_vertex *ir)
236 {
237    return rvalue_visit(ir);
238 }
239 
240 ir_visitor_status
visit_leave(ir_end_primitive * ir)241 ir_rvalue_visitor::visit_leave(ir_end_primitive *ir)
242 {
243    return rvalue_visit(ir);
244 }
245 
246 ir_visitor_status
visit_enter(ir_expression * ir)247 ir_rvalue_enter_visitor::visit_enter(ir_expression *ir)
248 {
249    return rvalue_visit(ir);
250 }
251 
252 ir_visitor_status
visit_enter(ir_texture * ir)253 ir_rvalue_enter_visitor::visit_enter(ir_texture *ir)
254 {
255    return rvalue_visit(ir);
256 }
257 
258 ir_visitor_status
visit_enter(ir_swizzle * ir)259 ir_rvalue_enter_visitor::visit_enter(ir_swizzle *ir)
260 {
261    return rvalue_visit(ir);
262 }
263 
264 ir_visitor_status
visit_enter(ir_dereference_array * ir)265 ir_rvalue_enter_visitor::visit_enter(ir_dereference_array *ir)
266 {
267    return rvalue_visit(ir);
268 }
269 
270 ir_visitor_status
visit_enter(ir_dereference_record * ir)271 ir_rvalue_enter_visitor::visit_enter(ir_dereference_record *ir)
272 {
273    return rvalue_visit(ir);
274 }
275 
276 ir_visitor_status
visit_enter(ir_assignment * ir)277 ir_rvalue_enter_visitor::visit_enter(ir_assignment *ir)
278 {
279    return rvalue_visit(ir);
280 }
281 
282 ir_visitor_status
visit_enter(ir_call * ir)283 ir_rvalue_enter_visitor::visit_enter(ir_call *ir)
284 {
285    return rvalue_visit(ir);
286 }
287 
288 ir_visitor_status
visit_enter(ir_discard * ir)289 ir_rvalue_enter_visitor::visit_enter(ir_discard *ir)
290 {
291    return rvalue_visit(ir);
292 }
293 
294 ir_visitor_status
visit_enter(ir_return * ir)295 ir_rvalue_enter_visitor::visit_enter(ir_return *ir)
296 {
297    return rvalue_visit(ir);
298 }
299 
300 ir_visitor_status
visit_enter(ir_if * ir)301 ir_rvalue_enter_visitor::visit_enter(ir_if *ir)
302 {
303    return rvalue_visit(ir);
304 }
305 
306 ir_visitor_status
visit_enter(ir_emit_vertex * ir)307 ir_rvalue_enter_visitor::visit_enter(ir_emit_vertex *ir)
308 {
309    return rvalue_visit(ir);
310 }
311 
312 ir_visitor_status
visit_enter(ir_end_primitive * ir)313 ir_rvalue_enter_visitor::visit_enter(ir_end_primitive *ir)
314 {
315    return rvalue_visit(ir);
316 }
317