2 * Copyright © 2010 Intel Corporation
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:
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
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.
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
43 * Visitor class for evaluating constant expressions
45 class ir_constant_visitor
: public ir_visitor
{
53 virtual ~ir_constant_visitor()
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.
66 virtual void visit(ir_variable
*);
67 virtual void visit(ir_function_signature
*);
68 virtual void visit(ir_function
*);
69 virtual void visit(ir_expression
*);
70 virtual void visit(ir_texture
*);
71 virtual void visit(ir_swizzle
*);
72 virtual void visit(ir_dereference_variable
*);
73 virtual void visit(ir_dereference_array
*);
74 virtual void visit(ir_dereference_record
*);
75 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
*);
80 virtual void visit(ir_loop
*);
81 virtual void visit(ir_loop_jump
*);
85 * Value of the constant expression.
88 * This field will be \c NULL if the expression is not constant valued.
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
96 ir_instruction::constant_expression_value()
98 ir_constant_visitor visitor
;
100 this->accept(& visitor
);
101 return visitor
.value
;
106 ir_constant_visitor::visit(ir_variable
*ir
)
114 ir_constant_visitor::visit(ir_function_signature
*ir
)
122 ir_constant_visitor::visit(ir_function
*ir
)
129 ir_constant_visitor::visit(ir_expression
*ir
)
133 unsigned int operand
, c
;
138 const glsl_type
*type
= NULL
;
140 for (operand
= 0; operand
< ir
->get_num_operands(); operand
++) {
141 op
[operand
] = ir
->operands
[operand
]->constant_expression_value();
146 switch (ir
->operation
) {
147 case ir_unop_logic_not
:
148 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
];
155 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
157 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
158 i
[c
] = op
[0]->value
.f
[c
];
162 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
||
163 op
[0]->type
->base_type
== GLSL_TYPE_INT
);
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
];
169 f
[c
] = op
[0]->value
.u
[c
];
173 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
175 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
176 f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
180 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
182 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
183 b
[c
] = bool(op
[0]->value
.f
[c
]);
189 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
190 switch (type
->base_type
) {
192 u
[c
] = -op
[0]->value
.u
[c
];
195 i
[c
] = -op
[0]->value
.i
[c
];
197 case GLSL_TYPE_FLOAT
:
198 f
[c
] = -op
[0]->value
.f
[c
];
207 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
209 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
210 switch (type
->base_type
) {
212 u
[c
] = op
[0]->value
.u
[c
];
215 i
[c
] = op
[0]->value
.i
[c
];
219 case GLSL_TYPE_FLOAT
:
220 f
[c
] = fabs(op
[0]->value
.f
[c
]);
229 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
231 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
232 switch (type
->base_type
) {
234 if (op
[0]->value
.u
[c
] != 0.0)
235 u
[c
] = 1 / op
[0]->value
.u
[c
];
238 if (op
[0]->value
.i
[c
] != 0.0)
239 i
[c
] = 1 / op
[0]->value
.i
[c
];
241 case GLSL_TYPE_FLOAT
:
242 if (op
[0]->value
.f
[c
] != 0.0)
243 f
[c
] = 1.0 / op
[0]->value
.f
[c
];
252 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
254 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
255 f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
260 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
262 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
263 f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
268 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
270 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
271 f
[c
] = expf(op
[0]->value
.f
[c
]);
276 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
278 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
279 f
[c
] = logf(op
[0]->value
.f
[c
]);
285 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
287 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
293 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
294 type
= ir
->operands
[0]->type
;
295 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
296 switch (ir
->operands
[0]->type
->base_type
) {
298 u
[c
] = op
[0]->value
.u
[c
] + op
[1]->value
.u
[c
];
301 i
[c
] = op
[0]->value
.i
[c
] + op
[1]->value
.i
[c
];
303 case GLSL_TYPE_FLOAT
:
304 f
[c
] = op
[0]->value
.f
[c
] + op
[1]->value
.f
[c
];
313 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
314 type
= ir
->operands
[0]->type
;
315 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
316 switch (ir
->operands
[0]->type
->base_type
) {
318 u
[c
] = op
[0]->value
.u
[c
] - op
[1]->value
.u
[c
];
321 i
[c
] = op
[0]->value
.i
[c
] - op
[1]->value
.i
[c
];
323 case GLSL_TYPE_FLOAT
:
324 f
[c
] = op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
333 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
&&
334 !ir
->operands
[0]->type
->is_matrix()) {
335 type
= ir
->operands
[0]->type
;
336 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
337 switch (ir
->operands
[0]->type
->base_type
) {
339 u
[c
] = op
[0]->value
.u
[c
] * op
[1]->value
.u
[c
];
342 i
[c
] = op
[0]->value
.i
[c
] * op
[1]->value
.i
[c
];
344 case GLSL_TYPE_FLOAT
:
345 f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
354 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
355 type
= ir
->operands
[0]->type
;
356 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
357 switch (ir
->operands
[0]->type
->base_type
) {
359 u
[c
] = op
[0]->value
.u
[c
] / op
[1]->value
.u
[c
];
362 i
[c
] = op
[0]->value
.i
[c
] / op
[1]->value
.i
[c
];
364 case GLSL_TYPE_FLOAT
:
365 f
[c
] = op
[0]->value
.f
[c
] / op
[1]->value
.f
[c
];
373 case ir_binop_logic_and
:
374 type
= ir
->operands
[0]->type
;
375 assert(type
->base_type
== GLSL_TYPE_BOOL
);
376 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
377 b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
379 case ir_binop_logic_xor
:
380 type
= ir
->operands
[0]->type
;
381 assert(type
->base_type
== GLSL_TYPE_BOOL
);
382 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
383 b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
385 case ir_binop_logic_or
:
386 type
= ir
->operands
[0]->type
;
387 assert(type
->base_type
== GLSL_TYPE_BOOL
);
388 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
389 b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
393 type
= glsl_type::bool_type
;
394 switch (ir
->operands
[0]->type
->base_type
) {
396 b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
399 b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
401 case GLSL_TYPE_FLOAT
:
402 b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
408 case ir_binop_greater
:
409 type
= glsl_type::bool_type
;
410 switch (ir
->operands
[0]->type
->base_type
) {
412 b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
415 b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
417 case GLSL_TYPE_FLOAT
:
418 b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
424 case ir_binop_lequal
:
425 type
= glsl_type::bool_type
;
426 switch (ir
->operands
[0]->type
->base_type
) {
428 b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
431 b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
433 case GLSL_TYPE_FLOAT
:
434 b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
440 case ir_binop_gequal
:
441 type
= glsl_type::bool_type
;
442 switch (ir
->operands
[0]->type
->base_type
) {
444 b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
447 b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
449 case GLSL_TYPE_FLOAT
:
450 b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
458 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
459 type
= glsl_type::bool_type
;
461 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
462 switch (ir
->operands
[0]->type
->base_type
) {
464 b
[0] = b
[0] && op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
467 b
[0] = b
[0] && op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
469 case GLSL_TYPE_FLOAT
:
470 b
[0] = b
[0] && op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
473 b
[0] = b
[0] && op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
481 case ir_binop_nequal
:
482 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
483 type
= glsl_type::bool_type
;
485 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
486 switch (ir
->operands
[0]->type
->base_type
) {
488 b
[0] = b
[0] || op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
491 b
[0] = b
[0] || op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
493 case GLSL_TYPE_FLOAT
:
494 b
[0] = b
[0] || op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
497 b
[0] = b
[0] || op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
511 switch (type
->base_type
) {
513 value
= new ir_constant(type
, u
);
516 value
= new ir_constant(type
, i
);
518 case GLSL_TYPE_FLOAT
:
519 value
= new ir_constant(type
, f
);
522 value
= new ir_constant(type
, b
);
530 ir_constant_visitor::visit(ir_texture
*ir
)
532 // FINISHME: Do stuff with texture lookups
539 ir_constant_visitor::visit(ir_swizzle
*ir
)
547 ir_constant_visitor::visit(ir_dereference_variable
*ir
)
551 ir_variable
*var
= ir
->variable_referenced();
552 if (var
&& var
->constant_value
)
553 value
= new ir_constant(ir
->type
, &var
->constant_value
->value
);
558 ir_constant_visitor::visit(ir_dereference_array
*ir
)
562 /* FINISHME: Other dereference modes. */
567 ir_constant_visitor::visit(ir_dereference_record
*ir
)
571 /* FINISHME: Other dereference modes. */
576 ir_constant_visitor::visit(ir_assignment
*ir
)
584 ir_constant_visitor::visit(ir_constant
*ir
)
591 ir_constant_visitor::visit(ir_call
*ir
)
599 ir_constant_visitor::visit(ir_return
*ir
)
607 ir_constant_visitor::visit(ir_if
*ir
)
615 ir_constant_visitor::visit(ir_loop
*ir
)
623 ir_constant_visitor::visit(ir_loop_jump
*ir
)