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