glsl_parser_extras.cpp revision 26b566e19cbfa189a6a158718f21859c0b7ed090
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_or_switch_nesting = NULL; 54 55 /* Set default language version and extensions */ 56 this->language_version = 110; 57 this->es_shader = false; 58 this->ARB_texture_rectangle_enable = true; 59 60 /* OpenGL ES 2.0 has different defaults from desktop GL. */ 61 if (ctx->API == API_OPENGLES2) { 62 this->language_version = 100; 63 this->es_shader = true; 64 this->ARB_texture_rectangle_enable = false; 65 } 66 67 this->extensions = &ctx->Extensions; 68 69 this->Const.MaxLights = ctx->Const.MaxLights; 70 this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; 71 this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; 72 this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; 73 this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; 74 this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; 75 this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4; 76 this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits; 77 this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; 78 this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; 79 this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; 80 81 this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; 82 83 /* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2 84 * Core context is supported, this logic will need change. Older versions of 85 * GLSL are no longer supported outside the compatibility contexts of 3.x. 86 */ 87 this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2) 88 || ctx->Extensions.ARB_ES2_compatibility; 89 this->Const.GLSL_110 = (ctx->API == API_OPENGL); 90 this->Const.GLSL_120 = (ctx->API == API_OPENGL) 91 && (ctx->Const.GLSLVersion >= 120); 92 this->Const.GLSL_130 = (ctx->API == API_OPENGL) 93 && (ctx->Const.GLSLVersion >= 130); 94 95 const unsigned lowest_version = 96 (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility 97 ? 100 : 110; 98 const unsigned highest_version = 99 (ctx->API == API_OPENGL) ? ctx->Const.GLSLVersion : 100; 100 char *supported = ralloc_strdup(this, ""); 101 102 for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) { 103 const char *const prefix = (ver == lowest_version) 104 ? "" 105 : ((ver == highest_version) ? ", and " : ", "); 106 107 ralloc_asprintf_append(& supported, "%s%d.%02d%s", 108 prefix, 109 ver / 100, ver % 100, 110 (ver == 100) ? " ES" : ""); 111 } 112 113 this->supported_version_string = supported; 114} 115 116const char * 117_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) 118{ 119 switch (target) { 120 case vertex_shader: return "vertex"; 121 case fragment_shader: return "fragment"; 122 case geometry_shader: return "geometry"; 123 } 124 125 assert(!"Should not get here."); 126 return "unknown"; 127} 128 129 130void 131_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, 132 const char *fmt, ...) 133{ 134 va_list ap; 135 136 state->error = true; 137 138 assert(state->info_log != NULL); 139 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ", 140 locp->source, 141 locp->first_line, 142 locp->first_column); 143 va_start(ap, fmt); 144 ralloc_vasprintf_append(&state->info_log, fmt, ap); 145 va_end(ap); 146 ralloc_strcat(&state->info_log, "\n"); 147} 148 149 150void 151_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, 152 const char *fmt, ...) 153{ 154 va_list ap; 155 156 assert(state->info_log != NULL); 157 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ", 158 locp->source, 159 locp->first_line, 160 locp->first_column); 161 va_start(ap, fmt); 162 ralloc_vasprintf_append(&state->info_log, fmt, ap); 163 va_end(ap); 164 ralloc_strcat(&state->info_log, "\n"); 165} 166 167 168bool 169_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, 170 const char *behavior, YYLTYPE *behavior_locp, 171 _mesa_glsl_parse_state *state) 172{ 173 enum { 174 extension_disable, 175 extension_enable, 176 extension_require, 177 extension_warn 178 } ext_mode; 179 180 if (strcmp(behavior, "warn") == 0) { 181 ext_mode = extension_warn; 182 } else if (strcmp(behavior, "require") == 0) { 183 ext_mode = extension_require; 184 } else if (strcmp(behavior, "enable") == 0) { 185 ext_mode = extension_enable; 186 } else if (strcmp(behavior, "disable") == 0) { 187 ext_mode = extension_disable; 188 } else { 189 _mesa_glsl_error(behavior_locp, state, 190 "Unknown extension behavior `%s'", 191 behavior); 192 return false; 193 } 194 195 bool unsupported = false; 196 197 if (strcmp(name, "all") == 0) { 198 if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { 199 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", 200 (ext_mode == extension_enable) 201 ? "enable" : "require"); 202 return false; 203 } 204 } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { 205 /* This extension is only supported in fragment shaders. 206 */ 207 if (state->target != fragment_shader) { 208 unsupported = true; 209 } else { 210 state->ARB_draw_buffers_enable = (ext_mode != extension_disable); 211 state->ARB_draw_buffers_warn = (ext_mode == extension_warn); 212 } 213 } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) { 214 state->ARB_draw_instanced_enable = (ext_mode != extension_disable); 215 state->ARB_draw_instanced_warn = (ext_mode == extension_warn); 216 217 /* This extension is only supported in vertex shaders. 218 */ 219 unsupported = (state->target != vertex_shader) 220 || !state->extensions->ARB_draw_instanced; 221 } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { 222 state->ARB_explicit_attrib_location_enable = 223 (ext_mode != extension_disable); 224 state->ARB_explicit_attrib_location_warn = 225 (ext_mode == extension_warn); 226 227 unsupported = !state->extensions->ARB_explicit_attrib_location; 228 } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { 229 state->ARB_fragment_coord_conventions_enable = 230 (ext_mode != extension_disable); 231 state->ARB_fragment_coord_conventions_warn = 232 (ext_mode == extension_warn); 233 234 unsupported = !state->extensions->ARB_fragment_coord_conventions; 235 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { 236 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); 237 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); 238 } else if (strcmp(name, "GL_EXT_texture_array") == 0) { 239 state->EXT_texture_array_enable = (ext_mode != extension_disable); 240 state->EXT_texture_array_warn = (ext_mode == extension_warn); 241 242 unsupported = !state->extensions->EXT_texture_array; 243 } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) { 244 /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */ 245 state->ARB_texture_rectangle_enable = true; 246 247 state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable); 248 state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn); 249 250 unsupported = !state->extensions->ARB_shader_texture_lod; 251 } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { 252 state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); 253 state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); 254 255 /* This extension is only supported in fragment shaders. 256 */ 257 unsupported = (state->target != fragment_shader) 258 || !state->extensions->ARB_shader_stencil_export; 259 } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) { 260 /* The AMD_conservative spec does not forbid requiring the extension in 261 * the vertex shader. 262 */ 263 state->AMD_conservative_depth_enable = (ext_mode != extension_disable); 264 state->AMD_conservative_depth_warn = (ext_mode == extension_warn); 265 unsupported = !state->extensions->AMD_conservative_depth; 266 } else if (strcmp(name, "GL_AMD_shader_stencil_export") == 0) { 267 state->AMD_shader_stencil_export_enable = (ext_mode != extension_disable); 268 state->AMD_shader_stencil_export_warn = (ext_mode == extension_warn); 269 270 /* This extension is only supported in fragment shaders. 271 * Both the ARB and AMD variants share the same ARB flag 272 * in gl_extensions. 273 */ 274 unsupported = (state->target != fragment_shader) 275 || !state->extensions->ARB_shader_stencil_export; 276 } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) { 277 state->OES_texture_3D_enable = (ext_mode != extension_disable); 278 state->OES_texture_3D_warn = (ext_mode == extension_warn); 279 280 unsupported = !state->extensions->EXT_texture3D; 281 } else { 282 unsupported = true; 283 } 284 285 if (unsupported) { 286 static const char *const fmt = "extension `%s' unsupported in %s shader"; 287 288 if (ext_mode == extension_require) { 289 _mesa_glsl_error(name_locp, state, fmt, 290 name, _mesa_glsl_shader_target_name(state->target)); 291 return false; 292 } else { 293 _mesa_glsl_warning(name_locp, state, fmt, 294 name, _mesa_glsl_shader_target_name(state->target)); 295 } 296 } 297 298 return true; 299} 300 301void 302_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) 303{ 304 if (q->flags.q.constant) 305 printf("const "); 306 307 if (q->flags.q.invariant) 308 printf("invariant "); 309 310 if (q->flags.q.attribute) 311 printf("attribute "); 312 313 if (q->flags.q.varying) 314 printf("varying "); 315 316 if (q->flags.q.in && q->flags.q.out) 317 printf("inout "); 318 else { 319 if (q->flags.q.in) 320 printf("in "); 321 322 if (q->flags.q.out) 323 printf("out "); 324 } 325 326 if (q->flags.q.centroid) 327 printf("centroid "); 328 if (q->flags.q.uniform) 329 printf("uniform "); 330 if (q->flags.q.smooth) 331 printf("smooth "); 332 if (q->flags.q.flat) 333 printf("flat "); 334 if (q->flags.q.noperspective) 335 printf("noperspective "); 336} 337 338 339void 340ast_node::print(void) const 341{ 342 printf("unhandled node "); 343} 344 345 346ast_node::ast_node(void) 347{ 348 this->location.source = 0; 349 this->location.line = 0; 350 this->location.column = 0; 351} 352 353 354static void 355ast_opt_array_size_print(bool is_array, const ast_expression *array_size) 356{ 357 if (is_array) { 358 printf("[ "); 359 360 if (array_size) 361 array_size->print(); 362 363 printf("] "); 364 } 365} 366 367 368void 369ast_compound_statement::print(void) const 370{ 371 printf("{\n"); 372 373 foreach_list_const(n, &this->statements) { 374 ast_node *ast = exec_node_data(ast_node, n, link); 375 ast->print(); 376 } 377 378 printf("}\n"); 379} 380 381 382ast_compound_statement::ast_compound_statement(int new_scope, 383 ast_node *statements) 384{ 385 this->new_scope = new_scope; 386 387 if (statements != NULL) { 388 this->statements.push_degenerate_list_at_head(&statements->link); 389 } 390} 391 392 393void 394ast_expression::print(void) const 395{ 396 switch (oper) { 397 case ast_assign: 398 case ast_mul_assign: 399 case ast_div_assign: 400 case ast_mod_assign: 401 case ast_add_assign: 402 case ast_sub_assign: 403 case ast_ls_assign: 404 case ast_rs_assign: 405 case ast_and_assign: 406 case ast_xor_assign: 407 case ast_or_assign: 408 subexpressions[0]->print(); 409 printf("%s ", operator_string(oper)); 410 subexpressions[1]->print(); 411 break; 412 413 case ast_field_selection: 414 subexpressions[0]->print(); 415 printf(". %s ", primary_expression.identifier); 416 break; 417 418 case ast_plus: 419 case ast_neg: 420 case ast_bit_not: 421 case ast_logic_not: 422 case ast_pre_inc: 423 case ast_pre_dec: 424 printf("%s ", operator_string(oper)); 425 subexpressions[0]->print(); 426 break; 427 428 case ast_post_inc: 429 case ast_post_dec: 430 subexpressions[0]->print(); 431 printf("%s ", operator_string(oper)); 432 break; 433 434 case ast_conditional: 435 subexpressions[0]->print(); 436 printf("? "); 437 subexpressions[1]->print(); 438 printf(": "); 439 subexpressions[2]->print(); 440 break; 441 442 case ast_array_index: 443 subexpressions[0]->print(); 444 printf("[ "); 445 subexpressions[1]->print(); 446 printf("] "); 447 break; 448 449 case ast_function_call: { 450 subexpressions[0]->print(); 451 printf("( "); 452 453 foreach_list_const (n, &this->expressions) { 454 if (n != this->expressions.get_head()) 455 printf(", "); 456 457 ast_node *ast = exec_node_data(ast_node, n, link); 458 ast->print(); 459 } 460 461 printf(") "); 462 break; 463 } 464 465 case ast_identifier: 466 printf("%s ", primary_expression.identifier); 467 break; 468 469 case ast_int_constant: 470 printf("%d ", primary_expression.int_constant); 471 break; 472 473 case ast_uint_constant: 474 printf("%u ", primary_expression.uint_constant); 475 break; 476 477 case ast_float_constant: 478 printf("%f ", primary_expression.float_constant); 479 break; 480 481 case ast_bool_constant: 482 printf("%s ", 483 primary_expression.bool_constant 484 ? "true" : "false"); 485 break; 486 487 case ast_sequence: { 488 printf("( "); 489 foreach_list_const(n, & this->expressions) { 490 if (n != this->expressions.get_head()) 491 printf(", "); 492 493 ast_node *ast = exec_node_data(ast_node, n, link); 494 ast->print(); 495 } 496 printf(") "); 497 break; 498 } 499 500 default: 501 assert(0); 502 break; 503 } 504} 505 506ast_expression::ast_expression(int oper, 507 ast_expression *ex0, 508 ast_expression *ex1, 509 ast_expression *ex2) 510{ 511 this->oper = ast_operators(oper); 512 this->subexpressions[0] = ex0; 513 this->subexpressions[1] = ex1; 514 this->subexpressions[2] = ex2; 515} 516 517 518void 519ast_expression_statement::print(void) const 520{ 521 if (expression) 522 expression->print(); 523 524 printf("; "); 525} 526 527 528ast_expression_statement::ast_expression_statement(ast_expression *ex) : 529 expression(ex) 530{ 531 /* empty */ 532} 533 534 535void 536ast_function::print(void) const 537{ 538 return_type->print(); 539 printf(" %s (", identifier); 540 541 foreach_list_const(n, & this->parameters) { 542 ast_node *ast = exec_node_data(ast_node, n, link); 543 ast->print(); 544 } 545 546 printf(")"); 547} 548 549 550ast_function::ast_function(void) 551 : is_definition(false), signature(NULL) 552{ 553 /* empty */ 554} 555 556 557void 558ast_fully_specified_type::print(void) const 559{ 560 _mesa_ast_type_qualifier_print(& qualifier); 561 specifier->print(); 562} 563 564 565void 566ast_parameter_declarator::print(void) const 567{ 568 type->print(); 569 if (identifier) 570 printf("%s ", identifier); 571 ast_opt_array_size_print(is_array, array_size); 572} 573 574 575void 576ast_function_definition::print(void) const 577{ 578 prototype->print(); 579 body->print(); 580} 581 582 583void 584ast_declaration::print(void) const 585{ 586 printf("%s ", identifier); 587 ast_opt_array_size_print(is_array, array_size); 588 589 if (initializer) { 590 printf("= "); 591 initializer->print(); 592 } 593} 594 595 596ast_declaration::ast_declaration(char *identifier, int is_array, 597 ast_expression *array_size, 598 ast_expression *initializer) 599{ 600 this->identifier = identifier; 601 this->is_array = is_array; 602 this->array_size = array_size; 603 this->initializer = initializer; 604} 605 606 607void 608ast_declarator_list::print(void) const 609{ 610 assert(type || invariant); 611 612 if (type) 613 type->print(); 614 else 615 printf("invariant "); 616 617 foreach_list_const (ptr, & this->declarations) { 618 if (ptr != this->declarations.get_head()) 619 printf(", "); 620 621 ast_node *ast = exec_node_data(ast_node, ptr, link); 622 ast->print(); 623 } 624 625 printf("; "); 626} 627 628 629ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) 630{ 631 this->type = type; 632 this->invariant = false; 633} 634 635void 636ast_jump_statement::print(void) const 637{ 638 switch (mode) { 639 case ast_continue: 640 printf("continue; "); 641 break; 642 case ast_break: 643 printf("break; "); 644 break; 645 case ast_return: 646 printf("return "); 647 if (opt_return_value) 648 opt_return_value->print(); 649 650 printf("; "); 651 break; 652 case ast_discard: 653 printf("discard; "); 654 break; 655 } 656} 657 658 659ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) 660{ 661 this->mode = ast_jump_modes(mode); 662 663 if (mode == ast_return) 664 opt_return_value = return_value; 665} 666 667 668void 669ast_selection_statement::print(void) const 670{ 671 printf("if ( "); 672 condition->print(); 673 printf(") "); 674 675 then_statement->print(); 676 677 if (else_statement) { 678 printf("else "); 679 else_statement->print(); 680 } 681 682} 683 684 685ast_selection_statement::ast_selection_statement(ast_expression *condition, 686 ast_node *then_statement, 687 ast_node *else_statement) 688{ 689 this->condition = condition; 690 this->then_statement = then_statement; 691 this->else_statement = else_statement; 692} 693 694 695void 696ast_iteration_statement::print(void) const 697{ 698 switch (mode) { 699 case ast_for: 700 printf("for( "); 701 if (init_statement) 702 init_statement->print(); 703 printf("; "); 704 705 if (condition) 706 condition->print(); 707 printf("; "); 708 709 if (rest_expression) 710 rest_expression->print(); 711 printf(") "); 712 713 body->print(); 714 break; 715 716 case ast_while: 717 printf("while ( "); 718 if (condition) 719 condition->print(); 720 printf(") "); 721 body->print(); 722 break; 723 724 case ast_do_while: 725 printf("do "); 726 body->print(); 727 printf("while ( "); 728 if (condition) 729 condition->print(); 730 printf("); "); 731 break; 732 } 733} 734 735 736ast_iteration_statement::ast_iteration_statement(int mode, 737 ast_node *init, 738 ast_node *condition, 739 ast_expression *rest_expression, 740 ast_node *body) 741{ 742 this->mode = ast_iteration_modes(mode); 743 this->init_statement = init; 744 this->condition = condition; 745 this->rest_expression = rest_expression; 746 this->body = body; 747} 748 749 750void 751ast_struct_specifier::print(void) const 752{ 753 printf("struct %s { ", name); 754 foreach_list_const(n, &this->declarations) { 755 ast_node *ast = exec_node_data(ast_node, n, link); 756 ast->print(); 757 } 758 printf("} "); 759} 760 761 762ast_struct_specifier::ast_struct_specifier(char *identifier, 763 ast_node *declarator_list) 764{ 765 if (identifier == NULL) { 766 static unsigned anon_count = 1; 767 identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count); 768 anon_count++; 769 } 770 name = identifier; 771 this->declarations.push_degenerate_list_at_head(&declarator_list->link); 772} 773 774bool 775do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations) 776{ 777 GLboolean progress = GL_FALSE; 778 779 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; 780 781 if (linked) { 782 progress = do_function_inlining(ir) || progress; 783 progress = do_dead_functions(ir) || progress; 784 } 785 progress = do_structure_splitting(ir) || progress; 786 progress = do_if_simplification(ir) || progress; 787 progress = do_discard_simplification(ir) || progress; 788 progress = do_copy_propagation(ir) || progress; 789 progress = do_copy_propagation_elements(ir) || progress; 790 if (linked) 791 progress = do_dead_code(ir) || progress; 792 else 793 progress = do_dead_code_unlinked(ir) || progress; 794 progress = do_dead_code_local(ir) || progress; 795 progress = do_tree_grafting(ir) || progress; 796 progress = do_constant_propagation(ir) || progress; 797 if (linked) 798 progress = do_constant_variable(ir) || progress; 799 else 800 progress = do_constant_variable_unlinked(ir) || progress; 801 progress = do_constant_folding(ir) || progress; 802 progress = do_algebraic(ir) || progress; 803 progress = do_lower_jumps(ir) || progress; 804 progress = do_vec_index_to_swizzle(ir) || progress; 805 progress = do_swizzle_swizzle(ir) || progress; 806 progress = do_noop_swizzle(ir) || progress; 807 808 progress = optimize_redundant_jumps(ir) || progress; 809 810 loop_state *ls = analyze_loop_variables(ir); 811 if (ls->loop_found) { 812 progress = set_loop_controls(ir, ls) || progress; 813 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress; 814 } 815 delete ls; 816 817 return progress; 818} 819 820extern "C" { 821 822/** 823 * To be called at GL teardown time, this frees compiler datastructures. 824 * 825 * After calling this, any previously compiled shaders and shader 826 * programs would be invalid. So this should happen at approximately 827 * program exit. 828 */ 829void 830_mesa_destroy_shader_compiler(void) 831{ 832 _mesa_destroy_shader_compiler_caches(); 833 834 _mesa_glsl_release_types(); 835} 836 837/** 838 * Releases compiler caches to trade off performance for memory. 839 * 840 * Intended to be used with glReleaseShaderCompiler(). 841 */ 842void 843_mesa_destroy_shader_compiler_caches(void) 844{ 845 _mesa_glsl_release_functions(); 846} 847 848} 849