glsl_parser_extras.cpp revision b9e27cc1426e3242a003fa5ae91fab330694009a
1/* 2 * Copyright © 2008, 2009 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#include <stdio.h> 24#include <stdarg.h> 25#include <string.h> 26#include <assert.h> 27 28extern "C" { 29#include "main/core.h" /* for struct gl_context */ 30} 31 32#include "ralloc.h" 33#include "ast.h" 34#include "glsl_parser_extras.h" 35#include "glsl_parser.h" 36#include "ir_optimization.h" 37#include "loop_analysis.h" 38 39_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx, 40 GLenum target, void *mem_ctx) 41{ 42 switch (target) { 43 case GL_VERTEX_SHADER: this->target = vertex_shader; break; 44 case GL_FRAGMENT_SHADER: this->target = fragment_shader; break; 45 case GL_GEOMETRY_SHADER: this->target = geometry_shader; break; 46 } 47 48 this->scanner = NULL; 49 this->translation_unit.make_empty(); 50 this->symbols = new(mem_ctx) glsl_symbol_table; 51 this->info_log = ralloc_strdup(mem_ctx, ""); 52 this->error = false; 53 this->loop_nesting_ast = NULL; 54 this->switch_nesting_ast = NULL; 55 56 this->num_builtins_to_link = 0; 57 58 /* Set default language version and extensions */ 59 this->language_version = 110; 60 this->es_shader = false; 61 this->ARB_texture_rectangle_enable = true; 62 63 /* OpenGL ES 2.0 has different defaults from desktop GL. */ 64 if (ctx->API == API_OPENGLES2) { 65 this->language_version = 100; 66 this->es_shader = true; 67 this->ARB_texture_rectangle_enable = false; 68 } 69 70 this->extensions = &ctx->Extensions; 71 72 this->Const.MaxLights = ctx->Const.MaxLights; 73 this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; 74 this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; 75 this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; 76 this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; 77 this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; 78 this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4; 79 this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits; 80 this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; 81 this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; 82 this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; 83 84 this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; 85 86 /* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2 87 * Core context is supported, this logic will need change. Older versions of 88 * GLSL are no longer supported outside the compatibility contexts of 3.x. 89 */ 90 this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2) 91 || ctx->Extensions.ARB_ES2_compatibility; 92 this->Const.GLSL_110 = (ctx->API == API_OPENGL); 93 this->Const.GLSL_120 = (ctx->API == API_OPENGL) 94 && (ctx->Const.GLSLVersion >= 120); 95 this->Const.GLSL_130 = (ctx->API == API_OPENGL) 96 && (ctx->Const.GLSLVersion >= 130); 97 98 const unsigned lowest_version = 99 (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility 100 ? 100 : 110; 101 const unsigned highest_version = 102 (ctx->API == API_OPENGL) ? ctx->Const.GLSLVersion : 100; 103 char *supported = ralloc_strdup(this, ""); 104 105 for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) { 106 const char *const prefix = (ver == lowest_version) 107 ? "" 108 : ((ver == highest_version) ? ", and " : ", "); 109 110 ralloc_asprintf_append(& supported, "%s%d.%02d%s", 111 prefix, 112 ver / 100, ver % 100, 113 (ver == 100) ? " ES" : ""); 114 } 115 116 this->supported_version_string = supported; 117 118 if (ctx->Const.ForceGLSLExtensionsWarn) 119 _mesa_glsl_process_extension("all", NULL, "warn", NULL, this); 120} 121 122const char * 123_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) 124{ 125 switch (target) { 126 case vertex_shader: return "vertex"; 127 case fragment_shader: return "fragment"; 128 case geometry_shader: return "geometry"; 129 } 130 131 assert(!"Should not get here."); 132 return "unknown"; 133} 134 135 136void 137_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, 138 const char *fmt, ...) 139{ 140 va_list ap; 141 142 state->error = true; 143 144 assert(state->info_log != NULL); 145 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ", 146 locp->source, 147 locp->first_line, 148 locp->first_column); 149 va_start(ap, fmt); 150 ralloc_vasprintf_append(&state->info_log, fmt, ap); 151 va_end(ap); 152 ralloc_strcat(&state->info_log, "\n"); 153} 154 155 156void 157_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, 158 const char *fmt, ...) 159{ 160 va_list ap; 161 162 assert(state->info_log != NULL); 163 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ", 164 locp->source, 165 locp->first_line, 166 locp->first_column); 167 va_start(ap, fmt); 168 ralloc_vasprintf_append(&state->info_log, fmt, ap); 169 va_end(ap); 170 ralloc_strcat(&state->info_log, "\n"); 171} 172 173 174/** 175 * Enum representing the possible behaviors that can be specified in 176 * an #extension directive. 177 */ 178enum ext_behavior { 179 extension_disable, 180 extension_enable, 181 extension_require, 182 extension_warn 183}; 184 185/** 186 * Element type for _mesa_glsl_supported_extensions 187 */ 188struct _mesa_glsl_extension { 189 /** 190 * Name of the extension when referred to in a GLSL extension 191 * statement 192 */ 193 const char *name; 194 195 /** True if this extension is available to vertex shaders */ 196 bool avail_in_VS; 197 198 /** True if this extension is available to geometry shaders */ 199 bool avail_in_GS; 200 201 /** True if this extension is available to fragment shaders */ 202 bool avail_in_FS; 203 204 /** True if this extension is available to desktop GL shaders */ 205 bool avail_in_GL; 206 207 /** True if this extension is available to GLES shaders */ 208 bool avail_in_ES; 209 210 /** 211 * Flag in the gl_extensions struct indicating whether this 212 * extension is supported by the driver, or 213 * &gl_extensions::dummy_true if supported by all drivers. 214 * 215 * Note: the type (GLboolean gl_extensions::*) is a "pointer to 216 * member" type, the type-safe alternative to the "offsetof" macro. 217 * In a nutshell: 218 * 219 * - foo bar::* p declares p to be an "offset" to a field of type 220 * foo that exists within struct bar 221 * - &bar::baz computes the "offset" of field baz within struct bar 222 * - x.*p accesses the field of x that exists at "offset" p 223 * - x->*p is equivalent to (*x).*p 224 */ 225 const GLboolean gl_extensions::* supported_flag; 226 227 /** 228 * Flag in the _mesa_glsl_parse_state struct that should be set 229 * when this extension is enabled. 230 * 231 * See note in _mesa_glsl_extension::supported_flag about "pointer 232 * to member" types. 233 */ 234 bool _mesa_glsl_parse_state::* enable_flag; 235 236 /** 237 * Flag in the _mesa_glsl_parse_state struct that should be set 238 * when the shader requests "warn" behavior for this extension. 239 * 240 * See note in _mesa_glsl_extension::supported_flag about "pointer 241 * to member" types. 242 */ 243 bool _mesa_glsl_parse_state::* warn_flag; 244 245 246 bool compatible_with_state(const _mesa_glsl_parse_state *state) const; 247 void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; 248}; 249 250#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \ 251 { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ 252 &_mesa_glsl_parse_state::NAME##_enable, \ 253 &_mesa_glsl_parse_state::NAME##_warn } 254 255/** 256 * Table of extensions that can be enabled/disabled within a shader, 257 * and the conditions under which they are supported. 258 */ 259static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { 260 /* target availability API availability */ 261 /* name VS GS FS GL ES supported flag */ 262 EXT(ARB_conservative_depth, false, false, true, true, false, ARB_conservative_depth), 263 EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), 264 EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), 265 EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), 266 EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions), 267 EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true), 268 EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), 269 EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), 270 EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), 271 EXT(AMD_conservative_depth, false, false, true, true, false, ARB_conservative_depth), 272 EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), 273 EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), 274 EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external), 275}; 276 277#undef EXT 278 279 280/** 281 * Determine whether a given extension is compatible with the target, 282 * API, and extension information in the current parser state. 283 */ 284bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * 285 state) const 286{ 287 /* Check that this extension matches the type of shader we are 288 * compiling to. 289 */ 290 switch (state->target) { 291 case vertex_shader: 292 if (!this->avail_in_VS) { 293 return false; 294 } 295 break; 296 case geometry_shader: 297 if (!this->avail_in_GS) { 298 return false; 299 } 300 break; 301 case fragment_shader: 302 if (!this->avail_in_FS) { 303 return false; 304 } 305 break; 306 default: 307 assert (!"Unrecognized shader target"); 308 return false; 309 } 310 311 /* Check that this extension matches whether we are compiling 312 * for desktop GL or GLES. 313 */ 314 if (state->es_shader) { 315 if (!this->avail_in_ES) return false; 316 } else { 317 if (!this->avail_in_GL) return false; 318 } 319 320 /* Check that this extension is supported by the OpenGL 321 * implementation. 322 * 323 * Note: the ->* operator indexes into state->extensions by the 324 * offset this->supported_flag. See 325 * _mesa_glsl_extension::supported_flag for more info. 326 */ 327 return state->extensions->*(this->supported_flag); 328} 329 330/** 331 * Set the appropriate flags in the parser state to establish the 332 * given behavior for this extension. 333 */ 334void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, 335 ext_behavior behavior) const 336{ 337 /* Note: the ->* operator indexes into state by the 338 * offsets this->enable_flag and this->warn_flag. See 339 * _mesa_glsl_extension::supported_flag for more info. 340 */ 341 state->*(this->enable_flag) = (behavior != extension_disable); 342 state->*(this->warn_flag) = (behavior == extension_warn); 343} 344 345/** 346 * Find an extension by name in _mesa_glsl_supported_extensions. If 347 * the name is not found, return NULL. 348 */ 349static const _mesa_glsl_extension *find_extension(const char *name) 350{ 351 for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) { 352 if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { 353 return &_mesa_glsl_supported_extensions[i]; 354 } 355 } 356 return NULL; 357} 358 359 360bool 361_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, 362 const char *behavior_string, YYLTYPE *behavior_locp, 363 _mesa_glsl_parse_state *state) 364{ 365 ext_behavior behavior; 366 if (strcmp(behavior_string, "warn") == 0) { 367 behavior = extension_warn; 368 } else if (strcmp(behavior_string, "require") == 0) { 369 behavior = extension_require; 370 } else if (strcmp(behavior_string, "enable") == 0) { 371 behavior = extension_enable; 372 } else if (strcmp(behavior_string, "disable") == 0) { 373 behavior = extension_disable; 374 } else { 375 _mesa_glsl_error(behavior_locp, state, 376 "Unknown extension behavior `%s'", 377 behavior_string); 378 return false; 379 } 380 381 if (strcmp(name, "all") == 0) { 382 if ((behavior == extension_enable) || (behavior == extension_require)) { 383 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", 384 (behavior == extension_enable) 385 ? "enable" : "require"); 386 return false; 387 } else { 388 for (unsigned i = 0; 389 i < Elements(_mesa_glsl_supported_extensions); ++i) { 390 const _mesa_glsl_extension *extension 391 = &_mesa_glsl_supported_extensions[i]; 392 if (extension->compatible_with_state(state)) { 393 _mesa_glsl_supported_extensions[i].set_flags(state, behavior); 394 } 395 } 396 } 397 } else { 398 const _mesa_glsl_extension *extension = find_extension(name); 399 if (extension && extension->compatible_with_state(state)) { 400 extension->set_flags(state, behavior); 401 } else { 402 static const char *const fmt = "extension `%s' unsupported in %s shader"; 403 404 if (behavior == extension_require) { 405 _mesa_glsl_error(name_locp, state, fmt, 406 name, _mesa_glsl_shader_target_name(state->target)); 407 return false; 408 } else { 409 _mesa_glsl_warning(name_locp, state, fmt, 410 name, _mesa_glsl_shader_target_name(state->target)); 411 } 412 } 413 } 414 415 return true; 416} 417 418void 419_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) 420{ 421 if (q->flags.q.constant) 422 printf("const "); 423 424 if (q->flags.q.invariant) 425 printf("invariant "); 426 427 if (q->flags.q.attribute) 428 printf("attribute "); 429 430 if (q->flags.q.varying) 431 printf("varying "); 432 433 if (q->flags.q.in && q->flags.q.out) 434 printf("inout "); 435 else { 436 if (q->flags.q.in) 437 printf("in "); 438 439 if (q->flags.q.out) 440 printf("out "); 441 } 442 443 if (q->flags.q.centroid) 444 printf("centroid "); 445 if (q->flags.q.uniform) 446 printf("uniform "); 447 if (q->flags.q.smooth) 448 printf("smooth "); 449 if (q->flags.q.flat) 450 printf("flat "); 451 if (q->flags.q.noperspective) 452 printf("noperspective "); 453} 454 455 456void 457ast_node::print(void) const 458{ 459 printf("unhandled node "); 460} 461 462 463ast_node::ast_node(void) 464{ 465 this->location.source = 0; 466 this->location.line = 0; 467 this->location.column = 0; 468} 469 470 471static void 472ast_opt_array_size_print(bool is_array, const ast_expression *array_size) 473{ 474 if (is_array) { 475 printf("[ "); 476 477 if (array_size) 478 array_size->print(); 479 480 printf("] "); 481 } 482} 483 484 485void 486ast_compound_statement::print(void) const 487{ 488 printf("{\n"); 489 490 foreach_list_const(n, &this->statements) { 491 ast_node *ast = exec_node_data(ast_node, n, link); 492 ast->print(); 493 } 494 495 printf("}\n"); 496} 497 498 499ast_compound_statement::ast_compound_statement(int new_scope, 500 ast_node *statements) 501{ 502 this->new_scope = new_scope; 503 504 if (statements != NULL) { 505 this->statements.push_degenerate_list_at_head(&statements->link); 506 } 507} 508 509 510void 511ast_expression::print(void) const 512{ 513 switch (oper) { 514 case ast_assign: 515 case ast_mul_assign: 516 case ast_div_assign: 517 case ast_mod_assign: 518 case ast_add_assign: 519 case ast_sub_assign: 520 case ast_ls_assign: 521 case ast_rs_assign: 522 case ast_and_assign: 523 case ast_xor_assign: 524 case ast_or_assign: 525 subexpressions[0]->print(); 526 printf("%s ", operator_string(oper)); 527 subexpressions[1]->print(); 528 break; 529 530 case ast_field_selection: 531 subexpressions[0]->print(); 532 printf(". %s ", primary_expression.identifier); 533 break; 534 535 case ast_plus: 536 case ast_neg: 537 case ast_bit_not: 538 case ast_logic_not: 539 case ast_pre_inc: 540 case ast_pre_dec: 541 printf("%s ", operator_string(oper)); 542 subexpressions[0]->print(); 543 break; 544 545 case ast_post_inc: 546 case ast_post_dec: 547 subexpressions[0]->print(); 548 printf("%s ", operator_string(oper)); 549 break; 550 551 case ast_conditional: 552 subexpressions[0]->print(); 553 printf("? "); 554 subexpressions[1]->print(); 555 printf(": "); 556 subexpressions[2]->print(); 557 break; 558 559 case ast_array_index: 560 subexpressions[0]->print(); 561 printf("[ "); 562 subexpressions[1]->print(); 563 printf("] "); 564 break; 565 566 case ast_function_call: { 567 subexpressions[0]->print(); 568 printf("( "); 569 570 foreach_list_const (n, &this->expressions) { 571 if (n != this->expressions.get_head()) 572 printf(", "); 573 574 ast_node *ast = exec_node_data(ast_node, n, link); 575 ast->print(); 576 } 577 578 printf(") "); 579 break; 580 } 581 582 case ast_identifier: 583 printf("%s ", primary_expression.identifier); 584 break; 585 586 case ast_int_constant: 587 printf("%d ", primary_expression.int_constant); 588 break; 589 590 case ast_uint_constant: 591 printf("%u ", primary_expression.uint_constant); 592 break; 593 594 case ast_float_constant: 595 printf("%f ", primary_expression.float_constant); 596 break; 597 598 case ast_bool_constant: 599 printf("%s ", 600 primary_expression.bool_constant 601 ? "true" : "false"); 602 break; 603 604 case ast_sequence: { 605 printf("( "); 606 foreach_list_const(n, & this->expressions) { 607 if (n != this->expressions.get_head()) 608 printf(", "); 609 610 ast_node *ast = exec_node_data(ast_node, n, link); 611 ast->print(); 612 } 613 printf(") "); 614 break; 615 } 616 617 default: 618 assert(0); 619 break; 620 } 621} 622 623ast_expression::ast_expression(int oper, 624 ast_expression *ex0, 625 ast_expression *ex1, 626 ast_expression *ex2) 627{ 628 this->oper = ast_operators(oper); 629 this->subexpressions[0] = ex0; 630 this->subexpressions[1] = ex1; 631 this->subexpressions[2] = ex2; 632 this->non_lvalue_description = NULL; 633} 634 635 636void 637ast_expression_statement::print(void) const 638{ 639 if (expression) 640 expression->print(); 641 642 printf("; "); 643} 644 645 646ast_expression_statement::ast_expression_statement(ast_expression *ex) : 647 expression(ex) 648{ 649 /* empty */ 650} 651 652 653void 654ast_function::print(void) const 655{ 656 return_type->print(); 657 printf(" %s (", identifier); 658 659 foreach_list_const(n, & this->parameters) { 660 ast_node *ast = exec_node_data(ast_node, n, link); 661 ast->print(); 662 } 663 664 printf(")"); 665} 666 667 668ast_function::ast_function(void) 669 : is_definition(false), signature(NULL) 670{ 671 /* empty */ 672} 673 674 675void 676ast_fully_specified_type::print(void) const 677{ 678 _mesa_ast_type_qualifier_print(& qualifier); 679 specifier->print(); 680} 681 682 683void 684ast_parameter_declarator::print(void) const 685{ 686 type->print(); 687 if (identifier) 688 printf("%s ", identifier); 689 ast_opt_array_size_print(is_array, array_size); 690} 691 692 693void 694ast_function_definition::print(void) const 695{ 696 prototype->print(); 697 body->print(); 698} 699 700 701void 702ast_declaration::print(void) const 703{ 704 printf("%s ", identifier); 705 ast_opt_array_size_print(is_array, array_size); 706 707 if (initializer) { 708 printf("= "); 709 initializer->print(); 710 } 711} 712 713 714ast_declaration::ast_declaration(char *identifier, int is_array, 715 ast_expression *array_size, 716 ast_expression *initializer) 717{ 718 this->identifier = identifier; 719 this->is_array = is_array; 720 this->array_size = array_size; 721 this->initializer = initializer; 722} 723 724 725void 726ast_declarator_list::print(void) const 727{ 728 assert(type || invariant); 729 730 if (type) 731 type->print(); 732 else 733 printf("invariant "); 734 735 foreach_list_const (ptr, & this->declarations) { 736 if (ptr != this->declarations.get_head()) 737 printf(", "); 738 739 ast_node *ast = exec_node_data(ast_node, ptr, link); 740 ast->print(); 741 } 742 743 printf("; "); 744} 745 746 747ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) 748{ 749 this->type = type; 750 this->invariant = false; 751} 752 753void 754ast_jump_statement::print(void) const 755{ 756 switch (mode) { 757 case ast_continue: 758 printf("continue; "); 759 break; 760 case ast_break: 761 printf("break; "); 762 break; 763 case ast_return: 764 printf("return "); 765 if (opt_return_value) 766 opt_return_value->print(); 767 768 printf("; "); 769 break; 770 case ast_discard: 771 printf("discard; "); 772 break; 773 } 774} 775 776 777ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) 778{ 779 this->mode = ast_jump_modes(mode); 780 781 if (mode == ast_return) 782 opt_return_value = return_value; 783} 784 785 786void 787ast_selection_statement::print(void) const 788{ 789 printf("if ( "); 790 condition->print(); 791 printf(") "); 792 793 then_statement->print(); 794 795 if (else_statement) { 796 printf("else "); 797 else_statement->print(); 798 } 799 800} 801 802 803ast_selection_statement::ast_selection_statement(ast_expression *condition, 804 ast_node *then_statement, 805 ast_node *else_statement) 806{ 807 this->condition = condition; 808 this->then_statement = then_statement; 809 this->else_statement = else_statement; 810} 811 812 813void 814ast_switch_statement::print(void) const 815{ 816 printf("switch ( "); 817 test_expression->print(); 818 printf(") "); 819 820 body->print(); 821} 822 823 824ast_switch_statement::ast_switch_statement(ast_expression *test_expression, 825 ast_node *body) 826{ 827 this->test_expression = test_expression; 828 this->body = body; 829} 830 831 832void 833ast_switch_body::print(void) const 834{ 835 printf("{\n"); 836 if (stmts != NULL) { 837 stmts->print(); 838 } 839 printf("}\n"); 840} 841 842 843ast_switch_body::ast_switch_body(ast_case_statement_list *stmts) 844{ 845 this->stmts = stmts; 846} 847 848 849void ast_case_label::print(void) const 850{ 851 if (test_value != NULL) { 852 printf("case "); 853 test_value->print(); 854 printf(": "); 855 } else { 856 printf("default: "); 857 } 858} 859 860 861ast_case_label::ast_case_label(ast_expression *test_value) 862{ 863 this->test_value = test_value; 864} 865 866 867void ast_case_label_list::print(void) const 868{ 869 foreach_list_const(n, & this->labels) { 870 ast_node *ast = exec_node_data(ast_node, n, link); 871 ast->print(); 872 } 873 printf("\n"); 874} 875 876 877ast_case_label_list::ast_case_label_list(void) 878{ 879} 880 881 882void ast_case_statement::print(void) const 883{ 884 labels->print(); 885 foreach_list_const(n, & this->stmts) { 886 ast_node *ast = exec_node_data(ast_node, n, link); 887 ast->print(); 888 printf("\n"); 889 } 890} 891 892 893ast_case_statement::ast_case_statement(ast_case_label_list *labels) 894{ 895 this->labels = labels; 896} 897 898 899void ast_case_statement_list::print(void) const 900{ 901 foreach_list_const(n, & this->cases) { 902 ast_node *ast = exec_node_data(ast_node, n, link); 903 ast->print(); 904 } 905} 906 907 908ast_case_statement_list::ast_case_statement_list(void) 909{ 910} 911 912 913void 914ast_iteration_statement::print(void) const 915{ 916 switch (mode) { 917 case ast_for: 918 printf("for( "); 919 if (init_statement) 920 init_statement->print(); 921 printf("; "); 922 923 if (condition) 924 condition->print(); 925 printf("; "); 926 927 if (rest_expression) 928 rest_expression->print(); 929 printf(") "); 930 931 body->print(); 932 break; 933 934 case ast_while: 935 printf("while ( "); 936 if (condition) 937 condition->print(); 938 printf(") "); 939 body->print(); 940 break; 941 942 case ast_do_while: 943 printf("do "); 944 body->print(); 945 printf("while ( "); 946 if (condition) 947 condition->print(); 948 printf("); "); 949 break; 950 } 951} 952 953 954ast_iteration_statement::ast_iteration_statement(int mode, 955 ast_node *init, 956 ast_node *condition, 957 ast_expression *rest_expression, 958 ast_node *body) 959{ 960 this->mode = ast_iteration_modes(mode); 961 this->init_statement = init; 962 this->condition = condition; 963 this->rest_expression = rest_expression; 964 this->body = body; 965} 966 967 968void 969ast_struct_specifier::print(void) const 970{ 971 printf("struct %s { ", name); 972 foreach_list_const(n, &this->declarations) { 973 ast_node *ast = exec_node_data(ast_node, n, link); 974 ast->print(); 975 } 976 printf("} "); 977} 978 979 980ast_struct_specifier::ast_struct_specifier(char *identifier, 981 ast_node *declarator_list) 982{ 983 if (identifier == NULL) { 984 static unsigned anon_count = 1; 985 identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count); 986 anon_count++; 987 } 988 name = identifier; 989 this->declarations.push_degenerate_list_at_head(&declarator_list->link); 990} 991 992/** 993 * Do the set of common optimizations passes 994 * 995 * \param ir List of instructions to be optimized 996 * \param linked Is the shader linked? This enables 997 * optimizations passes that remove code at 998 * global scope and could cause linking to 999 * fail. 1000 * \param uniform_locations_assigned Have locations already been assigned for 1001 * uniforms? This prevents the declarations 1002 * of unused uniforms from being removed. 1003 * The setting of this flag only matters if 1004 * \c linked is \c true. 1005 * \param max_unroll_iterations Maximum number of loop iterations to be 1006 * unrolled. Setting to 0 forces all loops 1007 * to be unrolled. 1008 */ 1009bool 1010do_common_optimization(exec_list *ir, bool linked, 1011 bool uniform_locations_assigned, 1012 unsigned max_unroll_iterations) 1013{ 1014 GLboolean progress = GL_FALSE; 1015 1016 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; 1017 1018 if (linked) { 1019 progress = do_function_inlining(ir) || progress; 1020 progress = do_dead_functions(ir) || progress; 1021 progress = do_structure_splitting(ir) || progress; 1022 } 1023 progress = do_if_simplification(ir) || progress; 1024 progress = do_discard_simplification(ir) || progress; 1025 progress = do_copy_propagation(ir) || progress; 1026 progress = do_copy_propagation_elements(ir) || progress; 1027 if (linked) 1028 progress = do_dead_code(ir, uniform_locations_assigned) || progress; 1029 else 1030 progress = do_dead_code_unlinked(ir) || progress; 1031 progress = do_dead_code_local(ir) || progress; 1032 progress = do_tree_grafting(ir) || progress; 1033 progress = do_constant_propagation(ir) || progress; 1034 if (linked) 1035 progress = do_constant_variable(ir) || progress; 1036 else 1037 progress = do_constant_variable_unlinked(ir) || progress; 1038 progress = do_constant_folding(ir) || progress; 1039 progress = do_algebraic(ir) || progress; 1040 progress = do_lower_jumps(ir) || progress; 1041 progress = do_vec_index_to_swizzle(ir) || progress; 1042 progress = do_swizzle_swizzle(ir) || progress; 1043 progress = do_noop_swizzle(ir) || progress; 1044 1045 progress = optimize_redundant_jumps(ir) || progress; 1046 1047 loop_state *ls = analyze_loop_variables(ir); 1048 if (ls->loop_found) { 1049 progress = set_loop_controls(ir, ls) || progress; 1050 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress; 1051 } 1052 delete ls; 1053 1054 return progress; 1055} 1056 1057extern "C" { 1058 1059/** 1060 * To be called at GL teardown time, this frees compiler datastructures. 1061 * 1062 * After calling this, any previously compiled shaders and shader 1063 * programs would be invalid. So this should happen at approximately 1064 * program exit. 1065 */ 1066void 1067_mesa_destroy_shader_compiler(void) 1068{ 1069 _mesa_destroy_shader_compiler_caches(); 1070 1071 _mesa_glsl_release_types(); 1072} 1073 1074/** 1075 * Releases compiler caches to trade off performance for memory. 1076 * 1077 * Intended to be used with glReleaseShaderCompiler(). 1078 */ 1079void 1080_mesa_destroy_shader_compiler_caches(void) 1081{ 1082 _mesa_glsl_release_functions(); 1083} 1084 1085} 1086