blob: 4055a84ff151d869353d885d35c90c64eb531957 [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
Eric Anholt43ad37a2010-05-12 14:42:21 -070037#include <math.h>
Ian Romanick1cf43a42010-03-30 16:56:50 -070038#include "ir.h"
39#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100040#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070041
42/**
43 * Visitor class for evaluating constant expressions
44 */
45class ir_constant_visitor : public ir_visitor {
46public:
47 ir_constant_visitor()
48 : value(NULL)
49 {
50 /* empty */
51 }
52
53 virtual ~ir_constant_visitor()
54 {
55 /* empty */
56 }
57
58 /**
59 * \name Visit methods
60 *
61 * As typical for the visitor pattern, there must be one \c visit method for
62 * each concrete subclass of \c ir_instruction. Virtual base classes within
63 * the hierarchy should not have \c visit methods.
64 */
65 /*@{*/
66 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070067 virtual void visit(ir_function_signature *);
68 virtual void visit(ir_function *);
69 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070070 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070071 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020072 virtual void visit(ir_dereference_variable *);
73 virtual void visit(ir_dereference_array *);
74 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070075 virtual void visit(ir_assignment *);
76 virtual void visit(ir_constant *);
77 virtual void visit(ir_call *);
78 virtual void visit(ir_return *);
79 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070080 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070081 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070082 /*@}*/
83
84 /**
85 * Value of the constant expression.
86 *
87 * \note
88 * This field will be \c NULL if the expression is not constant valued.
89 */
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
91 ir_constant *value;
92};
93
94
95ir_constant *
96ir_instruction::constant_expression_value()
97{
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102}
103
104
105void
106ir_constant_visitor::visit(ir_variable *ir)
107{
108 (void) ir;
109 value = NULL;
110}
111
112
113void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700114ir_constant_visitor::visit(ir_function_signature *ir)
115{
116 (void) ir;
117 value = NULL;
118}
119
120
121void
122ir_constant_visitor::visit(ir_function *ir)
123{
124 (void) ir;
125 value = NULL;
126}
127
Ian Romanick1cf43a42010-03-30 16:56:50 -0700128void
129ir_constant_visitor::visit(ir_expression *ir)
130{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700131 value = NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000132 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000133 unsigned int operand, c;
134 unsigned u[16];
135 int i[16];
136 float f[16];
137 bool b[16];
138 const glsl_type *type = NULL;
Eric Anholt160d0922010-04-01 18:07:08 -1000139
Eric Anholtd98da972010-04-01 18:25:11 -1000140 for (operand = 0; operand < ir->get_num_operands(); operand++) {
141 op[operand] = ir->operands[operand]->constant_expression_value();
142 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000143 return;
144 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000145
146 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000147 case ir_unop_logic_not:
Eric Anholtd98da972010-04-01 18:25:11 -1000148 type = ir->operands[0]->type;
149 assert(type->base_type == GLSL_TYPE_BOOL);
150 for (c = 0; c < ir->operands[0]->type->components(); c++)
151 b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000152 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700153
154 case ir_unop_f2i:
155 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
156 type = ir->type;
157 for (c = 0; c < ir->operands[0]->type->components(); c++) {
158 i[c] = op[0]->value.f[c];
159 }
160 break;
161 case ir_unop_i2f:
162 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
163 op[0]->type->base_type == GLSL_TYPE_INT);
164 type = ir->type;
165 for (c = 0; c < ir->operands[0]->type->components(); c++) {
166 if (op[0]->type->base_type == GLSL_TYPE_INT)
167 f[c] = op[0]->value.i[c];
168 else
169 f[c] = op[0]->value.u[c];
170 }
171 break;
172
Eric Anholt43ad37a2010-05-12 14:42:21 -0700173 case ir_unop_neg:
174 type = ir->type;
175 for (c = 0; c < ir->operands[0]->type->components(); c++) {
176 switch (type->base_type) {
177 case GLSL_TYPE_UINT:
178 u[c] = -op[0]->value.u[c];
179 break;
180 case GLSL_TYPE_INT:
181 i[c] = -op[0]->value.i[c];
182 break;
183 case GLSL_TYPE_FLOAT:
184 f[c] = -op[0]->value.f[c];
185 break;
186 default:
187 assert(0);
188 }
189 }
190 break;
191
192 case ir_unop_abs:
193 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
194 type = ir->type;
195 for (c = 0; c < ir->operands[0]->type->components(); c++) {
196 switch (type->base_type) {
197 case GLSL_TYPE_UINT:
198 u[c] = op[0]->value.u[c];
199 break;
200 case GLSL_TYPE_INT:
201 i[c] = op[0]->value.i[c];
202 if (i[c] < 0)
203 i[c] = -i[c];
204 break;
205 case GLSL_TYPE_FLOAT:
206 f[c] = fabs(op[0]->value.f[c]);
207 break;
208 default:
209 assert(0);
210 }
211 }
212 break;
213
214 case ir_unop_rcp:
215 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
216 type = ir->type;
217 for (c = 0; c < ir->operands[0]->type->components(); c++) {
218 switch (type->base_type) {
219 case GLSL_TYPE_UINT:
220 if (op[0]->value.u[c] != 0.0)
221 u[c] = 1 / op[0]->value.u[c];
222 break;
223 case GLSL_TYPE_INT:
224 if (op[0]->value.i[c] != 0.0)
225 i[c] = 1 / op[0]->value.i[c];
226 break;
227 case GLSL_TYPE_FLOAT:
228 if (op[0]->value.f[c] != 0.0)
229 f[c] = 1.0 / op[0]->value.f[c];
230 break;
231 default:
232 assert(0);
233 }
234 }
235 break;
236
237 case ir_unop_rsq:
238 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
239 type = ir->type;
240 for (c = 0; c < ir->operands[0]->type->components(); c++) {
241 f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
242 }
243 break;
244
245 case ir_unop_sqrt:
246 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
247 type = ir->type;
248 for (c = 0; c < ir->operands[0]->type->components(); c++) {
249 f[c] = sqrtf(op[0]->value.f[c]);
250 }
251 break;
252
253 case ir_unop_exp:
254 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
255 type = ir->type;
256 for (c = 0; c < ir->operands[0]->type->components(); c++) {
257 f[c] = expf(op[0]->value.f[c]);
258 }
259 break;
260
261 case ir_unop_log:
262 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
263 type = ir->type;
264 for (c = 0; c < ir->operands[0]->type->components(); c++) {
265 f[c] = logf(op[0]->value.f[c]);
266 }
267 break;
268
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700269 case ir_unop_dFdx:
270 case ir_unop_dFdy:
271 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
272 type = ir->type;
273 for (c = 0; c < ir->operands[0]->type->components(); c++) {
274 f[c] = 0.0;
275 }
276 break;
277
Eric Anholtd251b922010-04-01 18:35:42 -1000278 case ir_binop_add:
279 if (ir->operands[0]->type == ir->operands[1]->type) {
280 type = ir->operands[0]->type;
281 for (c = 0; c < ir->operands[0]->type->components(); c++) {
282 switch (ir->operands[0]->type->base_type) {
283 case GLSL_TYPE_UINT:
284 u[c] = op[0]->value.u[c] + op[1]->value.u[c];
285 break;
286 case GLSL_TYPE_INT:
287 i[c] = op[0]->value.i[c] + op[1]->value.i[c];
288 break;
289 case GLSL_TYPE_FLOAT:
290 f[c] = op[0]->value.f[c] + op[1]->value.f[c];
291 break;
292 default:
293 assert(0);
294 }
295 }
296 }
297 break;
298 case ir_binop_sub:
299 if (ir->operands[0]->type == ir->operands[1]->type) {
300 type = ir->operands[0]->type;
301 for (c = 0; c < ir->operands[0]->type->components(); c++) {
302 switch (ir->operands[0]->type->base_type) {
303 case GLSL_TYPE_UINT:
304 u[c] = op[0]->value.u[c] - op[1]->value.u[c];
305 break;
306 case GLSL_TYPE_INT:
307 i[c] = op[0]->value.i[c] - op[1]->value.i[c];
308 break;
309 case GLSL_TYPE_FLOAT:
310 f[c] = op[0]->value.f[c] - op[1]->value.f[c];
311 break;
312 default:
313 assert(0);
314 }
315 }
316 }
317 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000318 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000319 if (ir->operands[0]->type == ir->operands[1]->type &&
320 !ir->operands[0]->type->is_matrix()) {
321 type = ir->operands[0]->type;
322 for (c = 0; c < ir->operands[0]->type->components(); c++) {
323 switch (ir->operands[0]->type->base_type) {
324 case GLSL_TYPE_UINT:
325 u[c] = op[0]->value.u[c] * op[1]->value.u[c];
326 break;
327 case GLSL_TYPE_INT:
328 i[c] = op[0]->value.i[c] * op[1]->value.i[c];
329 break;
330 case GLSL_TYPE_FLOAT:
331 f[c] = op[0]->value.f[c] * op[1]->value.f[c];
332 break;
333 default:
334 assert(0);
335 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000336 }
337 }
338 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000339 case ir_binop_div:
340 if (ir->operands[0]->type == ir->operands[1]->type) {
341 type = ir->operands[0]->type;
342 for (c = 0; c < ir->operands[0]->type->components(); c++) {
343 switch (ir->operands[0]->type->base_type) {
344 case GLSL_TYPE_UINT:
345 u[c] = op[0]->value.u[c] / op[1]->value.u[c];
346 break;
347 case GLSL_TYPE_INT:
348 i[c] = op[0]->value.i[c] / op[1]->value.i[c];
349 break;
350 case GLSL_TYPE_FLOAT:
351 f[c] = op[0]->value.f[c] / op[1]->value.f[c];
352 break;
353 default:
354 assert(0);
355 }
356 }
357 }
358 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000359 case ir_binop_logic_and:
Eric Anholtd98da972010-04-01 18:25:11 -1000360 type = ir->operands[0]->type;
361 assert(type->base_type == GLSL_TYPE_BOOL);
362 for (c = 0; c < ir->operands[0]->type->components(); c++)
363 b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000364 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000365 case ir_binop_logic_xor:
366 type = ir->operands[0]->type;
367 assert(type->base_type == GLSL_TYPE_BOOL);
368 for (c = 0; c < ir->operands[0]->type->components(); c++)
369 b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
370 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000371 case ir_binop_logic_or:
Eric Anholtd98da972010-04-01 18:25:11 -1000372 type = ir->operands[0]->type;
373 assert(type->base_type == GLSL_TYPE_BOOL);
374 for (c = 0; c < ir->operands[0]->type->components(); c++)
375 b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000376 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700377
378 case ir_binop_less:
379 type = glsl_type::bool_type;
380 switch (ir->operands[0]->type->base_type) {
381 case GLSL_TYPE_UINT:
382 b[0] = op[0]->value.u[0] < op[1]->value.u[0];
383 break;
384 case GLSL_TYPE_INT:
385 b[0] = op[0]->value.i[0] < op[1]->value.i[0];
386 break;
387 case GLSL_TYPE_FLOAT:
388 b[0] = op[0]->value.f[0] < op[1]->value.f[0];
389 break;
390 default:
391 assert(0);
392 }
393 break;
394 case ir_binop_greater:
395 type = glsl_type::bool_type;
396 switch (ir->operands[0]->type->base_type) {
397 case GLSL_TYPE_UINT:
398 b[0] = op[0]->value.u[0] > op[1]->value.u[0];
399 break;
400 case GLSL_TYPE_INT:
401 b[0] = op[0]->value.i[0] > op[1]->value.i[0];
402 break;
403 case GLSL_TYPE_FLOAT:
404 b[0] = op[0]->value.f[0] > op[1]->value.f[0];
405 break;
406 default:
407 assert(0);
408 }
409 break;
410 case ir_binop_lequal:
411 type = glsl_type::bool_type;
412 switch (ir->operands[0]->type->base_type) {
413 case GLSL_TYPE_UINT:
414 b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
415 break;
416 case GLSL_TYPE_INT:
417 b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
418 break;
419 case GLSL_TYPE_FLOAT:
420 b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
421 break;
422 default:
423 assert(0);
424 }
425 break;
426 case ir_binop_gequal:
427 type = glsl_type::bool_type;
428 switch (ir->operands[0]->type->base_type) {
429 case GLSL_TYPE_UINT:
430 b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
431 break;
432 case GLSL_TYPE_INT:
433 b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
434 break;
435 case GLSL_TYPE_FLOAT:
436 b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
437 break;
438 default:
439 assert(0);
440 }
441 break;
442
Eric Anholtec1949e2010-04-06 10:02:27 -0700443 case ir_binop_equal:
444 if (ir->operands[0]->type == ir->operands[1]->type) {
445 type = glsl_type::bool_type;
446 b[0] = true;
447 for (c = 0; c < ir->operands[0]->type->components(); c++) {
448 switch (ir->operands[0]->type->base_type) {
449 case GLSL_TYPE_UINT:
450 b[0] = b[0] && op[0]->value.u[c] == op[1]->value.u[c];
451 break;
452 case GLSL_TYPE_INT:
453 b[0] = b[0] && op[0]->value.i[c] == op[1]->value.i[c];
454 break;
455 case GLSL_TYPE_FLOAT:
456 b[0] = b[0] && op[0]->value.f[c] == op[1]->value.f[c];
457 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700458 case GLSL_TYPE_BOOL:
459 b[0] = b[0] && op[0]->value.b[c] == op[1]->value.b[c];
460 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700461 default:
462 assert(0);
463 }
464 }
465 }
466 break;
467 case ir_binop_nequal:
468 if (ir->operands[0]->type == ir->operands[1]->type) {
469 type = glsl_type::bool_type;
470 b[0] = false;
471 for (c = 0; c < ir->operands[0]->type->components(); c++) {
472 switch (ir->operands[0]->type->base_type) {
473 case GLSL_TYPE_UINT:
474 b[0] = b[0] || op[0]->value.u[c] != op[1]->value.u[c];
475 break;
476 case GLSL_TYPE_INT:
477 b[0] = b[0] || op[0]->value.i[c] != op[1]->value.i[c];
478 break;
479 case GLSL_TYPE_FLOAT:
480 b[0] = b[0] || op[0]->value.f[c] != op[1]->value.f[c];
481 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700482 case GLSL_TYPE_BOOL:
483 b[0] = b[0] || op[0]->value.b[c] != op[1]->value.b[c];
484 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700485 default:
486 assert(0);
487 }
488 }
489 }
490 break;
491
Eric Anholta576f9d2010-03-31 16:25:12 -1000492 default:
493 break;
494 }
Eric Anholtd98da972010-04-01 18:25:11 -1000495
496 if (type) {
497 switch (type->base_type) {
498 case GLSL_TYPE_UINT:
499 value = new ir_constant(type, u);
500 break;
501 case GLSL_TYPE_INT:
502 value = new ir_constant(type, i);
503 break;
504 case GLSL_TYPE_FLOAT:
505 value = new ir_constant(type, f);
506 break;
507 case GLSL_TYPE_BOOL:
508 value = new ir_constant(type, b);
509 break;
510 }
511 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700512}
513
514
515void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700516ir_constant_visitor::visit(ir_texture *ir)
517{
518 // FINISHME: Do stuff with texture lookups
519 (void) ir;
520 value = NULL;
521}
522
523
524void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700525ir_constant_visitor::visit(ir_swizzle *ir)
526{
527 (void) ir;
528 value = NULL;
529}
530
531
532void
Ian Romanickc7b10462010-05-19 13:20:12 +0200533ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700534{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700535 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700536
Ian Romanickc7b10462010-05-19 13:20:12 +0200537 ir_variable *var = ir->variable_referenced();
538 if (var && var->constant_value)
539 value = new ir_constant(ir->type, &var->constant_value->value);
540}
541
542
543void
544ir_constant_visitor::visit(ir_dereference_array *ir)
545{
Ian Romanick36ea2862010-05-19 13:52:29 +0200546 (void) ir;
Ian Romanickc7b10462010-05-19 13:20:12 +0200547 value = NULL;
548 /* FINISHME: Other dereference modes. */
549}
550
551
552void
553ir_constant_visitor::visit(ir_dereference_record *ir)
554{
Ian Romanick36ea2862010-05-19 13:52:29 +0200555 (void) ir;
Ian Romanickc7b10462010-05-19 13:20:12 +0200556 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700557 /* FINISHME: Other dereference modes. */
Ian Romanick1cf43a42010-03-30 16:56:50 -0700558}
559
560
561void
562ir_constant_visitor::visit(ir_assignment *ir)
563{
564 (void) ir;
565 value = NULL;
566}
567
568
569void
570ir_constant_visitor::visit(ir_constant *ir)
571{
572 value = ir;
573}
574
575
576void
577ir_constant_visitor::visit(ir_call *ir)
578{
579 (void) ir;
580 value = NULL;
581}
582
583
584void
585ir_constant_visitor::visit(ir_return *ir)
586{
587 (void) ir;
588 value = NULL;
589}
590
591
592void
593ir_constant_visitor::visit(ir_if *ir)
594{
595 (void) ir;
596 value = NULL;
597}
Ian Romanickfad607a2010-04-05 16:16:07 -0700598
599
600void
601ir_constant_visitor::visit(ir_loop *ir)
602{
603 (void) ir;
604 value = NULL;
605}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700606
607
608void
609ir_constant_visitor::visit(ir_loop_jump *ir)
610{
611 (void) ir;
612 value = NULL;
613}