linker: Limit attribute allocation to MAX_VERTEX_ATTRIBS
[mesa.git] / ir_constant_folding.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 /**
25 * \file ir_constant_folding.cpp
26 * Replace constant-valued expressions with references to constant values.
27 */
28
29 #include "ir.h"
30 #include "ir_visitor.h"
31 #include "ir_optimization.h"
32 #include "glsl_types.h"
33
34 /**
35 * Visitor class for replacing expressions with ir_constant values.
36 */
37
38 class ir_constant_folding_visitor : public ir_visitor {
39 public:
40 ir_constant_folding_visitor()
41 {
42 /* empty */
43 }
44
45 virtual ~ir_constant_folding_visitor()
46 {
47 /* empty */
48 }
49
50 /**
51 * \name Visit methods
52 *
53 * As typical for the visitor pattern, there must be one \c visit method for
54 * each concrete subclass of \c ir_instruction. Virtual base classes within
55 * the hierarchy should not have \c visit methods.
56 */
57 /*@{*/
58 virtual void visit(ir_variable *);
59 virtual void visit(ir_function_signature *);
60 virtual void visit(ir_function *);
61 virtual void visit(ir_expression *);
62 virtual void visit(ir_texture *);
63 virtual void visit(ir_swizzle *);
64 virtual void visit(ir_dereference_variable *);
65 virtual void visit(ir_dereference_array *);
66 virtual void visit(ir_dereference_record *);
67 virtual void visit(ir_assignment *);
68 virtual void visit(ir_constant *);
69 virtual void visit(ir_call *);
70 virtual void visit(ir_return *);
71 virtual void visit(ir_if *);
72 virtual void visit(ir_loop *);
73 virtual void visit(ir_loop_jump *);
74 /*@}*/
75 };
76
77 void
78 ir_constant_folding_visitor::visit(ir_variable *ir)
79 {
80 (void) ir;
81 }
82
83
84 void
85 ir_constant_folding_visitor::visit(ir_function_signature *ir)
86 {
87 visit_exec_list(&ir->body, this);
88 }
89
90
91 void
92 ir_constant_folding_visitor::visit(ir_function *ir)
93 {
94 foreach_iter(exec_list_iterator, iter, *ir) {
95 ir_function_signature *const sig = (ir_function_signature *) iter.get();
96 sig->accept(this);
97 }
98 }
99
100 void
101 ir_constant_folding_visitor::visit(ir_expression *ir)
102 {
103 ir_constant *op[2];
104 unsigned int operand;
105
106 for (operand = 0; operand < ir->get_num_operands(); operand++) {
107 op[operand] = ir->operands[operand]->constant_expression_value();
108 if (op[operand]) {
109 ir->operands[operand] = op[operand];
110 } else {
111 ir->operands[operand]->accept(this);
112 }
113 }
114 }
115
116
117 void
118 ir_constant_folding_visitor::visit(ir_texture *ir)
119 {
120 // FINISHME: Do stuff with texture lookups
121 (void) ir;
122 }
123
124
125 void
126 ir_constant_folding_visitor::visit(ir_swizzle *ir)
127 {
128 ir->val->accept(this);
129 }
130
131
132 void
133 ir_constant_folding_visitor::visit(ir_dereference_variable *ir)
134 {
135 (void) ir;
136 }
137
138
139 void
140 ir_constant_folding_visitor::visit(ir_dereference_array *ir)
141 {
142 ir_constant *const_val =
143 ir->array_index->constant_expression_value();
144
145 if (const_val)
146 ir->array_index = const_val;
147 else
148 ir->array_index->accept(this);
149
150 ir->array->accept(this);
151 }
152
153
154 void
155 ir_constant_folding_visitor::visit(ir_dereference_record *ir)
156 {
157 ir->record->accept(this);
158 }
159
160
161 void
162 ir_constant_folding_visitor::visit(ir_assignment *ir)
163 {
164 ir_constant *const_val = ir->rhs->constant_expression_value();
165 if (const_val)
166 ir->rhs = const_val;
167 else
168 ir->rhs->accept(this);
169 }
170
171
172 void
173 ir_constant_folding_visitor::visit(ir_constant *ir)
174 {
175 (void) ir;
176 }
177
178
179 void
180 ir_constant_folding_visitor::visit(ir_call *ir)
181 {
182 (void) ir;
183 }
184
185
186 void
187 ir_constant_folding_visitor::visit(ir_return *ir)
188 {
189 (void) ir;
190 }
191
192
193 void
194 ir_constant_folding_visitor::visit(ir_if *ir)
195 {
196 ir_constant *const_val = ir->condition->constant_expression_value();
197 if (const_val)
198 ir->condition = const_val;
199 else
200 ir->condition->accept(this);
201
202 visit_exec_list(&ir->then_instructions, this);
203 visit_exec_list(&ir->else_instructions, this);
204 }
205
206
207 void
208 ir_constant_folding_visitor::visit(ir_loop *ir)
209 {
210 (void) ir;
211 }
212
213
214 void
215 ir_constant_folding_visitor::visit(ir_loop_jump *ir)
216 {
217 (void) ir;
218 }
219
220 bool
221 do_constant_folding(exec_list *instructions)
222 {
223 ir_constant_folding_visitor constant_folding;
224
225 visit_exec_list(instructions, &constant_folding);
226
227 /* FINISHME: Return real progress. */
228 return false;
229 }