ir_constant_expression.cpp revision 29285882676388aacff123e8bdf025904abf8ea9
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_if *); 79 virtual void visit(ir_loop *); 80 virtual void visit(ir_loop_jump *); 81 /*@}*/ 82 83 /** 84 * Value of the constant expression. 85 * 86 * \note 87 * This field will be \c NULL if the expression is not constant valued. 88 */ 89 /* FINIHSME: This cannot hold values for constant arrays or structures. */ 90 ir_constant *value; 91}; 92 93 94ir_constant * 95ir_instruction::constant_expression_value() 96{ 97 ir_constant_visitor visitor; 98 99 this->accept(& visitor); 100 return visitor.value; 101} 102 103 104void 105ir_constant_visitor::visit(ir_variable *ir) 106{ 107 (void) ir; 108 value = NULL; 109} 110 111 112void 113ir_constant_visitor::visit(ir_function_signature *ir) 114{ 115 (void) ir; 116 value = NULL; 117} 118 119 120void 121ir_constant_visitor::visit(ir_function *ir) 122{ 123 (void) ir; 124 value = NULL; 125} 126 127void 128ir_constant_visitor::visit(ir_expression *ir) 129{ 130 value = NULL; 131 ir_constant *op[2]; 132 unsigned int operand, c; 133 ir_constant_data data; 134 135 for (operand = 0; operand < ir->get_num_operands(); operand++) { 136 op[operand] = ir->operands[operand]->constant_expression_value(); 137 if (!op[operand]) 138 return; 139 } 140 141 switch (ir->operation) { 142 case ir_unop_logic_not: 143 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 144 for (c = 0; c < ir->operands[0]->type->components(); c++) 145 data.b[c] = !op[0]->value.b[c]; 146 break; 147 148 case ir_unop_f2i: 149 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 150 for (c = 0; c < ir->operands[0]->type->components(); c++) { 151 data.i[c] = op[0]->value.f[c]; 152 } 153 break; 154 case ir_unop_i2f: 155 assert(op[0]->type->base_type == GLSL_TYPE_UINT || 156 op[0]->type->base_type == GLSL_TYPE_INT); 157 for (c = 0; c < ir->operands[0]->type->components(); c++) { 158 if (op[0]->type->base_type == GLSL_TYPE_INT) 159 data.f[c] = op[0]->value.i[c]; 160 else 161 data.f[c] = op[0]->value.u[c]; 162 } 163 break; 164 case ir_unop_b2f: 165 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 166 for (c = 0; c < ir->operands[0]->type->components(); c++) { 167 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0; 168 } 169 break; 170 case ir_unop_f2b: 171 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 172 for (c = 0; c < ir->operands[0]->type->components(); c++) { 173 data.b[c] = bool(op[0]->value.f[c]); 174 } 175 break; 176 case ir_unop_b2i: 177 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 178 for (c = 0; c < ir->operands[0]->type->components(); c++) { 179 data.u[c] = op[0]->value.b[c] ? 1 : 0; 180 } 181 break; 182 case ir_unop_i2b: 183 assert(op[0]->type->is_integer()); 184 for (c = 0; c < ir->operands[0]->type->components(); c++) { 185 data.b[c] = bool(op[0]->value.u[c]); 186 } 187 break; 188 189 case ir_unop_neg: 190 for (c = 0; c < ir->operands[0]->type->components(); c++) { 191 switch (ir->type->base_type) { 192 case GLSL_TYPE_UINT: 193 data.u[c] = -op[0]->value.u[c]; 194 break; 195 case GLSL_TYPE_INT: 196 data.i[c] = -op[0]->value.i[c]; 197 break; 198 case GLSL_TYPE_FLOAT: 199 data.f[c] = -op[0]->value.f[c]; 200 break; 201 default: 202 assert(0); 203 } 204 } 205 break; 206 207 case ir_unop_abs: 208 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 209 for (c = 0; c < ir->operands[0]->type->components(); c++) { 210 switch (ir->type->base_type) { 211 case GLSL_TYPE_UINT: 212 data.u[c] = op[0]->value.u[c]; 213 break; 214 case GLSL_TYPE_INT: 215 data.i[c] = op[0]->value.i[c]; 216 if (data.i[c] < 0) 217 data.i[c] = -data.i[c]; 218 break; 219 case GLSL_TYPE_FLOAT: 220 data.f[c] = fabs(op[0]->value.f[c]); 221 break; 222 default: 223 assert(0); 224 } 225 } 226 break; 227 228 case ir_unop_rcp: 229 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 230 for (c = 0; c < ir->operands[0]->type->components(); c++) { 231 switch (ir->type->base_type) { 232 case GLSL_TYPE_UINT: 233 if (op[0]->value.u[c] != 0.0) 234 data.u[c] = 1 / op[0]->value.u[c]; 235 break; 236 case GLSL_TYPE_INT: 237 if (op[0]->value.i[c] != 0.0) 238 data.i[c] = 1 / op[0]->value.i[c]; 239 break; 240 case GLSL_TYPE_FLOAT: 241 if (op[0]->value.f[c] != 0.0) 242 data.f[c] = 1.0 / op[0]->value.f[c]; 243 break; 244 default: 245 assert(0); 246 } 247 } 248 break; 249 250 case ir_unop_rsq: 251 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 252 for (c = 0; c < ir->operands[0]->type->components(); c++) { 253 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]); 254 } 255 break; 256 257 case ir_unop_sqrt: 258 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 259 for (c = 0; c < ir->operands[0]->type->components(); c++) { 260 data.f[c] = sqrtf(op[0]->value.f[c]); 261 } 262 break; 263 264 case ir_unop_exp: 265 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 266 for (c = 0; c < ir->operands[0]->type->components(); c++) { 267 data.f[c] = expf(op[0]->value.f[c]); 268 } 269 break; 270 271 case ir_unop_log: 272 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 273 for (c = 0; c < ir->operands[0]->type->components(); c++) { 274 data.f[c] = logf(op[0]->value.f[c]); 275 } 276 break; 277 278 case ir_unop_dFdx: 279 case ir_unop_dFdy: 280 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 281 for (c = 0; c < ir->operands[0]->type->components(); c++) { 282 data.f[c] = 0.0; 283 } 284 break; 285 286 case ir_binop_add: 287 if (ir->operands[0]->type == ir->operands[1]->type) { 288 for (c = 0; c < ir->operands[0]->type->components(); c++) { 289 switch (ir->operands[0]->type->base_type) { 290 case GLSL_TYPE_UINT: 291 data.u[c] = op[0]->value.u[c] + op[1]->value.u[c]; 292 break; 293 case GLSL_TYPE_INT: 294 data.i[c] = op[0]->value.i[c] + op[1]->value.i[c]; 295 break; 296 case GLSL_TYPE_FLOAT: 297 data.f[c] = op[0]->value.f[c] + op[1]->value.f[c]; 298 break; 299 default: 300 assert(0); 301 } 302 } 303 } else 304 /* FINISHME: Support operations with non-equal types. */ 305 return; 306 307 break; 308 case ir_binop_sub: 309 if (ir->operands[0]->type == ir->operands[1]->type) { 310 for (c = 0; c < ir->operands[0]->type->components(); c++) { 311 switch (ir->operands[0]->type->base_type) { 312 case GLSL_TYPE_UINT: 313 data.u[c] = op[0]->value.u[c] - op[1]->value.u[c]; 314 break; 315 case GLSL_TYPE_INT: 316 data.i[c] = op[0]->value.i[c] - op[1]->value.i[c]; 317 break; 318 case GLSL_TYPE_FLOAT: 319 data.f[c] = op[0]->value.f[c] - op[1]->value.f[c]; 320 break; 321 default: 322 assert(0); 323 } 324 } 325 } else 326 /* FINISHME: Support operations with non-equal types. */ 327 return; 328 329 break; 330 case ir_binop_mul: 331 if (ir->operands[0]->type == ir->operands[1]->type && 332 !ir->operands[0]->type->is_matrix()) { 333 for (c = 0; c < ir->operands[0]->type->components(); c++) { 334 switch (ir->operands[0]->type->base_type) { 335 case GLSL_TYPE_UINT: 336 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c]; 337 break; 338 case GLSL_TYPE_INT: 339 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c]; 340 break; 341 case GLSL_TYPE_FLOAT: 342 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c]; 343 break; 344 default: 345 assert(0); 346 } 347 } 348 } else 349 /* FINISHME: Support operations with non-equal types. */ 350 return; 351 352 break; 353 case ir_binop_div: 354 if (ir->operands[0]->type == ir->operands[1]->type) { 355 for (c = 0; c < ir->operands[0]->type->components(); c++) { 356 switch (ir->operands[0]->type->base_type) { 357 case GLSL_TYPE_UINT: 358 data.u[c] = op[0]->value.u[c] / op[1]->value.u[c]; 359 break; 360 case GLSL_TYPE_INT: 361 data.i[c] = op[0]->value.i[c] / op[1]->value.i[c]; 362 break; 363 case GLSL_TYPE_FLOAT: 364 data.f[c] = op[0]->value.f[c] / op[1]->value.f[c]; 365 break; 366 default: 367 assert(0); 368 } 369 } 370 } else 371 /* FINISHME: Support operations with non-equal types. */ 372 return; 373 374 break; 375 case ir_binop_logic_and: 376 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 377 for (c = 0; c < ir->operands[0]->type->components(); c++) 378 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; 379 break; 380 case ir_binop_logic_xor: 381 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 382 for (c = 0; c < ir->operands[0]->type->components(); c++) 383 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; 384 break; 385 case ir_binop_logic_or: 386 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 387 for (c = 0; c < ir->operands[0]->type->components(); c++) 388 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; 389 break; 390 391 case ir_binop_less: 392 switch (ir->operands[0]->type->base_type) { 393 case GLSL_TYPE_UINT: 394 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; 395 break; 396 case GLSL_TYPE_INT: 397 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; 398 break; 399 case GLSL_TYPE_FLOAT: 400 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; 401 break; 402 default: 403 assert(0); 404 } 405 break; 406 case ir_binop_greater: 407 switch (ir->operands[0]->type->base_type) { 408 case GLSL_TYPE_UINT: 409 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0]; 410 break; 411 case GLSL_TYPE_INT: 412 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0]; 413 break; 414 case GLSL_TYPE_FLOAT: 415 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0]; 416 break; 417 default: 418 assert(0); 419 } 420 break; 421 case ir_binop_lequal: 422 switch (ir->operands[0]->type->base_type) { 423 case GLSL_TYPE_UINT: 424 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0]; 425 break; 426 case GLSL_TYPE_INT: 427 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; 428 break; 429 case GLSL_TYPE_FLOAT: 430 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; 431 break; 432 default: 433 assert(0); 434 } 435 break; 436 case ir_binop_gequal: 437 switch (ir->operands[0]->type->base_type) { 438 case GLSL_TYPE_UINT: 439 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0]; 440 break; 441 case GLSL_TYPE_INT: 442 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0]; 443 break; 444 case GLSL_TYPE_FLOAT: 445 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0]; 446 break; 447 default: 448 assert(0); 449 } 450 break; 451 452 case ir_binop_equal: 453 data.b[0] = true; 454 for (c = 0; c < ir->operands[0]->type->components(); c++) { 455 switch (ir->operands[0]->type->base_type) { 456 case GLSL_TYPE_UINT: 457 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c]; 458 break; 459 case GLSL_TYPE_INT: 460 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c]; 461 break; 462 case GLSL_TYPE_FLOAT: 463 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c]; 464 break; 465 case GLSL_TYPE_BOOL: 466 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c]; 467 break; 468 default: 469 assert(0); 470 } 471 } 472 break; 473 case ir_binop_nequal: 474 data.b[0] = false; 475 for (c = 0; c < ir->operands[0]->type->components(); c++) { 476 switch (ir->operands[0]->type->base_type) { 477 case GLSL_TYPE_UINT: 478 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c]; 479 break; 480 case GLSL_TYPE_INT: 481 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c]; 482 break; 483 case GLSL_TYPE_FLOAT: 484 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c]; 485 break; 486 case GLSL_TYPE_BOOL: 487 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c]; 488 break; 489 default: 490 assert(0); 491 } 492 } 493 break; 494 495 default: 496 /* FINISHME: Should handle all expression types. */ 497 return; 498 } 499 500 void *ctx = talloc_parent(ir); 501 this->value = new(ctx) ir_constant(ir->type, &data); 502} 503 504 505void 506ir_constant_visitor::visit(ir_texture *ir) 507{ 508 // FINISHME: Do stuff with texture lookups 509 (void) ir; 510 value = NULL; 511} 512 513 514void 515ir_constant_visitor::visit(ir_swizzle *ir) 516{ 517 ir_constant *v = ir->val->constant_expression_value(); 518 519 this->value = NULL; 520 521 if (v != NULL) { 522 ir_constant_data data; 523 524 const unsigned swiz_idx[4] = { 525 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w 526 }; 527 528 for (unsigned i = 0; i < ir->mask.num_components; i++) { 529 switch (v->type->base_type) { 530 case GLSL_TYPE_UINT: 531 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 532 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 533 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 534 default: assert(!"Should not get here."); break; 535 } 536 } 537 538 void *ctx = talloc_parent(ir); 539 this->value = new(ctx) ir_constant(ir->type, &data); 540 } 541} 542 543 544void 545ir_constant_visitor::visit(ir_dereference_variable *ir) 546{ 547 value = NULL; 548 549 ir_variable *var = ir->variable_referenced(); 550 if (var && var->constant_value) 551 value = (ir_constant *)var->constant_value->clone(NULL); 552} 553 554 555void 556ir_constant_visitor::visit(ir_dereference_array *ir) 557{ 558 void *ctx = talloc_parent(ir); 559 ir_constant *array = ir->array->constant_expression_value(); 560 ir_constant *idx = ir->array_index->constant_expression_value(); 561 562 this->value = NULL; 563 564 if ((array != NULL) && (idx != NULL)) { 565 if (array->type->is_matrix()) { 566 /* Array access of a matrix results in a vector. 567 */ 568 const unsigned column = idx->value.u[0]; 569 570 const glsl_type *const column_type = array->type->column_type(); 571 572 /* Offset in the constant matrix to the first element of the column 573 * to be extracted. 574 */ 575 const unsigned mat_idx = column * column_type->vector_elements; 576 577 ir_constant_data data; 578 579 switch (column_type->base_type) { 580 case GLSL_TYPE_UINT: 581 case GLSL_TYPE_INT: 582 for (unsigned i = 0; i < column_type->vector_elements; i++) 583 data.u[i] = array->value.u[mat_idx + i]; 584 585 break; 586 587 case GLSL_TYPE_FLOAT: 588 for (unsigned i = 0; i < column_type->vector_elements; i++) 589 data.f[i] = array->value.f[mat_idx + i]; 590 591 break; 592 593 default: 594 assert(!"Should not get here."); 595 break; 596 } 597 598 this->value = new(ctx) ir_constant(column_type, &data); 599 } else if (array->type->is_vector()) { 600 const unsigned component = idx->value.u[0]; 601 602 this->value = new(ctx) ir_constant(array, component); 603 } else { 604 /* FINISHME: Handle access of constant arrays. */ 605 } 606 } 607} 608 609 610void 611ir_constant_visitor::visit(ir_dereference_record *ir) 612{ 613 ir_constant *v = ir->record->constant_expression_value(); 614 615 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL; 616} 617 618 619void 620ir_constant_visitor::visit(ir_assignment *ir) 621{ 622 (void) ir; 623 value = NULL; 624} 625 626 627void 628ir_constant_visitor::visit(ir_constant *ir) 629{ 630 value = ir; 631} 632 633 634void 635ir_constant_visitor::visit(ir_call *ir) 636{ 637 (void) ir; 638 value = NULL; 639} 640 641 642void 643ir_constant_visitor::visit(ir_return *ir) 644{ 645 (void) ir; 646 value = NULL; 647} 648 649 650void 651ir_constant_visitor::visit(ir_if *ir) 652{ 653 (void) ir; 654 value = NULL; 655} 656 657 658void 659ir_constant_visitor::visit(ir_loop *ir) 660{ 661 (void) ir; 662 value = NULL; 663} 664 665 666void 667ir_constant_visitor::visit(ir_loop_jump *ir) 668{ 669 (void) ir; 670 value = NULL; 671} 672