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