blob: e3a0d9eaa11645837f7cecd2231a7c86cf2429a3 [file] [log] [blame]
Ian Romanick1cf43a42010-03-30 16:56:50 -07001/*
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_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
34 */
35
36#define NULL 0
37#include "ir.h"
38#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100039#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070040
41/**
42 * Visitor class for evaluating constant expressions
43 */
44class ir_constant_visitor : public ir_visitor {
45public:
46 ir_constant_visitor()
47 : value(NULL)
48 {
49 /* empty */
50 }
51
52 virtual ~ir_constant_visitor()
53 {
54 /* empty */
55 }
56
57 /**
58 * \name Visit methods
59 *
60 * As typical for the visitor pattern, there must be one \c visit method for
61 * each concrete subclass of \c ir_instruction. Virtual base classes within
62 * the hierarchy should not have \c visit methods.
63 */
64 /*@{*/
65 virtual void visit(ir_variable *);
66 virtual void visit(ir_label *);
67 virtual void visit(ir_function_signature *);
68 virtual void visit(ir_function *);
69 virtual void visit(ir_expression *);
70 virtual void visit(ir_swizzle *);
71 virtual void visit(ir_dereference *);
72 virtual void visit(ir_assignment *);
73 virtual void visit(ir_constant *);
74 virtual void visit(ir_call *);
75 virtual void visit(ir_return *);
76 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070077 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070078 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070079 /*@}*/
80
81 /**
82 * Value of the constant expression.
83 *
84 * \note
85 * This field will be \c NULL if the expression is not constant valued.
86 */
87 /* FINIHSME: This cannot hold values for constant arrays or structures. */
88 ir_constant *value;
89};
90
91
92ir_constant *
93ir_instruction::constant_expression_value()
94{
95 ir_constant_visitor visitor;
96
97 this->accept(& visitor);
98 return visitor.value;
99}
100
101
102void
103ir_constant_visitor::visit(ir_variable *ir)
104{
105 (void) ir;
106 value = NULL;
107}
108
109
110void
111ir_constant_visitor::visit(ir_label *ir)
112{
113 (void) ir;
114 value = NULL;
115}
116
117
118void
119ir_constant_visitor::visit(ir_function_signature *ir)
120{
121 (void) ir;
122 value = NULL;
123}
124
125
126void
127ir_constant_visitor::visit(ir_function *ir)
128{
129 (void) ir;
130 value = NULL;
131}
132
Ian Romanick1cf43a42010-03-30 16:56:50 -0700133void
134ir_constant_visitor::visit(ir_expression *ir)
135{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700136 value = NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000137 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000138 unsigned int operand, c;
139 unsigned u[16];
140 int i[16];
141 float f[16];
142 bool b[16];
143 const glsl_type *type = NULL;
Eric Anholt160d0922010-04-01 18:07:08 -1000144
Eric Anholtd98da972010-04-01 18:25:11 -1000145 for (operand = 0; operand < ir->get_num_operands(); operand++) {
146 op[operand] = ir->operands[operand]->constant_expression_value();
147 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000148 return;
149 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000150
151 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000152 case ir_unop_logic_not:
Eric Anholtd98da972010-04-01 18:25:11 -1000153 type = ir->operands[0]->type;
154 assert(type->base_type == GLSL_TYPE_BOOL);
155 for (c = 0; c < ir->operands[0]->type->components(); c++)
156 b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000157 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700158
159 case ir_unop_f2i:
160 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
161 type = ir->type;
162 for (c = 0; c < ir->operands[0]->type->components(); c++) {
163 i[c] = op[0]->value.f[c];
164 }
165 break;
166 case ir_unop_i2f:
167 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
168 op[0]->type->base_type == GLSL_TYPE_INT);
169 type = ir->type;
170 for (c = 0; c < ir->operands[0]->type->components(); c++) {
171 if (op[0]->type->base_type == GLSL_TYPE_INT)
172 f[c] = op[0]->value.i[c];
173 else
174 f[c] = op[0]->value.u[c];
175 }
176 break;
177
Eric Anholtd251b922010-04-01 18:35:42 -1000178 case ir_binop_add:
179 if (ir->operands[0]->type == ir->operands[1]->type) {
180 type = ir->operands[0]->type;
181 for (c = 0; c < ir->operands[0]->type->components(); c++) {
182 switch (ir->operands[0]->type->base_type) {
183 case GLSL_TYPE_UINT:
184 u[c] = op[0]->value.u[c] + op[1]->value.u[c];
185 break;
186 case GLSL_TYPE_INT:
187 i[c] = op[0]->value.i[c] + op[1]->value.i[c];
188 break;
189 case GLSL_TYPE_FLOAT:
190 f[c] = op[0]->value.f[c] + op[1]->value.f[c];
191 break;
192 default:
193 assert(0);
194 }
195 }
196 }
197 break;
198 case ir_binop_sub:
199 if (ir->operands[0]->type == ir->operands[1]->type) {
200 type = ir->operands[0]->type;
201 for (c = 0; c < ir->operands[0]->type->components(); c++) {
202 switch (ir->operands[0]->type->base_type) {
203 case GLSL_TYPE_UINT:
204 u[c] = op[0]->value.u[c] - op[1]->value.u[c];
205 break;
206 case GLSL_TYPE_INT:
207 i[c] = op[0]->value.i[c] - op[1]->value.i[c];
208 break;
209 case GLSL_TYPE_FLOAT:
210 f[c] = op[0]->value.f[c] - op[1]->value.f[c];
211 break;
212 default:
213 assert(0);
214 }
215 }
216 }
217 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000218 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000219 if (ir->operands[0]->type == ir->operands[1]->type &&
220 !ir->operands[0]->type->is_matrix()) {
221 type = ir->operands[0]->type;
222 for (c = 0; c < ir->operands[0]->type->components(); c++) {
223 switch (ir->operands[0]->type->base_type) {
224 case GLSL_TYPE_UINT:
225 u[c] = op[0]->value.u[c] * op[1]->value.u[c];
226 break;
227 case GLSL_TYPE_INT:
228 i[c] = op[0]->value.i[c] * op[1]->value.i[c];
229 break;
230 case GLSL_TYPE_FLOAT:
231 f[c] = op[0]->value.f[c] * op[1]->value.f[c];
232 break;
233 default:
234 assert(0);
235 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000236 }
237 }
238 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000239 case ir_binop_div:
240 if (ir->operands[0]->type == ir->operands[1]->type) {
241 type = ir->operands[0]->type;
242 for (c = 0; c < ir->operands[0]->type->components(); c++) {
243 switch (ir->operands[0]->type->base_type) {
244 case GLSL_TYPE_UINT:
245 u[c] = op[0]->value.u[c] / op[1]->value.u[c];
246 break;
247 case GLSL_TYPE_INT:
248 i[c] = op[0]->value.i[c] / op[1]->value.i[c];
249 break;
250 case GLSL_TYPE_FLOAT:
251 f[c] = op[0]->value.f[c] / op[1]->value.f[c];
252 break;
253 default:
254 assert(0);
255 }
256 }
257 }
258 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000259 case ir_binop_logic_and:
Eric Anholtd98da972010-04-01 18:25:11 -1000260 type = ir->operands[0]->type;
261 assert(type->base_type == GLSL_TYPE_BOOL);
262 for (c = 0; c < ir->operands[0]->type->components(); c++)
263 b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000264 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000265 case ir_binop_logic_xor:
266 type = ir->operands[0]->type;
267 assert(type->base_type == GLSL_TYPE_BOOL);
268 for (c = 0; c < ir->operands[0]->type->components(); c++)
269 b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
270 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000271 case ir_binop_logic_or:
Eric Anholtd98da972010-04-01 18:25:11 -1000272 type = ir->operands[0]->type;
273 assert(type->base_type == GLSL_TYPE_BOOL);
274 for (c = 0; c < ir->operands[0]->type->components(); c++)
275 b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000276 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700277
278 case ir_binop_less:
279 type = glsl_type::bool_type;
280 switch (ir->operands[0]->type->base_type) {
281 case GLSL_TYPE_UINT:
282 b[0] = op[0]->value.u[0] < op[1]->value.u[0];
283 break;
284 case GLSL_TYPE_INT:
285 b[0] = op[0]->value.i[0] < op[1]->value.i[0];
286 break;
287 case GLSL_TYPE_FLOAT:
288 b[0] = op[0]->value.f[0] < op[1]->value.f[0];
289 break;
290 default:
291 assert(0);
292 }
293 break;
294 case ir_binop_greater:
295 type = glsl_type::bool_type;
296 switch (ir->operands[0]->type->base_type) {
297 case GLSL_TYPE_UINT:
298 b[0] = op[0]->value.u[0] > op[1]->value.u[0];
299 break;
300 case GLSL_TYPE_INT:
301 b[0] = op[0]->value.i[0] > op[1]->value.i[0];
302 break;
303 case GLSL_TYPE_FLOAT:
304 b[0] = op[0]->value.f[0] > op[1]->value.f[0];
305 break;
306 default:
307 assert(0);
308 }
309 break;
310 case ir_binop_lequal:
311 type = glsl_type::bool_type;
312 switch (ir->operands[0]->type->base_type) {
313 case GLSL_TYPE_UINT:
314 b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
315 break;
316 case GLSL_TYPE_INT:
317 b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
318 break;
319 case GLSL_TYPE_FLOAT:
320 b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
321 break;
322 default:
323 assert(0);
324 }
325 break;
326 case ir_binop_gequal:
327 type = glsl_type::bool_type;
328 switch (ir->operands[0]->type->base_type) {
329 case GLSL_TYPE_UINT:
330 b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
331 break;
332 case GLSL_TYPE_INT:
333 b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
334 break;
335 case GLSL_TYPE_FLOAT:
336 b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
337 break;
338 default:
339 assert(0);
340 }
341 break;
342
Eric Anholtec1949e2010-04-06 10:02:27 -0700343 case ir_binop_equal:
344 if (ir->operands[0]->type == ir->operands[1]->type) {
345 type = glsl_type::bool_type;
346 b[0] = true;
347 for (c = 0; c < ir->operands[0]->type->components(); c++) {
348 switch (ir->operands[0]->type->base_type) {
349 case GLSL_TYPE_UINT:
350 b[0] = b[0] && op[0]->value.u[c] == op[1]->value.u[c];
351 break;
352 case GLSL_TYPE_INT:
353 b[0] = b[0] && op[0]->value.i[c] == op[1]->value.i[c];
354 break;
355 case GLSL_TYPE_FLOAT:
356 b[0] = b[0] && op[0]->value.f[c] == op[1]->value.f[c];
357 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700358 case GLSL_TYPE_BOOL:
359 b[0] = b[0] && op[0]->value.b[c] == op[1]->value.b[c];
360 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700361 default:
362 assert(0);
363 }
364 }
365 }
366 break;
367 case ir_binop_nequal:
368 if (ir->operands[0]->type == ir->operands[1]->type) {
369 type = glsl_type::bool_type;
370 b[0] = false;
371 for (c = 0; c < ir->operands[0]->type->components(); c++) {
372 switch (ir->operands[0]->type->base_type) {
373 case GLSL_TYPE_UINT:
374 b[0] = b[0] || op[0]->value.u[c] != op[1]->value.u[c];
375 break;
376 case GLSL_TYPE_INT:
377 b[0] = b[0] || op[0]->value.i[c] != op[1]->value.i[c];
378 break;
379 case GLSL_TYPE_FLOAT:
380 b[0] = b[0] || op[0]->value.f[c] != op[1]->value.f[c];
381 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700382 case GLSL_TYPE_BOOL:
383 b[0] = b[0] || op[0]->value.b[c] != op[1]->value.b[c];
384 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700385 default:
386 assert(0);
387 }
388 }
389 }
390 break;
391
Eric Anholta576f9d2010-03-31 16:25:12 -1000392 default:
393 break;
394 }
Eric Anholtd98da972010-04-01 18:25:11 -1000395
396 if (type) {
397 switch (type->base_type) {
398 case GLSL_TYPE_UINT:
399 value = new ir_constant(type, u);
400 break;
401 case GLSL_TYPE_INT:
402 value = new ir_constant(type, i);
403 break;
404 case GLSL_TYPE_FLOAT:
405 value = new ir_constant(type, f);
406 break;
407 case GLSL_TYPE_BOOL:
408 value = new ir_constant(type, b);
409 break;
410 }
411 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700412}
413
414
415void
416ir_constant_visitor::visit(ir_swizzle *ir)
417{
418 (void) ir;
419 value = NULL;
420}
421
422
423void
424ir_constant_visitor::visit(ir_dereference *ir)
425{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700426 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700427
428 if (ir->mode == ir_dereference::ir_reference_variable) {
429 ir_variable *var = ir->var->as_variable();
430 if (var && var->constant_value) {
431 value = new ir_constant(ir->type, &var->constant_value->value);
432 }
433 }
434 /* FINISHME: Other dereference modes. */
Ian Romanick1cf43a42010-03-30 16:56:50 -0700435}
436
437
438void
439ir_constant_visitor::visit(ir_assignment *ir)
440{
441 (void) ir;
442 value = NULL;
443}
444
445
446void
447ir_constant_visitor::visit(ir_constant *ir)
448{
449 value = ir;
450}
451
452
453void
454ir_constant_visitor::visit(ir_call *ir)
455{
456 (void) ir;
457 value = NULL;
458}
459
460
461void
462ir_constant_visitor::visit(ir_return *ir)
463{
464 (void) ir;
465 value = NULL;
466}
467
468
469void
470ir_constant_visitor::visit(ir_if *ir)
471{
472 (void) ir;
473 value = NULL;
474}
Ian Romanickfad607a2010-04-05 16:16:07 -0700475
476
477void
478ir_constant_visitor::visit(ir_loop *ir)
479{
480 (void) ir;
481 value = NULL;
482}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700483
484
485void
486ir_constant_visitor::visit(ir_loop_jump *ir)
487{
488 (void) ir;
489 value = NULL;
490}