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