Merge branch 'xa_branch'
[mesa.git] / src / glsl / glsl_parser_extras.cpp
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
28 extern "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
116 const 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
130 void
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
150 void
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 */
172 enum 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 */
182 struct _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 */
253 static 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 */
276 bool _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 */
326 void _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 */
341 static 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
352 bool
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
410 void
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
448 void
449 ast_node::print(void) const
450 {
451 printf("unhandled node ");
452 }
453
454
455 ast_node::ast_node(void)
456 {
457 this->location.source = 0;
458 this->location.line = 0;
459 this->location.column = 0;
460 }
461
462
463 static void
464 ast_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
477 void
478 ast_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
491 ast_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
502 void
503 ast_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
615 ast_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
627 void
628 ast_expression_statement::print(void) const
629 {
630 if (expression)
631 expression->print();
632
633 printf("; ");
634 }
635
636
637 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
638 expression(ex)
639 {
640 /* empty */
641 }
642
643
644 void
645 ast_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
659 ast_function::ast_function(void)
660 : is_definition(false), signature(NULL)
661 {
662 /* empty */
663 }
664
665
666 void
667 ast_fully_specified_type::print(void) const
668 {
669 _mesa_ast_type_qualifier_print(& qualifier);
670 specifier->print();
671 }
672
673
674 void
675 ast_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
684 void
685 ast_function_definition::print(void) const
686 {
687 prototype->print();
688 body->print();
689 }
690
691
692 void
693 ast_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
705 ast_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
716 void
717 ast_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
738 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
739 {
740 this->type = type;
741 this->invariant = false;
742 }
743
744 void
745 ast_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
768 ast_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
777 void
778 ast_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
794 ast_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
804 void
805 ast_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
845 ast_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
859 void
860 ast_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
871 ast_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
883 bool
884 do_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
929 extern "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 */
938 void
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 */
951 void
952 _mesa_destroy_shader_compiler_caches(void)
953 {
954 _mesa_glsl_release_functions();
955 }
956
957 }