glsl_parser_extras.cpp revision 3097715d41da4b725b7ce9f9d5bbc0f684cbf0a6
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 168/** 169 * Enum representing the possible behaviors that can be specified in 170 * an #extension directive. 171 */ 172enum ext_behavior { 173 extension_disable, 174 extension_enable, 175 extension_require, 176 extension_warn 177}; 178 179/** 180 * Element type for _mesa_glsl_supported_extensions 181 */ 182struct _mesa_glsl_extension { 183 /** 184 * Name of the extension when referred to in a GLSL extension 185 * statement 186 */ 187 const char *name; 188 189 /** True if this extension is available to vertex shaders */ 190 bool avail_in_VS; 191 192 /** True if this extension is available to geometry shaders */ 193 bool avail_in_GS; 194 195 /** True if this extension is available to fragment shaders */ 196 bool avail_in_FS; 197 198 /** True if this extension is available to desktop GL shaders */ 199 bool avail_in_GL; 200 201 /** True if this extension is available to GLES shaders */ 202 bool avail_in_ES; 203 204 /** 205 * Flag in the gl_extensions struct indicating whether this 206 * extension is supported by the driver, or 207 * &gl_extensions::dummy_true if supported by all drivers. 208 * 209 * Note: the type (GLboolean gl_extensions::*) is a "pointer to 210 * member" type, the type-safe alternative to the "offsetof" macro. 211 * In a nutshell: 212 * 213 * - foo bar::* p declares p to be an "offset" to a field of type 214 * foo that exists within struct bar 215 * - &bar::baz computes the "offset" of field baz within struct bar 216 * - x.*p accesses the field of x that exists at "offset" p 217 * - x->*p is equivalent to (*x).*p 218 */ 219 const GLboolean gl_extensions::* supported_flag; 220 221 /** 222 * Flag in the _mesa_glsl_parse_state struct that should be set 223 * when this extension is enabled. 224 * 225 * See note in _mesa_glsl_extension::supported_flag about "pointer 226 * to member" types. 227 */ 228 bool _mesa_glsl_parse_state::* enable_flag; 229 230 /** 231 * Flag in the _mesa_glsl_parse_state struct that should be set 232 * when the shader requests "warn" behavior for this extension. 233 * 234 * See note in _mesa_glsl_extension::supported_flag about "pointer 235 * to member" types. 236 */ 237 bool _mesa_glsl_parse_state::* warn_flag; 238 239 240 bool compatible_with_state(const _mesa_glsl_parse_state *state) const; 241 void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; 242}; 243 244#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \ 245 { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ 246 &_mesa_glsl_parse_state::NAME##_enable, \ 247 &_mesa_glsl_parse_state::NAME##_warn } 248 249/** 250 * Table of extensions that can be enabled/disabled within a shader, 251 * and the conditions under which they are supported. 252 */ 253static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { 254 /* target availability API availability */ 255 /* name VS GS FS GL ES supported flag */ 256 EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), 257 EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), 258 EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), 259 EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions), 260 EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true), 261 EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), 262 EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), 263 EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), 264 EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth), 265 EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), 266 EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), 267}; 268 269#undef EXT 270 271 272/** 273 * Determine whether a given extension is compatible with the target, 274 * API, and extension information in the current parser state. 275 */ 276bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * 277 state) const 278{ 279 /* Check that this extension matches the type of shader we are 280 * compiling to. 281 */ 282 switch (state->target) { 283 case vertex_shader: 284 if (!this->avail_in_VS) { 285 return false; 286 } 287 break; 288 case geometry_shader: 289 if (!this->avail_in_GS) { 290 return false; 291 } 292 break; 293 case fragment_shader: 294 if (!this->avail_in_FS) { 295 return false; 296 } 297 break; 298 default: 299 assert (!"Unrecognized shader target"); 300 return false; 301 } 302 303 /* Check that this extension matches whether we are compiling 304 * for desktop GL or GLES. 305 */ 306 if (state->es_shader) { 307 if (!this->avail_in_ES) return false; 308 } else { 309 if (!this->avail_in_GL) return false; 310 } 311 312 /* Check that this extension is supported by the OpenGL 313 * implementation. 314 * 315 * Note: the ->* operator indexes into state->extensions by the 316 * offset this->supported_flag. See 317 * _mesa_glsl_extension::supported_flag for more info. 318 */ 319 return state->extensions->*(this->supported_flag); 320} 321 322/** 323 * Set the appropriate flags in the parser state to establish the 324 * given behavior for this extension. 325 */ 326void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, 327 ext_behavior behavior) const 328{ 329 /* Note: the ->* operator indexes into state by the 330 * offsets this->enable_flag and this->warn_flag. See 331 * _mesa_glsl_extension::supported_flag for more info. 332 */ 333 state->*(this->enable_flag) = (behavior != extension_disable); 334 state->*(this->warn_flag) = (behavior == extension_warn); 335} 336 337/** 338 * Find an extension by name in _mesa_glsl_supported_extensions. If 339 * the name is not found, return NULL. 340 */ 341static const _mesa_glsl_extension *find_extension(const char *name) 342{ 343 for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) { 344 if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { 345 return &_mesa_glsl_supported_extensions[i]; 346 } 347 } 348 return NULL; 349} 350 351 352bool 353_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, 354 const char *behavior_string, YYLTYPE *behavior_locp, 355 _mesa_glsl_parse_state *state) 356{ 357 ext_behavior behavior; 358 if (strcmp(behavior_string, "warn") == 0) { 359 behavior = extension_warn; 360 } else if (strcmp(behavior_string, "require") == 0) { 361 behavior = extension_require; 362 } else if (strcmp(behavior_string, "enable") == 0) { 363 behavior = extension_enable; 364 } else if (strcmp(behavior_string, "disable") == 0) { 365 behavior = extension_disable; 366 } else { 367 _mesa_glsl_error(behavior_locp, state, 368 "Unknown extension behavior `%s'", 369 behavior_string); 370 return false; 371 } 372 373 if (strcmp(name, "all") == 0) { 374 if ((behavior == extension_enable) || (behavior == extension_require)) { 375 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", 376 (behavior == extension_enable) 377 ? "enable" : "require"); 378 return false; 379 } else { 380 for (unsigned i = 0; 381 i < Elements(_mesa_glsl_supported_extensions); ++i) { 382 const _mesa_glsl_extension *extension 383 = &_mesa_glsl_supported_extensions[i]; 384 if (extension->compatible_with_state(state)) { 385 _mesa_glsl_supported_extensions[i].set_flags(state, behavior); 386 } 387 } 388 } 389 } else { 390 const _mesa_glsl_extension *extension = find_extension(name); 391 if (extension && extension->compatible_with_state(state)) { 392 extension->set_flags(state, behavior); 393 } else { 394 static const char *const fmt = "extension `%s' unsupported in %s shader"; 395 396 if (behavior == extension_require) { 397 _mesa_glsl_error(name_locp, state, fmt, 398 name, _mesa_glsl_shader_target_name(state->target)); 399 return false; 400 } else { 401 _mesa_glsl_warning(name_locp, state, fmt, 402 name, _mesa_glsl_shader_target_name(state->target)); 403 } 404 } 405 } 406 407 return true; 408} 409 410void 411_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) 412{ 413 if (q->flags.q.constant) 414 printf("const "); 415 416 if (q->flags.q.invariant) 417 printf("invariant "); 418 419 if (q->flags.q.attribute) 420 printf("attribute "); 421 422 if (q->flags.q.varying) 423 printf("varying "); 424 425 if (q->flags.q.in && q->flags.q.out) 426 printf("inout "); 427 else { 428 if (q->flags.q.in) 429 printf("in "); 430 431 if (q->flags.q.out) 432 printf("out "); 433 } 434 435 if (q->flags.q.centroid) 436 printf("centroid "); 437 if (q->flags.q.uniform) 438 printf("uniform "); 439 if (q->flags.q.smooth) 440 printf("smooth "); 441 if (q->flags.q.flat) 442 printf("flat "); 443 if (q->flags.q.noperspective) 444 printf("noperspective "); 445} 446 447 448void 449ast_node::print(void) const 450{ 451 printf("unhandled node "); 452} 453 454 455ast_node::ast_node(void) 456{ 457 this->location.source = 0; 458 this->location.line = 0; 459 this->location.column = 0; 460} 461 462 463static void 464ast_opt_array_size_print(bool is_array, const ast_expression *array_size) 465{ 466 if (is_array) { 467 printf("[ "); 468 469 if (array_size) 470 array_size->print(); 471 472 printf("] "); 473 } 474} 475 476 477void 478ast_compound_statement::print(void) const 479{ 480 printf("{\n"); 481 482 foreach_list_const(n, &this->statements) { 483 ast_node *ast = exec_node_data(ast_node, n, link); 484 ast->print(); 485 } 486 487 printf("}\n"); 488} 489 490 491ast_compound_statement::ast_compound_statement(int new_scope, 492 ast_node *statements) 493{ 494 this->new_scope = new_scope; 495 496 if (statements != NULL) { 497 this->statements.push_degenerate_list_at_head(&statements->link); 498 } 499} 500 501 502void 503ast_expression::print(void) const 504{ 505 switch (oper) { 506 case ast_assign: 507 case ast_mul_assign: 508 case ast_div_assign: 509 case ast_mod_assign: 510 case ast_add_assign: 511 case ast_sub_assign: 512 case ast_ls_assign: 513 case ast_rs_assign: 514 case ast_and_assign: 515 case ast_xor_assign: 516 case ast_or_assign: 517 subexpressions[0]->print(); 518 printf("%s ", operator_string(oper)); 519 subexpressions[1]->print(); 520 break; 521 522 case ast_field_selection: 523 subexpressions[0]->print(); 524 printf(". %s ", primary_expression.identifier); 525 break; 526 527 case ast_plus: 528 case ast_neg: 529 case ast_bit_not: 530 case ast_logic_not: 531 case ast_pre_inc: 532 case ast_pre_dec: 533 printf("%s ", operator_string(oper)); 534 subexpressions[0]->print(); 535 break; 536 537 case ast_post_inc: 538 case ast_post_dec: 539 subexpressions[0]->print(); 540 printf("%s ", operator_string(oper)); 541 break; 542 543 case ast_conditional: 544 subexpressions[0]->print(); 545 printf("? "); 546 subexpressions[1]->print(); 547 printf(": "); 548 subexpressions[2]->print(); 549 break; 550 551 case ast_array_index: 552 subexpressions[0]->print(); 553 printf("[ "); 554 subexpressions[1]->print(); 555 printf("] "); 556 break; 557 558 case ast_function_call: { 559 subexpressions[0]->print(); 560 printf("( "); 561 562 foreach_list_const (n, &this->expressions) { 563 if (n != this->expressions.get_head()) 564 printf(", "); 565 566 ast_node *ast = exec_node_data(ast_node, n, link); 567 ast->print(); 568 } 569 570 printf(") "); 571 break; 572 } 573 574 case ast_identifier: 575 printf("%s ", primary_expression.identifier); 576 break; 577 578 case ast_int_constant: 579 printf("%d ", primary_expression.int_constant); 580 break; 581 582 case ast_uint_constant: 583 printf("%u ", primary_expression.uint_constant); 584 break; 585 586 case ast_float_constant: 587 printf("%f ", primary_expression.float_constant); 588 break; 589 590 case ast_bool_constant: 591 printf("%s ", 592 primary_expression.bool_constant 593 ? "true" : "false"); 594 break; 595 596 case ast_sequence: { 597 printf("( "); 598 foreach_list_const(n, & this->expressions) { 599 if (n != this->expressions.get_head()) 600 printf(", "); 601 602 ast_node *ast = exec_node_data(ast_node, n, link); 603 ast->print(); 604 } 605 printf(") "); 606 break; 607 } 608 609 default: 610 assert(0); 611 break; 612 } 613} 614 615ast_expression::ast_expression(int oper, 616 ast_expression *ex0, 617 ast_expression *ex1, 618 ast_expression *ex2) 619{ 620 this->oper = ast_operators(oper); 621 this->subexpressions[0] = ex0; 622 this->subexpressions[1] = ex1; 623 this->subexpressions[2] = ex2; 624} 625 626 627void 628ast_expression_statement::print(void) const 629{ 630 if (expression) 631 expression->print(); 632 633 printf("; "); 634} 635 636 637ast_expression_statement::ast_expression_statement(ast_expression *ex) : 638 expression(ex) 639{ 640 /* empty */ 641} 642 643 644void 645ast_function::print(void) const 646{ 647 return_type->print(); 648 printf(" %s (", identifier); 649 650 foreach_list_const(n, & this->parameters) { 651 ast_node *ast = exec_node_data(ast_node, n, link); 652 ast->print(); 653 } 654 655 printf(")"); 656} 657 658 659ast_function::ast_function(void) 660 : is_definition(false), signature(NULL) 661{ 662 /* empty */ 663} 664 665 666void 667ast_fully_specified_type::print(void) const 668{ 669 _mesa_ast_type_qualifier_print(& qualifier); 670 specifier->print(); 671} 672 673 674void 675ast_parameter_declarator::print(void) const 676{ 677 type->print(); 678 if (identifier) 679 printf("%s ", identifier); 680 ast_opt_array_size_print(is_array, array_size); 681} 682 683 684void 685ast_function_definition::print(void) const 686{ 687 prototype->print(); 688 body->print(); 689} 690 691 692void 693ast_declaration::print(void) const 694{ 695 printf("%s ", identifier); 696 ast_opt_array_size_print(is_array, array_size); 697 698 if (initializer) { 699 printf("= "); 700 initializer->print(); 701 } 702} 703 704 705ast_declaration::ast_declaration(char *identifier, int is_array, 706 ast_expression *array_size, 707 ast_expression *initializer) 708{ 709 this->identifier = identifier; 710 this->is_array = is_array; 711 this->array_size = array_size; 712 this->initializer = initializer; 713} 714 715 716void 717ast_declarator_list::print(void) const 718{ 719 assert(type || invariant); 720 721 if (type) 722 type->print(); 723 else 724 printf("invariant "); 725 726 foreach_list_const (ptr, & this->declarations) { 727 if (ptr != this->declarations.get_head()) 728 printf(", "); 729 730 ast_node *ast = exec_node_data(ast_node, ptr, link); 731 ast->print(); 732 } 733 734 printf("; "); 735} 736 737 738ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) 739{ 740 this->type = type; 741 this->invariant = false; 742} 743 744void 745ast_jump_statement::print(void) const 746{ 747 switch (mode) { 748 case ast_continue: 749 printf("continue; "); 750 break; 751 case ast_break: 752 printf("break; "); 753 break; 754 case ast_return: 755 printf("return "); 756 if (opt_return_value) 757 opt_return_value->print(); 758 759 printf("; "); 760 break; 761 case ast_discard: 762 printf("discard; "); 763 break; 764 } 765} 766 767 768ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) 769{ 770 this->mode = ast_jump_modes(mode); 771 772 if (mode == ast_return) 773 opt_return_value = return_value; 774} 775 776 777void 778ast_selection_statement::print(void) const 779{ 780 printf("if ( "); 781 condition->print(); 782 printf(") "); 783 784 then_statement->print(); 785 786 if (else_statement) { 787 printf("else "); 788 else_statement->print(); 789 } 790 791} 792 793 794ast_selection_statement::ast_selection_statement(ast_expression *condition, 795 ast_node *then_statement, 796 ast_node *else_statement) 797{ 798 this->condition = condition; 799 this->then_statement = then_statement; 800 this->else_statement = else_statement; 801} 802 803 804void 805ast_iteration_statement::print(void) const 806{ 807 switch (mode) { 808 case ast_for: 809 printf("for( "); 810 if (init_statement) 811 init_statement->print(); 812 printf("; "); 813 814 if (condition) 815 condition->print(); 816 printf("; "); 817 818 if (rest_expression) 819 rest_expression->print(); 820 printf(") "); 821 822 body->print(); 823 break; 824 825 case ast_while: 826 printf("while ( "); 827 if (condition) 828 condition->print(); 829 printf(") "); 830 body->print(); 831 break; 832 833 case ast_do_while: 834 printf("do "); 835 body->print(); 836 printf("while ( "); 837 if (condition) 838 condition->print(); 839 printf("); "); 840 break; 841 } 842} 843 844 845ast_iteration_statement::ast_iteration_statement(int mode, 846 ast_node *init, 847 ast_node *condition, 848 ast_expression *rest_expression, 849 ast_node *body) 850{ 851 this->mode = ast_iteration_modes(mode); 852 this->init_statement = init; 853 this->condition = condition; 854 this->rest_expression = rest_expression; 855 this->body = body; 856} 857 858 859void 860ast_struct_specifier::print(void) const 861{ 862 printf("struct %s { ", name); 863 foreach_list_const(n, &this->declarations) { 864 ast_node *ast = exec_node_data(ast_node, n, link); 865 ast->print(); 866 } 867 printf("} "); 868} 869 870 871ast_struct_specifier::ast_struct_specifier(char *identifier, 872 ast_node *declarator_list) 873{ 874 if (identifier == NULL) { 875 static unsigned anon_count = 1; 876 identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count); 877 anon_count++; 878 } 879 name = identifier; 880 this->declarations.push_degenerate_list_at_head(&declarator_list->link); 881} 882 883bool 884do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations) 885{ 886 GLboolean progress = GL_FALSE; 887 888 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; 889 890 if (linked) { 891 progress = do_function_inlining(ir) || progress; 892 progress = do_dead_functions(ir) || progress; 893 } 894 progress = do_structure_splitting(ir) || progress; 895 progress = do_if_simplification(ir) || progress; 896 progress = do_discard_simplification(ir) || progress; 897 progress = do_copy_propagation(ir) || progress; 898 progress = do_copy_propagation_elements(ir) || progress; 899 if (linked) 900 progress = do_dead_code(ir) || progress; 901 else 902 progress = do_dead_code_unlinked(ir) || progress; 903 progress = do_dead_code_local(ir) || progress; 904 progress = do_tree_grafting(ir) || progress; 905 progress = do_constant_propagation(ir) || progress; 906 if (linked) 907 progress = do_constant_variable(ir) || progress; 908 else 909 progress = do_constant_variable_unlinked(ir) || progress; 910 progress = do_constant_folding(ir) || progress; 911 progress = do_algebraic(ir) || progress; 912 progress = do_lower_jumps(ir) || progress; 913 progress = do_vec_index_to_swizzle(ir) || progress; 914 progress = do_swizzle_swizzle(ir) || progress; 915 progress = do_noop_swizzle(ir) || progress; 916 917 progress = optimize_redundant_jumps(ir) || progress; 918 919 loop_state *ls = analyze_loop_variables(ir); 920 if (ls->loop_found) { 921 progress = set_loop_controls(ir, ls) || progress; 922 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress; 923 } 924 delete ls; 925 926 return progress; 927} 928 929extern "C" { 930 931/** 932 * To be called at GL teardown time, this frees compiler datastructures. 933 * 934 * After calling this, any previously compiled shaders and shader 935 * programs would be invalid. So this should happen at approximately 936 * program exit. 937 */ 938void 939_mesa_destroy_shader_compiler(void) 940{ 941 _mesa_destroy_shader_compiler_caches(); 942 943 _mesa_glsl_release_types(); 944} 945 946/** 947 * Releases compiler caches to trade off performance for memory. 948 * 949 * Intended to be used with glReleaseShaderCompiler(). 950 */ 951void 952_mesa_destroy_shader_compiler_caches(void) 953{ 954 _mesa_glsl_release_functions(); 955} 956 957} 958