541398a91c7afd346c69700e1d60d365836a59e6
[mesa.git] / src / glsl / ir_constant_expression.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_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 #include <math.h>
37 #include "ir.h"
38 #include "ir_visitor.h"
39 #include "glsl_types.h"
40
41 /**
42 * Visitor class for evaluating constant expressions
43 */
44 class ir_constant_visitor : public ir_visitor {
45 public:
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_function_signature *);
67 virtual void visit(ir_function *);
68 virtual void visit(ir_expression *);
69 virtual void visit(ir_texture *);
70 virtual void visit(ir_swizzle *);
71 virtual void visit(ir_dereference_variable *);
72 virtual void visit(ir_dereference_array *);
73 virtual void visit(ir_dereference_record *);
74 virtual void visit(ir_assignment *);
75 virtual void visit(ir_constant *);
76 virtual void visit(ir_call *);
77 virtual void visit(ir_return *);
78 virtual void visit(ir_discard *);
79 virtual void visit(ir_if *);
80 virtual void visit(ir_loop *);
81 virtual void visit(ir_loop_jump *);
82 /*@}*/
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
95 ir_constant *
96 ir_instruction::constant_expression_value()
97 {
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102 }
103
104
105 void
106 ir_constant_visitor::visit(ir_variable *ir)
107 {
108 (void) ir;
109 value = NULL;
110 }
111
112
113 void
114 ir_constant_visitor::visit(ir_function_signature *ir)
115 {
116 (void) ir;
117 value = NULL;
118 }
119
120
121 void
122 ir_constant_visitor::visit(ir_function *ir)
123 {
124 (void) ir;
125 value = NULL;
126 }
127
128 void
129 ir_constant_visitor::visit(ir_expression *ir)
130 {
131 value = NULL;
132 ir_constant *op[2] = { NULL, NULL };
133 ir_constant_data data;
134
135 memset(&data, 0, sizeof(data));
136
137 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
138 op[operand] = ir->operands[operand]->constant_expression_value();
139 if (!op[operand])
140 return;
141 }
142
143 if (op[1] != NULL)
144 assert(op[0]->type->base_type == op[1]->type->base_type);
145
146 bool op0_scalar = op[0]->type->is_scalar();
147 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
148
149 /* When iterating over a vector or matrix's components, we want to increase
150 * the loop counter. However, for scalars, we want to stay at 0.
151 */
152 unsigned c0_inc = op0_scalar ? 1 : 0;
153 unsigned c1_inc = op1_scalar ? 1 : 0;
154 unsigned components = op[op1_scalar ? 0 : 1]->type->components();
155
156 switch (ir->operation) {
157 case ir_unop_logic_not:
158 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
159 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
160 data.b[c] = !op[0]->value.b[c];
161 break;
162
163 case ir_unop_f2i:
164 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
165 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
166 data.i[c] = op[0]->value.f[c];
167 }
168 break;
169 case ir_unop_i2f:
170 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
171 op[0]->type->base_type == GLSL_TYPE_INT);
172 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
173 if (op[0]->type->base_type == GLSL_TYPE_INT)
174 data.f[c] = op[0]->value.i[c];
175 else
176 data.f[c] = op[0]->value.u[c];
177 }
178 break;
179 case ir_unop_b2f:
180 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
181 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
182 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
183 }
184 break;
185 case ir_unop_f2b:
186 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
187 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
188 data.b[c] = bool(op[0]->value.f[c]);
189 }
190 break;
191 case ir_unop_b2i:
192 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
193 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
194 data.u[c] = op[0]->value.b[c] ? 1 : 0;
195 }
196 break;
197 case ir_unop_i2b:
198 assert(op[0]->type->is_integer());
199 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
200 data.b[c] = bool(op[0]->value.u[c]);
201 }
202 break;
203
204 case ir_unop_fract:
205 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
206 switch (ir->type->base_type) {
207 case GLSL_TYPE_UINT:
208 data.u[c] = 0;
209 break;
210 case GLSL_TYPE_INT:
211 data.i[c] = 0;
212 break;
213 case GLSL_TYPE_FLOAT:
214 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
215 break;
216 default:
217 assert(0);
218 }
219 }
220 break;
221
222 case ir_unop_neg:
223 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
224 switch (ir->type->base_type) {
225 case GLSL_TYPE_UINT:
226 data.u[c] = -op[0]->value.u[c];
227 break;
228 case GLSL_TYPE_INT:
229 data.i[c] = -op[0]->value.i[c];
230 break;
231 case GLSL_TYPE_FLOAT:
232 data.f[c] = -op[0]->value.f[c];
233 break;
234 default:
235 assert(0);
236 }
237 }
238 break;
239
240 case ir_unop_abs:
241 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
242 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
243 switch (ir->type->base_type) {
244 case GLSL_TYPE_UINT:
245 data.u[c] = op[0]->value.u[c];
246 break;
247 case GLSL_TYPE_INT:
248 data.i[c] = op[0]->value.i[c];
249 if (data.i[c] < 0)
250 data.i[c] = -data.i[c];
251 break;
252 case GLSL_TYPE_FLOAT:
253 data.f[c] = fabs(op[0]->value.f[c]);
254 break;
255 default:
256 assert(0);
257 }
258 }
259 break;
260
261 case ir_unop_rcp:
262 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
263 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
264 switch (ir->type->base_type) {
265 case GLSL_TYPE_UINT:
266 if (op[0]->value.u[c] != 0.0)
267 data.u[c] = 1 / op[0]->value.u[c];
268 break;
269 case GLSL_TYPE_INT:
270 if (op[0]->value.i[c] != 0.0)
271 data.i[c] = 1 / op[0]->value.i[c];
272 break;
273 case GLSL_TYPE_FLOAT:
274 if (op[0]->value.f[c] != 0.0)
275 data.f[c] = 1.0 / op[0]->value.f[c];
276 break;
277 default:
278 assert(0);
279 }
280 }
281 break;
282
283 case ir_unop_rsq:
284 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
285 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
286 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
287 }
288 break;
289
290 case ir_unop_sqrt:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
292 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
293 data.f[c] = sqrtf(op[0]->value.f[c]);
294 }
295 break;
296
297 case ir_unop_exp:
298 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
299 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
300 data.f[c] = expf(op[0]->value.f[c]);
301 }
302 break;
303
304 case ir_unop_log:
305 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
306 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
307 data.f[c] = logf(op[0]->value.f[c]);
308 }
309 break;
310
311 case ir_unop_dFdx:
312 case ir_unop_dFdy:
313 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
314 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
315 data.f[c] = 0.0;
316 }
317 break;
318
319 case ir_binop_dot:
320 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
321 data.f[0] = 0;
322 for (unsigned c = 0; c < op[0]->type->components(); c++) {
323 switch (ir->operands[0]->type->base_type) {
324 case GLSL_TYPE_UINT:
325 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
326 break;
327 case GLSL_TYPE_INT:
328 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
329 break;
330 case GLSL_TYPE_FLOAT:
331 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
332 break;
333 default:
334 assert(0);
335 }
336 }
337
338 break;
339 case ir_binop_add:
340 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
341 for (unsigned c = 0, c0 = 0, c1 = 0;
342 c < components;
343 c0 += c0_inc, c1 += c1_inc, c++) {
344
345 switch (ir->operands[0]->type->base_type) {
346 case GLSL_TYPE_UINT:
347 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
348 break;
349 case GLSL_TYPE_INT:
350 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
351 break;
352 case GLSL_TYPE_FLOAT:
353 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
354 break;
355 default:
356 assert(0);
357 }
358 }
359
360 break;
361 case ir_binop_sub:
362 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
363 for (unsigned c = 0, c0 = 0, c1 = 0;
364 c < components;
365 c0 += c0_inc, c1 += c1_inc, c++) {
366
367 switch (ir->operands[0]->type->base_type) {
368 case GLSL_TYPE_UINT:
369 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
370 break;
371 case GLSL_TYPE_INT:
372 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
373 break;
374 case GLSL_TYPE_FLOAT:
375 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
376 break;
377 default:
378 assert(0);
379 }
380 }
381
382 break;
383 case ir_binop_mul:
384 /* Check for equal types, or unequal types involving scalars */
385 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
386 || op0_scalar || op1_scalar) {
387 for (unsigned c = 0, c0 = 0, c1 = 0;
388 c < components;
389 c0 += c0_inc, c1 += c1_inc, c++) {
390
391 switch (ir->operands[0]->type->base_type) {
392 case GLSL_TYPE_UINT:
393 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
394 break;
395 case GLSL_TYPE_INT:
396 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
397 break;
398 case GLSL_TYPE_FLOAT:
399 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
400 break;
401 default:
402 assert(0);
403 }
404 }
405 } else {
406 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
407
408 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
409 * matrix can be a GLSL vector, either N or P can be 1.
410 *
411 * For vec*mat, the vector is treated as a row vector. This
412 * means the vector is a 1-row x M-column matrix.
413 *
414 * For mat*vec, the vector is treated as a column vector. Since
415 * matrix_columns is 1 for vectors, this just works.
416 */
417 const unsigned n = op[0]->type->is_vector()
418 ? 1 : op[0]->type->vector_elements;
419 const unsigned m = op[1]->type->vector_elements;
420 const unsigned p = op[1]->type->matrix_columns;
421 for (unsigned j = 0; j < p; j++) {
422 for (unsigned i = 0; i < n; i++) {
423 for (unsigned k = 0; k < m; k++) {
424 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
425 }
426 }
427 }
428 }
429
430 break;
431 case ir_binop_div:
432 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
433 for (unsigned c = 0, c0 = 0, c1 = 0;
434 c < components;
435 c0 += c0_inc, c1 += c1_inc, c++) {
436
437 switch (ir->operands[0]->type->base_type) {
438 case GLSL_TYPE_UINT:
439 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
440 break;
441 case GLSL_TYPE_INT:
442 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
443 break;
444 case GLSL_TYPE_FLOAT:
445 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
446 break;
447 default:
448 assert(0);
449 }
450 }
451
452 break;
453 case ir_binop_logic_and:
454 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
455 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
456 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
457 break;
458 case ir_binop_logic_xor:
459 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
460 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
461 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
462 break;
463 case ir_binop_logic_or:
464 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
465 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
466 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
467 break;
468
469 case ir_binop_less:
470 switch (ir->operands[0]->type->base_type) {
471 case GLSL_TYPE_UINT:
472 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
473 break;
474 case GLSL_TYPE_INT:
475 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
476 break;
477 case GLSL_TYPE_FLOAT:
478 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
479 break;
480 default:
481 assert(0);
482 }
483 break;
484 case ir_binop_greater:
485 switch (ir->operands[0]->type->base_type) {
486 case GLSL_TYPE_UINT:
487 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
488 break;
489 case GLSL_TYPE_INT:
490 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
491 break;
492 case GLSL_TYPE_FLOAT:
493 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
494 break;
495 default:
496 assert(0);
497 }
498 break;
499 case ir_binop_lequal:
500 switch (ir->operands[0]->type->base_type) {
501 case GLSL_TYPE_UINT:
502 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
503 break;
504 case GLSL_TYPE_INT:
505 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
506 break;
507 case GLSL_TYPE_FLOAT:
508 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
509 break;
510 default:
511 assert(0);
512 }
513 break;
514 case ir_binop_gequal:
515 switch (ir->operands[0]->type->base_type) {
516 case GLSL_TYPE_UINT:
517 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
518 break;
519 case GLSL_TYPE_INT:
520 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
521 break;
522 case GLSL_TYPE_FLOAT:
523 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
524 break;
525 default:
526 assert(0);
527 }
528 break;
529
530 case ir_binop_equal:
531 data.b[0] = true;
532 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
533 switch (ir->operands[0]->type->base_type) {
534 case GLSL_TYPE_UINT:
535 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
536 break;
537 case GLSL_TYPE_INT:
538 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
539 break;
540 case GLSL_TYPE_FLOAT:
541 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
542 break;
543 case GLSL_TYPE_BOOL:
544 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
545 break;
546 default:
547 assert(0);
548 }
549 }
550 break;
551 case ir_binop_nequal:
552 data.b[0] = false;
553 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
554 switch (ir->operands[0]->type->base_type) {
555 case GLSL_TYPE_UINT:
556 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
557 break;
558 case GLSL_TYPE_INT:
559 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
560 break;
561 case GLSL_TYPE_FLOAT:
562 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
563 break;
564 case GLSL_TYPE_BOOL:
565 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
566 break;
567 default:
568 assert(0);
569 }
570 }
571 break;
572
573 default:
574 /* FINISHME: Should handle all expression types. */
575 return;
576 }
577
578 void *ctx = talloc_parent(ir);
579 this->value = new(ctx) ir_constant(ir->type, &data);
580 }
581
582
583 void
584 ir_constant_visitor::visit(ir_texture *ir)
585 {
586 // FINISHME: Do stuff with texture lookups
587 (void) ir;
588 value = NULL;
589 }
590
591
592 void
593 ir_constant_visitor::visit(ir_swizzle *ir)
594 {
595 ir_constant *v = ir->val->constant_expression_value();
596
597 this->value = NULL;
598
599 if (v != NULL) {
600 ir_constant_data data;
601
602 const unsigned swiz_idx[4] = {
603 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
604 };
605
606 for (unsigned i = 0; i < ir->mask.num_components; i++) {
607 switch (v->type->base_type) {
608 case GLSL_TYPE_UINT:
609 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
610 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
611 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
612 default: assert(!"Should not get here."); break;
613 }
614 }
615
616 void *ctx = talloc_parent(ir);
617 this->value = new(ctx) ir_constant(ir->type, &data);
618 }
619 }
620
621
622 void
623 ir_constant_visitor::visit(ir_dereference_variable *ir)
624 {
625 value = NULL;
626
627 ir_variable *var = ir->variable_referenced();
628 if (var && var->constant_value)
629 value = var->constant_value->clone(NULL);
630 }
631
632
633 void
634 ir_constant_visitor::visit(ir_dereference_array *ir)
635 {
636 void *ctx = talloc_parent(ir);
637 ir_constant *array = ir->array->constant_expression_value();
638 ir_constant *idx = ir->array_index->constant_expression_value();
639
640 this->value = NULL;
641
642 if ((array != NULL) && (idx != NULL)) {
643 if (array->type->is_matrix()) {
644 /* Array access of a matrix results in a vector.
645 */
646 const unsigned column = idx->value.u[0];
647
648 const glsl_type *const column_type = array->type->column_type();
649
650 /* Offset in the constant matrix to the first element of the column
651 * to be extracted.
652 */
653 const unsigned mat_idx = column * column_type->vector_elements;
654
655 ir_constant_data data;
656
657 switch (column_type->base_type) {
658 case GLSL_TYPE_UINT:
659 case GLSL_TYPE_INT:
660 for (unsigned i = 0; i < column_type->vector_elements; i++)
661 data.u[i] = array->value.u[mat_idx + i];
662
663 break;
664
665 case GLSL_TYPE_FLOAT:
666 for (unsigned i = 0; i < column_type->vector_elements; i++)
667 data.f[i] = array->value.f[mat_idx + i];
668
669 break;
670
671 default:
672 assert(!"Should not get here.");
673 break;
674 }
675
676 this->value = new(ctx) ir_constant(column_type, &data);
677 } else if (array->type->is_vector()) {
678 const unsigned component = idx->value.u[0];
679
680 this->value = new(ctx) ir_constant(array, component);
681 } else {
682 /* FINISHME: Handle access of constant arrays. */
683 }
684 }
685 }
686
687
688 void
689 ir_constant_visitor::visit(ir_dereference_record *ir)
690 {
691 ir_constant *v = ir->record->constant_expression_value();
692
693 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
694 }
695
696
697 void
698 ir_constant_visitor::visit(ir_assignment *ir)
699 {
700 (void) ir;
701 value = NULL;
702 }
703
704
705 void
706 ir_constant_visitor::visit(ir_constant *ir)
707 {
708 value = ir;
709 }
710
711
712 void
713 ir_constant_visitor::visit(ir_call *ir)
714 {
715 (void) ir;
716 value = NULL;
717 }
718
719
720 void
721 ir_constant_visitor::visit(ir_return *ir)
722 {
723 (void) ir;
724 value = NULL;
725 }
726
727
728 void
729 ir_constant_visitor::visit(ir_discard *ir)
730 {
731 (void) ir;
732 value = NULL;
733 }
734
735
736 void
737 ir_constant_visitor::visit(ir_if *ir)
738 {
739 (void) ir;
740 value = NULL;
741 }
742
743
744 void
745 ir_constant_visitor::visit(ir_loop *ir)
746 {
747 (void) ir;
748 value = NULL;
749 }
750
751
752 void
753 ir_constant_visitor::visit(ir_loop_jump *ir)
754 {
755 (void) ir;
756 value = NULL;
757 }