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 "ir_print_visitor.h"
36#include "glsl_types.h"
37
38ir_visitor_status
39ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir)
40{
41   unsigned int operand;
42
43   for (operand = 0; operand < ir->get_num_operands(); operand++) {
44      handle_rvalue(&ir->operands[operand]);
45   }
46
47   return visit_continue;
48}
49
50ir_visitor_status
51ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
52{
53   handle_rvalue(&ir->coordinate);
54   handle_rvalue(&ir->projector);
55   handle_rvalue(&ir->shadow_comparitor);
56   handle_rvalue(&ir->offset);
57
58   switch (ir->op) {
59   case ir_tex:
60      break;
61   case ir_txb:
62      handle_rvalue(&ir->lod_info.bias);
63      break;
64   case ir_txf:
65   case ir_txl:
66   case ir_txs:
67      handle_rvalue(&ir->lod_info.lod);
68      break;
69   case ir_txd:
70      handle_rvalue(&ir->lod_info.grad.dPdx);
71      handle_rvalue(&ir->lod_info.grad.dPdy);
72      break;
73   }
74
75   return visit_continue;
76}
77
78ir_visitor_status
79ir_rvalue_base_visitor::rvalue_visit(ir_swizzle *ir)
80{
81   handle_rvalue(&ir->val);
82   return visit_continue;
83}
84
85ir_visitor_status
86ir_rvalue_base_visitor::rvalue_visit(ir_dereference_array *ir)
87{
88   /* The array index is not the target of the assignment, so clear the
89    * 'in_assignee' flag.  Restore it after returning from the array index.
90    */
91   const bool was_in_assignee = this->in_assignee;
92   this->in_assignee = false;
93   handle_rvalue(&ir->array_index);
94   this->in_assignee = was_in_assignee;
95
96   handle_rvalue(&ir->array);
97   return visit_continue;
98}
99
100ir_visitor_status
101ir_rvalue_base_visitor::rvalue_visit(ir_dereference_record *ir)
102{
103   handle_rvalue(&ir->record);
104   return visit_continue;
105}
106
107ir_visitor_status
108ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir)
109{
110   handle_rvalue(&ir->rhs);
111   handle_rvalue(&ir->condition);
112
113   return visit_continue;
114}
115
116ir_visitor_status
117ir_rvalue_base_visitor::rvalue_visit(ir_call *ir)
118{
119   foreach_iter(exec_list_iterator, iter, *ir) {
120      ir_rvalue *param = (ir_rvalue *)iter.get();
121      ir_rvalue *new_param = param;
122      handle_rvalue(&new_param);
123
124      if (new_param != param) {
125	 param->replace_with(new_param);
126      }
127   }
128   return visit_continue;
129}
130
131ir_visitor_status
132ir_rvalue_base_visitor::rvalue_visit(ir_return *ir)
133{
134   handle_rvalue(&ir->value);;
135   return visit_continue;
136}
137
138ir_visitor_status
139ir_rvalue_base_visitor::rvalue_visit(ir_if *ir)
140{
141   handle_rvalue(&ir->condition);
142   return visit_continue;
143}
144
145
146ir_visitor_status
147ir_rvalue_visitor::visit_leave(ir_expression *ir)
148{
149   return rvalue_visit(ir);
150}
151
152ir_visitor_status
153ir_rvalue_visitor::visit_leave(ir_texture *ir)
154{
155   return rvalue_visit(ir);
156}
157
158ir_visitor_status
159ir_rvalue_visitor::visit_leave(ir_swizzle *ir)
160{
161   return rvalue_visit(ir);
162}
163
164ir_visitor_status
165ir_rvalue_visitor::visit_leave(ir_dereference_array *ir)
166{
167   return rvalue_visit(ir);
168}
169
170ir_visitor_status
171ir_rvalue_visitor::visit_leave(ir_dereference_record *ir)
172{
173   return rvalue_visit(ir);
174}
175
176ir_visitor_status
177ir_rvalue_visitor::visit_leave(ir_assignment *ir)
178{
179   return rvalue_visit(ir);
180}
181
182ir_visitor_status
183ir_rvalue_visitor::visit_leave(ir_call *ir)
184{
185   return rvalue_visit(ir);
186}
187
188ir_visitor_status
189ir_rvalue_visitor::visit_leave(ir_return *ir)
190{
191   return rvalue_visit(ir);
192}
193
194ir_visitor_status
195ir_rvalue_visitor::visit_leave(ir_if *ir)
196{
197   return rvalue_visit(ir);
198}
199
200ir_visitor_status
201ir_rvalue_enter_visitor::visit_enter(ir_expression *ir)
202{
203   return rvalue_visit(ir);
204}
205
206ir_visitor_status
207ir_rvalue_enter_visitor::visit_enter(ir_texture *ir)
208{
209   return rvalue_visit(ir);
210}
211
212ir_visitor_status
213ir_rvalue_enter_visitor::visit_enter(ir_swizzle *ir)
214{
215   return rvalue_visit(ir);
216}
217
218ir_visitor_status
219ir_rvalue_enter_visitor::visit_enter(ir_dereference_array *ir)
220{
221   return rvalue_visit(ir);
222}
223
224ir_visitor_status
225ir_rvalue_enter_visitor::visit_enter(ir_dereference_record *ir)
226{
227   return rvalue_visit(ir);
228}
229
230ir_visitor_status
231ir_rvalue_enter_visitor::visit_enter(ir_assignment *ir)
232{
233   return rvalue_visit(ir);
234}
235
236ir_visitor_status
237ir_rvalue_enter_visitor::visit_enter(ir_call *ir)
238{
239   return rvalue_visit(ir);
240}
241
242ir_visitor_status
243ir_rvalue_enter_visitor::visit_enter(ir_return *ir)
244{
245   return rvalue_visit(ir);
246}
247
248ir_visitor_status
249ir_rvalue_enter_visitor::visit_enter(ir_if *ir)
250{
251   return rvalue_visit(ir);
252}
253