blob: 4183d1385660e134cee875e567d00fb3240b2aa6 [file] [log] [blame]
Ian Romanicka87ac252010-02-22 13:19:34 -08001/*
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 <stdlib.h>
26#include <string.h>
27#include <assert.h>
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <unistd.h>
33
34#include "ast.h"
35#include "glsl_parser_extras.h"
Ian Romanickd59673c2010-02-25 17:17:23 -080036#include "glsl_parser.h"
Eric Anholt62735692010-04-05 15:24:28 -070037#include "ir_constant_folding.h"
Eric Anholt7d211042010-04-16 16:43:47 -070038#include "ir_dead_code.h"
Eric Anholtcad97662010-04-07 11:46:26 -070039#include "ir_function_inlining.h"
Eric Anholt5ba94202010-04-14 17:03:03 -070040#include "ir_if_simplification.h"
Ian Romanick1c4156f2010-03-10 09:27:03 -080041#include "ir_print_visitor.h"
Kenneth Graunke34350be2010-04-07 14:38:03 -070042#include "ir_reader.h"
Ian Romanicka87ac252010-02-22 13:19:34 -080043
Ian Romanick5bfe30a2010-04-07 16:44:30 -070044const char *
45_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
46{
47 switch (target) {
48 case vertex_shader: return "vertex";
49 case fragment_shader: return "fragment";
50 case geometry_shader: return "geometry";
Eric Anholt81f49a72010-04-29 17:57:28 -070051 case ir_shader: break;
Ian Romanick5bfe30a2010-04-07 16:44:30 -070052 }
53
54 assert(!"Should not get here.");
55}
56
57
Ian Romanicka87ac252010-02-22 13:19:34 -080058void
Ian Romanick1f585182010-03-11 14:08:33 -080059_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
60 const char *fmt, ...)
Ian Romanicka87ac252010-02-22 13:19:34 -080061{
62 char buf[1024];
63 int len;
64 va_list ap;
65
Ian Romanick71d0bbf2010-03-23 13:21:19 -070066 state->error = true;
Ian Romanick1f585182010-03-11 14:08:33 -080067
Ian Romanicka87ac252010-02-22 13:19:34 -080068 len = snprintf(buf, sizeof(buf), "%u:%u(%u): error: ",
69 locp->source, locp->first_line, locp->first_column);
70
71 va_start(ap, fmt);
72 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
73 va_end(ap);
74
75 printf("%s\n", buf);
76}
77
78
Ian Romanick56b8b212010-04-07 14:47:46 -070079void
80_mesa_glsl_warning(const YYLTYPE *locp, const _mesa_glsl_parse_state *state,
81 const char *fmt, ...)
82{
83 char buf[1024];
84 int len;
85 va_list ap;
86
87 len = snprintf(buf, sizeof(buf), "%u:%u(%u): warning: ",
88 locp->source, locp->first_line, locp->first_column);
89
90 va_start(ap, fmt);
91 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
92 va_end(ap);
93
94 printf("%s\n", buf);
95}
96
97
Ian Romanicke7017612010-04-07 16:46:25 -070098bool
99_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
100 const char *behavior, YYLTYPE *behavior_locp,
101 _mesa_glsl_parse_state *state)
102{
103 enum {
104 extension_disable,
105 extension_enable,
106 extension_require,
107 extension_warn
108 } ext_mode;
Ian Romanicke7017612010-04-07 16:46:25 -0700109
110 if (strcmp(behavior, "warn") == 0) {
111 ext_mode = extension_warn;
112 } else if (strcmp(behavior, "require") == 0) {
113 ext_mode = extension_require;
114 } else if (strcmp(behavior, "enable") == 0) {
115 ext_mode = extension_enable;
116 } else if (strcmp(behavior, "disable") == 0) {
117 ext_mode = extension_disable;
118 } else {
119 _mesa_glsl_error(behavior_locp, state,
120 "Unknown extension behavior `%s'",
121 behavior);
122 return false;
123 }
124
Ian Romanick887a8b02010-04-07 16:57:56 -0700125 bool unsupported = false;
126
Ian Romanicke7017612010-04-07 16:46:25 -0700127 if (strcmp(name, "all") == 0) {
128 if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
129 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
130 (ext_mode == extension_enable)
131 ? "enable" : "require");
132 return false;
133 }
Ian Romanickeb56cea2010-04-23 13:32:23 -0700134 } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
Ian Romanickc77b2572010-04-07 16:59:46 -0700135 /* This extension is only supported in fragment shaders.
136 */
137 if (state->target != fragment_shader) {
138 unsupported = true;
139 } else {
140 state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
141 state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
142 }
Ian Romanickeb56cea2010-04-23 13:32:23 -0700143 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
Ian Romanick0c824652010-04-07 17:13:44 -0700144 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
145 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
Ian Romanicke7017612010-04-07 16:46:25 -0700146 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700147 unsupported = true;
148 }
149
150 if (unsupported) {
151 static const char *const fmt = "extension `%s' unsupported in %s shader";
152
Ian Romanicke7017612010-04-07 16:46:25 -0700153 if (ext_mode == extension_require) {
Ian Romanick887a8b02010-04-07 16:57:56 -0700154 _mesa_glsl_error(name_locp, state, fmt,
155 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700156 return false;
Ian Romanick1799a0c2010-04-07 14:50:36 -0700157 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700158 _mesa_glsl_warning(name_locp, state, fmt,
159 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700160 }
161 }
162
163 return true;
164}
165
166
Ian Romanicka87ac252010-02-22 13:19:34 -0800167ast_node::~ast_node()
168{
169 /* empty */
170}
171
172
173void
174_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
175{
176 if (q->constant)
177 printf("const ");
178
179 if (q->invariant)
180 printf("invariant ");
181
182 if (q->attribute)
183 printf("attribute ");
184
185 if (q->varying)
186 printf("varying ");
187
188 if (q->in && q->out)
189 printf("inout ");
190 else {
191 if (q->in)
192 printf("in ");
193
194 if (q->out)
195 printf("out ");
196 }
197
198 if (q->centroid)
199 printf("centroid ");
200 if (q->uniform)
201 printf("uniform ");
202 if (q->smooth)
203 printf("smooth ");
204 if (q->flat)
205 printf("flat ");
206 if (q->noperspective)
207 printf("noperspective ");
208}
209
210
211void
212ast_node::print(void) const
213{
Ian Romanick03d3f3a2010-04-02 11:03:47 -0700214 printf("unhandled node ");
Ian Romanicka87ac252010-02-22 13:19:34 -0800215}
216
217
218ast_node::ast_node(void)
219{
Ian Romanick53d27742010-02-22 13:22:10 -0800220 make_empty_list(this);
Ian Romanicka87ac252010-02-22 13:19:34 -0800221}
222
Ian Romanicka87ac252010-02-22 13:19:34 -0800223
224static void
225ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
226{
227 if (is_array) {
228 printf("[ ");
229
230 if (array_size)
231 array_size->print();
232
233 printf("] ");
234 }
235}
236
237
Ian Romanicka87ac252010-02-22 13:19:34 -0800238void
239ast_compound_statement::print(void) const
240{
241 const struct simple_node *ptr;
242
243 printf("{\n");
244
245 foreach(ptr, & statements) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800246 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800247 }
248
249 printf("}\n");
250}
251
252
253ast_compound_statement::ast_compound_statement(int new_scope,
254 ast_node *statements)
255{
256 this->new_scope = new_scope;
257 make_empty_list(& this->statements);
258
259 if (statements != NULL) {
260 /* This seems odd, but it works. The simple_list is,
261 * basically, a circular list. insert_at_tail adds
262 * the specified node to the list before the current
263 * head.
264 */
265 insert_at_tail((struct simple_node *) statements,
266 & this->statements);
267 }
268}
269
270
271void
272ast_expression::print(void) const
273{
Ian Romanicka87ac252010-02-22 13:19:34 -0800274 switch (oper) {
275 case ast_assign:
Ian Romanicka87ac252010-02-22 13:19:34 -0800276 case ast_mul_assign:
277 case ast_div_assign:
278 case ast_mod_assign:
279 case ast_add_assign:
280 case ast_sub_assign:
281 case ast_ls_assign:
282 case ast_rs_assign:
283 case ast_and_assign:
284 case ast_xor_assign:
285 case ast_or_assign:
286 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800287 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800288 subexpressions[1]->print();
289 break;
290
291 case ast_field_selection:
292 subexpressions[0]->print();
293 printf(". %s ", primary_expression.identifier);
294 break;
295
296 case ast_plus:
297 case ast_neg:
298 case ast_bit_not:
299 case ast_logic_not:
300 case ast_pre_inc:
301 case ast_pre_dec:
Ian Romanick88349b22010-02-22 19:10:25 -0800302 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800303 subexpressions[0]->print();
304 break;
305
306 case ast_post_inc:
307 case ast_post_dec:
308 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800309 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800310 break;
311
312 case ast_conditional:
313 subexpressions[0]->print();
314 printf("? ");
315 subexpressions[1]->print();
316 printf(": ");
317 subexpressions[1]->print();
318 break;
319
320 case ast_array_index:
321 subexpressions[0]->print();
322 printf("[ ");
323 subexpressions[1]->print();
324 printf("] ");
325 break;
326
327 case ast_function_call: {
328 ast_expression *parameters = subexpressions[1];
329
330 subexpressions[0]->print();
331 printf("( ");
332
333 if (parameters != NULL) {
334 struct simple_node *ptr;
335
336 parameters->print();
337 foreach (ptr, (struct simple_node *) parameters) {
338 printf(", ");
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800339 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800340 }
341 }
342
343 printf(") ");
344 break;
345 }
346
347 case ast_identifier:
348 printf("%s ", primary_expression.identifier);
349 break;
350
351 case ast_int_constant:
352 printf("%d ", primary_expression.int_constant);
353 break;
354
355 case ast_uint_constant:
356 printf("%u ", primary_expression.uint_constant);
357 break;
358
359 case ast_float_constant:
360 printf("%f ", primary_expression.float_constant);
361 break;
362
363 case ast_bool_constant:
364 printf("%s ",
365 primary_expression.bool_constant
366 ? "true" : "false");
367 break;
368
369 case ast_sequence: {
370 struct simple_node *ptr;
371 struct simple_node *const head = first_elem(& expressions);
372
373 printf("( ");
374 foreach (ptr, & expressions) {
375 if (ptr != head)
376 printf(", ");
377
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800378 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800379 }
380 printf(") ");
381 break;
382 }
Ian Romanick88349b22010-02-22 19:10:25 -0800383
384 default:
385 assert(0);
386 break;
Ian Romanicka87ac252010-02-22 13:19:34 -0800387 }
388}
389
390ast_expression::ast_expression(int oper,
391 ast_expression *ex0,
392 ast_expression *ex1,
393 ast_expression *ex2)
394{
395 this->oper = ast_operators(oper);
396 this->subexpressions[0] = ex0;
397 this->subexpressions[1] = ex1;
398 this->subexpressions[2] = ex2;
399 make_empty_list(& expressions);
400}
401
402
403void
404ast_expression_statement::print(void) const
405{
406 if (expression)
407 expression->print();
408
409 printf("; ");
410}
411
412
413ast_expression_statement::ast_expression_statement(ast_expression *ex) :
414 expression(ex)
415{
416 /* empty */
417}
418
419
420void
421ast_function::print(void) const
422{
423 struct simple_node *ptr;
424
425 return_type->print();
426 printf(" %s (", identifier);
427
428 foreach(ptr, & parameters) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800429 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800430 }
431
432 printf(")");
433}
434
435
436ast_function::ast_function(void)
Ian Romanick92318a92010-03-31 18:23:21 -0700437 : is_definition(false), signature(NULL)
Ian Romanicka87ac252010-02-22 13:19:34 -0800438{
439 make_empty_list(& parameters);
440}
441
442
443void
444ast_fully_specified_type::print(void) const
445{
446 _mesa_ast_type_qualifier_print(& qualifier);
447 specifier->print();
448}
449
450
451void
452ast_parameter_declarator::print(void) const
453{
454 type->print();
455 if (identifier)
456 printf("%s ", identifier);
457 ast_opt_array_size_print(is_array, array_size);
458}
459
460
461void
462ast_function_definition::print(void) const
463{
464 prototype->print();
465 body->print();
466}
467
468
469void
470ast_declaration::print(void) const
471{
472 printf("%s ", identifier);
473 ast_opt_array_size_print(is_array, array_size);
474
475 if (initializer) {
476 printf("= ");
477 initializer->print();
478 }
479}
480
481
482ast_declaration::ast_declaration(char *identifier, int is_array,
483 ast_expression *array_size,
484 ast_expression *initializer)
485{
486 this->identifier = identifier;
487 this->is_array = is_array;
488 this->array_size = array_size;
489 this->initializer = initializer;
490}
491
492
493void
494ast_declarator_list::print(void) const
495{
496 struct simple_node *head;
497 struct simple_node *ptr;
498
499 assert(type || invariant);
500
501 if (type)
502 type->print();
503 else
504 printf("invariant ");
505
506 head = first_elem(& declarations);
507 foreach (ptr, & declarations) {
508 if (ptr != head)
509 printf(", ");
510
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800511 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800512 }
513
514 printf("; ");
515}
516
517
518ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
519{
520 this->type = type;
521 make_empty_list(& this->declarations);
522}
523
524void
525ast_jump_statement::print(void) const
526{
527 switch (mode) {
528 case ast_continue:
529 printf("continue; ");
530 break;
531 case ast_break:
532 printf("break; ");
533 break;
534 case ast_return:
535 printf("return ");
536 if (opt_return_value)
537 opt_return_value->print();
538
539 printf("; ");
540 break;
541 case ast_discard:
542 printf("discard; ");
543 break;
544 }
545}
546
547
548ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
549{
550 this->mode = ast_jump_modes(mode);
551
552 if (mode == ast_return)
553 opt_return_value = return_value;
554}
555
556
557void
558ast_selection_statement::print(void) const
559{
560 printf("if ( ");
561 condition->print();
562 printf(") ");
563
564 then_statement->print();
565
566 if (else_statement) {
567 printf("else ");
568 else_statement->print();
569 }
570
571}
572
573
574ast_selection_statement::ast_selection_statement(ast_expression *condition,
575 ast_node *then_statement,
576 ast_node *else_statement)
577{
578 this->condition = condition;
579 this->then_statement = then_statement;
580 this->else_statement = else_statement;
581}
582
583
584void
585ast_iteration_statement::print(void) const
586{
587 switch (mode) {
588 case ast_for:
589 printf("for( ");
590 if (init_statement)
591 init_statement->print();
592 printf("; ");
593
594 if (condition)
595 condition->print();
596 printf("; ");
597
598 if (rest_expression)
599 rest_expression->print();
600 printf(") ");
601
602 body->print();
603 break;
604
605 case ast_while:
606 printf("while ( ");
607 if (condition)
608 condition->print();
609 printf(") ");
610 body->print();
611 break;
612
613 case ast_do_while:
614 printf("do ");
615 body->print();
616 printf("while ( ");
617 if (condition)
618 condition->print();
619 printf("); ");
620 break;
621 }
622}
623
624
625ast_iteration_statement::ast_iteration_statement(int mode,
626 ast_node *init,
627 ast_node *condition,
628 ast_expression *rest_expression,
629 ast_node *body)
630{
631 this->mode = ast_iteration_modes(mode);
632 this->init_statement = init;
633 this->condition = condition;
634 this->rest_expression = rest_expression;
635 this->body = body;
636}
637
638
639void
640ast_struct_specifier::print(void) const
641{
642 struct simple_node *ptr;
643
644 printf("struct %s { ", name);
645 foreach (ptr, & declarations) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800646 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800647 }
648 printf("} ");
649}
650
651
652ast_struct_specifier::ast_struct_specifier(char *identifier,
653 ast_node *declarator_list)
654{
655 name = identifier;
656
657 /* This seems odd, but it works. The simple_list is,
658 * basically, a circular list. insert_at_tail adds
659 * the specified node to the list before the current
660 * head.
661 */
662 insert_at_tail((struct simple_node *) declarator_list,
663 & declarations);
664}
665
666
667static char *
668load_text_file(const char *file_name, size_t *size)
669{
670 char *text = NULL;
671 struct stat st;
672 ssize_t total_read = 0;
673 int fd = open(file_name, O_RDONLY);
674
675 *size = 0;
676 if (fd < 0) {
677 return NULL;
678 }
679
680 if (fstat(fd, & st) == 0) {
681 text = (char *) malloc(st.st_size + 1);
682 if (text != NULL) {
683 do {
684 ssize_t bytes = read(fd, text + total_read,
685 st.st_size - total_read);
686 if (bytes < 0) {
687 free(text);
688 text = NULL;
689 break;
690 }
691
692 if (bytes == 0) {
693 break;
694 }
695
696 total_read += bytes;
697 } while (total_read < st.st_size);
698
699 text[total_read] = '\0';
700 *size = total_read;
701 }
702 }
703
704 close(fd);
705
706 return text;
707}
708
709
710int
711main(int argc, char **argv)
712{
713 struct _mesa_glsl_parse_state state;
714 char *shader;
715 size_t shader_len;
716 struct simple_node *ptr;
Ian Romanick0044e7e2010-03-08 23:44:00 -0800717 exec_list instructions;
Ian Romanicka87ac252010-02-22 13:19:34 -0800718
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800719 if (argc < 3) {
Kenneth Graunke34350be2010-04-07 14:38:03 -0700720 printf("Usage: %s [v|g|f|i] <shader_file>\n", argv[0]);
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800721 return EXIT_FAILURE;
722 }
723
Ian Romanick6aeada72010-04-23 13:37:47 -0700724 memset(& state, 0, sizeof(state));
725
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800726 switch (argv[1][0]) {
727 case 'v':
728 state.target = vertex_shader;
729 break;
730 case 'g':
731 state.target = geometry_shader;
732 break;
733 case 'f':
734 state.target = fragment_shader;
735 break;
Kenneth Graunke34350be2010-04-07 14:38:03 -0700736 case 'i':
737 state.target = ir_shader;
738 break;
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800739 default:
Kenneth Graunke34350be2010-04-07 14:38:03 -0700740 printf("Usage: %s [v|g|f|i] <shader_file>\n", argv[0]);
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800741 return EXIT_FAILURE;
742 }
743
744 shader = load_text_file(argv[2], & shader_len);
Ian Romanicka87ac252010-02-22 13:19:34 -0800745
746 state.scanner = NULL;
747 make_empty_list(& state.translation_unit);
Ian Romanick8bde4ce2010-03-19 11:57:24 -0700748 state.symbols = new glsl_symbol_table;
Ian Romanick1f585182010-03-11 14:08:33 -0800749 state.error = false;
Ian Romanick5185a5f2010-03-29 15:20:42 -0700750 state.temp_index = 0;
Ian Romanicke9d0f262010-04-05 17:01:53 -0700751 state.loop_or_switch_nesting = NULL;
Ian Romanick0c824652010-04-07 17:13:44 -0700752 state.ARB_texture_rectangle_enable = true;
Ian Romanicka87ac252010-02-22 13:19:34 -0800753
Kenneth Graunke34350be2010-04-07 14:38:03 -0700754 if (state.target != ir_shader) {
755 _mesa_glsl_lexer_ctor(& state, shader, shader_len);
756 _mesa_glsl_parse(& state);
757 _mesa_glsl_lexer_dtor(& state);
Ian Romanicka87ac252010-02-22 13:19:34 -0800758
Kenneth Graunke34350be2010-04-07 14:38:03 -0700759 foreach (ptr, & state.translation_unit) {
760 ((ast_node *)ptr)->print();
761 }
762
763 _mesa_ast_to_hir(&instructions, &state);
764 } else {
Kenneth Graunkee8b39922010-04-07 15:16:20 -0700765 /* FINISHME: We should initialize this to the max GLSL version supported
766 * FINISHME: by the driver. At the moment, we don't know what that is.
767 */
768 state.language_version = 130;
769
Kenneth Graunke34350be2010-04-07 14:38:03 -0700770 _mesa_glsl_read_ir(&state, &instructions, shader);
Ian Romanicka87ac252010-02-22 13:19:34 -0800771 }
772
Eric Anholt62735692010-04-05 15:24:28 -0700773 /* Optimization passes */
774 if (!state.error) {
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700775 bool progress;
776 do {
777 progress = false;
Eric Anholtcad97662010-04-07 11:46:26 -0700778
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700779 progress = do_function_inlining(&instructions) || progress;
Eric Anholt5ba94202010-04-14 17:03:03 -0700780 progress = do_if_simplification(&instructions) || progress;
Eric Anholt7d211042010-04-16 16:43:47 -0700781 progress = do_dead_code_unlinked(&instructions) || progress;
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700782
783 /* Constant folding */
784 ir_constant_folding_visitor constant_folding;
785 visit_exec_list(&instructions, &constant_folding);
786 } while (progress);
Eric Anholt62735692010-04-05 15:24:28 -0700787 }
788
789 /* Print out the resulting IR */
Ian Romanick1c4156f2010-03-10 09:27:03 -0800790 printf("\n\n");
Ian Romanick1c4156f2010-03-10 09:27:03 -0800791
Ian Romanick1f585182010-03-11 14:08:33 -0800792 if (!state.error) {
Ian Romanick36d8a642010-04-28 13:04:15 -0700793 _mesa_print_ir(&instructions, &state);
Ian Romanick1c4156f2010-03-10 09:27:03 -0800794 }
795
Ian Romanick8bde4ce2010-03-19 11:57:24 -0700796 delete state.symbols;
Ian Romanicka87ac252010-02-22 13:19:34 -0800797
Eric Anholt7c15bb22010-03-25 14:37:25 -0700798 return state.error != 0;
Ian Romanicka87ac252010-02-22 13:19:34 -0800799}