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
38 #include "ir_visitor.h"
39 #include "glsl_types.h"
42 * Visitor class for evaluating constant expressions
44 class ir_constant_visitor
: public ir_visitor
{
52 virtual ~ir_constant_visitor()
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.
65 virtual void visit(ir_variable
*);
66 virtual void visit(ir_function_signature
*);
67 virtual void visit(ir_function
*);
68 virtual void visit(ir_expression
*);
69 virtual void visit(ir_swizzle
*);
70 virtual void visit(ir_dereference
*);
71 virtual void visit(ir_assignment
*);
72 virtual void visit(ir_constant
*);
73 virtual void visit(ir_call
*);
74 virtual void visit(ir_return
*);
75 virtual void visit(ir_if
*);
76 virtual void visit(ir_loop
*);
77 virtual void visit(ir_loop_jump
*);
81 * Value of the constant expression.
84 * This field will be \c NULL if the expression is not constant valued.
86 /* FINIHSME: This cannot hold values for constant arrays or structures. */
92 ir_instruction::constant_expression_value()
94 ir_constant_visitor visitor
;
96 this->accept(& visitor
);
102 ir_constant_visitor::visit(ir_variable
*ir
)
110 ir_constant_visitor::visit(ir_function_signature
*ir
)
118 ir_constant_visitor::visit(ir_function
*ir
)
125 ir_constant_visitor::visit(ir_expression
*ir
)
129 unsigned int operand
, c
;
134 const glsl_type
*type
= NULL
;
136 for (operand
= 0; operand
< ir
->get_num_operands(); operand
++) {
137 op
[operand
] = ir
->operands
[operand
]->constant_expression_value();
142 switch (ir
->operation
) {
143 case ir_unop_logic_not
:
144 type
= ir
->operands
[0]->type
;
145 assert(type
->base_type
== GLSL_TYPE_BOOL
);
146 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
147 b
[c
] = !op
[0]->value
.b
[c
];
151 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
153 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
154 i
[c
] = op
[0]->value
.f
[c
];
158 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
||
159 op
[0]->type
->base_type
== GLSL_TYPE_INT
);
161 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
162 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
)
163 f
[c
] = op
[0]->value
.i
[c
];
165 f
[c
] = op
[0]->value
.u
[c
];
170 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
171 type
= ir
->operands
[0]->type
;
172 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
173 switch (ir
->operands
[0]->type
->base_type
) {
175 u
[c
] = op
[0]->value
.u
[c
] + op
[1]->value
.u
[c
];
178 i
[c
] = op
[0]->value
.i
[c
] + op
[1]->value
.i
[c
];
180 case GLSL_TYPE_FLOAT
:
181 f
[c
] = op
[0]->value
.f
[c
] + op
[1]->value
.f
[c
];
190 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
191 type
= ir
->operands
[0]->type
;
192 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
193 switch (ir
->operands
[0]->type
->base_type
) {
195 u
[c
] = op
[0]->value
.u
[c
] - op
[1]->value
.u
[c
];
198 i
[c
] = op
[0]->value
.i
[c
] - op
[1]->value
.i
[c
];
200 case GLSL_TYPE_FLOAT
:
201 f
[c
] = op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
210 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
&&
211 !ir
->operands
[0]->type
->is_matrix()) {
212 type
= ir
->operands
[0]->type
;
213 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
214 switch (ir
->operands
[0]->type
->base_type
) {
216 u
[c
] = op
[0]->value
.u
[c
] * op
[1]->value
.u
[c
];
219 i
[c
] = op
[0]->value
.i
[c
] * op
[1]->value
.i
[c
];
221 case GLSL_TYPE_FLOAT
:
222 f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
231 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
232 type
= ir
->operands
[0]->type
;
233 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
234 switch (ir
->operands
[0]->type
->base_type
) {
236 u
[c
] = op
[0]->value
.u
[c
] / op
[1]->value
.u
[c
];
239 i
[c
] = op
[0]->value
.i
[c
] / op
[1]->value
.i
[c
];
241 case GLSL_TYPE_FLOAT
:
242 f
[c
] = op
[0]->value
.f
[c
] / op
[1]->value
.f
[c
];
250 case ir_binop_logic_and
:
251 type
= ir
->operands
[0]->type
;
252 assert(type
->base_type
== GLSL_TYPE_BOOL
);
253 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
254 b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
256 case ir_binop_logic_xor
:
257 type
= ir
->operands
[0]->type
;
258 assert(type
->base_type
== GLSL_TYPE_BOOL
);
259 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
260 b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
262 case ir_binop_logic_or
:
263 type
= ir
->operands
[0]->type
;
264 assert(type
->base_type
== GLSL_TYPE_BOOL
);
265 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
266 b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
270 type
= glsl_type::bool_type
;
271 switch (ir
->operands
[0]->type
->base_type
) {
273 b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
276 b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
278 case GLSL_TYPE_FLOAT
:
279 b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
285 case ir_binop_greater
:
286 type
= glsl_type::bool_type
;
287 switch (ir
->operands
[0]->type
->base_type
) {
289 b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
292 b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
294 case GLSL_TYPE_FLOAT
:
295 b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
301 case ir_binop_lequal
:
302 type
= glsl_type::bool_type
;
303 switch (ir
->operands
[0]->type
->base_type
) {
305 b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
308 b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
310 case GLSL_TYPE_FLOAT
:
311 b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
317 case ir_binop_gequal
:
318 type
= glsl_type::bool_type
;
319 switch (ir
->operands
[0]->type
->base_type
) {
321 b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
324 b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
326 case GLSL_TYPE_FLOAT
:
327 b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
335 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
336 type
= glsl_type::bool_type
;
338 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
339 switch (ir
->operands
[0]->type
->base_type
) {
341 b
[0] = b
[0] && op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
344 b
[0] = b
[0] && op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
346 case GLSL_TYPE_FLOAT
:
347 b
[0] = b
[0] && op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
350 b
[0] = b
[0] && op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
358 case ir_binop_nequal
:
359 if (ir
->operands
[0]->type
== ir
->operands
[1]->type
) {
360 type
= glsl_type::bool_type
;
362 for (c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
363 switch (ir
->operands
[0]->type
->base_type
) {
365 b
[0] = b
[0] || op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
368 b
[0] = b
[0] || op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
370 case GLSL_TYPE_FLOAT
:
371 b
[0] = b
[0] || op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
374 b
[0] = b
[0] || op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
388 switch (type
->base_type
) {
390 value
= new ir_constant(type
, u
);
393 value
= new ir_constant(type
, i
);
395 case GLSL_TYPE_FLOAT
:
396 value
= new ir_constant(type
, f
);
399 value
= new ir_constant(type
, b
);
407 ir_constant_visitor::visit(ir_swizzle
*ir
)
415 ir_constant_visitor::visit(ir_dereference
*ir
)
419 if (ir
->mode
== ir_dereference::ir_reference_variable
) {
420 ir_variable
*var
= ir
->var
->as_variable();
421 if (var
&& var
->constant_value
) {
422 value
= new ir_constant(ir
->type
, &var
->constant_value
->value
);
425 /* FINISHME: Other dereference modes. */
430 ir_constant_visitor::visit(ir_assignment
*ir
)
438 ir_constant_visitor::visit(ir_constant
*ir
)
445 ir_constant_visitor::visit(ir_call
*ir
)
453 ir_constant_visitor::visit(ir_return
*ir
)
461 ir_constant_visitor::visit(ir_if
*ir
)
469 ir_constant_visitor::visit(ir_loop
*ir
)
477 ir_constant_visitor::visit(ir_loop_jump
*ir
)