ir_constant_expression.cpp revision f14e596f11b4e44c75a880536efb1e8c5a72da7d
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 */ 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_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 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 114ir_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 128void 129ir_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 583void 584ir_constant_visitor::visit(ir_texture *ir) 585{ 586 // FINISHME: Do stuff with texture lookups 587 (void) ir; 588 value = NULL; 589} 590 591 592void 593ir_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 622void 623ir_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 = (ir_constant *)var->constant_value->clone(NULL); 630} 631 632 633void 634ir_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 688void 689ir_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 697void 698ir_constant_visitor::visit(ir_assignment *ir) 699{ 700 (void) ir; 701 value = NULL; 702} 703 704 705void 706ir_constant_visitor::visit(ir_constant *ir) 707{ 708 value = ir; 709} 710 711 712void 713ir_constant_visitor::visit(ir_call *ir) 714{ 715 (void) ir; 716 value = NULL; 717} 718 719 720void 721ir_constant_visitor::visit(ir_return *ir) 722{ 723 (void) ir; 724 value = NULL; 725} 726 727 728void 729ir_constant_visitor::visit(ir_discard *ir) 730{ 731 (void) ir; 732 value = NULL; 733} 734 735 736void 737ir_constant_visitor::visit(ir_if *ir) 738{ 739 (void) ir; 740 value = NULL; 741} 742 743 744void 745ir_constant_visitor::visit(ir_loop *ir) 746{ 747 (void) ir; 748 value = NULL; 749} 750 751 752void 753ir_constant_visitor::visit(ir_loop_jump *ir) 754{ 755 (void) ir; 756 value = NULL; 757} 758