blob: 4255d2d66e77c928542f924733a4fda16a2794f9 [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";
51 }
52
53 assert(!"Should not get here.");
54}
55
56
Ian Romanicka87ac252010-02-22 13:19:34 -080057void
Ian Romanick1f585182010-03-11 14:08:33 -080058_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
59 const char *fmt, ...)
Ian Romanicka87ac252010-02-22 13:19:34 -080060{
61 char buf[1024];
62 int len;
63 va_list ap;
64
Ian Romanick71d0bbf2010-03-23 13:21:19 -070065 state->error = true;
Ian Romanick1f585182010-03-11 14:08:33 -080066
Ian Romanicka87ac252010-02-22 13:19:34 -080067 len = snprintf(buf, sizeof(buf), "%u:%u(%u): error: ",
68 locp->source, locp->first_line, locp->first_column);
69
70 va_start(ap, fmt);
71 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
72 va_end(ap);
73
74 printf("%s\n", buf);
75}
76
77
Ian Romanick56b8b212010-04-07 14:47:46 -070078void
79_mesa_glsl_warning(const YYLTYPE *locp, const _mesa_glsl_parse_state *state,
80 const char *fmt, ...)
81{
82 char buf[1024];
83 int len;
84 va_list ap;
85
86 len = snprintf(buf, sizeof(buf), "%u:%u(%u): warning: ",
87 locp->source, locp->first_line, locp->first_column);
88
89 va_start(ap, fmt);
90 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
91 va_end(ap);
92
93 printf("%s\n", buf);
94}
95
96
Ian Romanicke7017612010-04-07 16:46:25 -070097bool
98_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
99 const char *behavior, YYLTYPE *behavior_locp,
100 _mesa_glsl_parse_state *state)
101{
102 enum {
103 extension_disable,
104 extension_enable,
105 extension_require,
106 extension_warn
107 } ext_mode;
Ian Romanicke7017612010-04-07 16:46:25 -0700108
109 if (strcmp(behavior, "warn") == 0) {
110 ext_mode = extension_warn;
111 } else if (strcmp(behavior, "require") == 0) {
112 ext_mode = extension_require;
113 } else if (strcmp(behavior, "enable") == 0) {
114 ext_mode = extension_enable;
115 } else if (strcmp(behavior, "disable") == 0) {
116 ext_mode = extension_disable;
117 } else {
118 _mesa_glsl_error(behavior_locp, state,
119 "Unknown extension behavior `%s'",
120 behavior);
121 return false;
122 }
123
Ian Romanick887a8b02010-04-07 16:57:56 -0700124 bool unsupported = false;
125
Ian Romanicke7017612010-04-07 16:46:25 -0700126 if (strcmp(name, "all") == 0) {
127 if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
128 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
129 (ext_mode == extension_enable)
130 ? "enable" : "require");
131 return false;
132 }
Ian Romanickeb56cea2010-04-23 13:32:23 -0700133 } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
Ian Romanickc77b2572010-04-07 16:59:46 -0700134 /* This extension is only supported in fragment shaders.
135 */
136 if (state->target != fragment_shader) {
137 unsupported = true;
138 } else {
139 state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
140 state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
141 }
Ian Romanickeb56cea2010-04-23 13:32:23 -0700142 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
Ian Romanick0c824652010-04-07 17:13:44 -0700143 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
144 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
Ian Romanicke7017612010-04-07 16:46:25 -0700145 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700146 unsupported = true;
147 }
148
149 if (unsupported) {
150 static const char *const fmt = "extension `%s' unsupported in %s shader";
151
Ian Romanicke7017612010-04-07 16:46:25 -0700152 if (ext_mode == extension_require) {
Ian Romanick887a8b02010-04-07 16:57:56 -0700153 _mesa_glsl_error(name_locp, state, fmt,
154 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700155 return false;
Ian Romanick1799a0c2010-04-07 14:50:36 -0700156 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700157 _mesa_glsl_warning(name_locp, state, fmt,
158 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700159 }
160 }
161
162 return true;
163}
164
165
Ian Romanicka87ac252010-02-22 13:19:34 -0800166ast_node::~ast_node()
167{
168 /* empty */
169}
170
171
172void
173_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
174{
175 if (q->constant)
176 printf("const ");
177
178 if (q->invariant)
179 printf("invariant ");
180
181 if (q->attribute)
182 printf("attribute ");
183
184 if (q->varying)
185 printf("varying ");
186
187 if (q->in && q->out)
188 printf("inout ");
189 else {
190 if (q->in)
191 printf("in ");
192
193 if (q->out)
194 printf("out ");
195 }
196
197 if (q->centroid)
198 printf("centroid ");
199 if (q->uniform)
200 printf("uniform ");
201 if (q->smooth)
202 printf("smooth ");
203 if (q->flat)
204 printf("flat ");
205 if (q->noperspective)
206 printf("noperspective ");
207}
208
209
210void
211ast_node::print(void) const
212{
Ian Romanick03d3f3a2010-04-02 11:03:47 -0700213 printf("unhandled node ");
Ian Romanicka87ac252010-02-22 13:19:34 -0800214}
215
216
217ast_node::ast_node(void)
218{
Ian Romanick53d27742010-02-22 13:22:10 -0800219 make_empty_list(this);
Ian Romanicka87ac252010-02-22 13:19:34 -0800220}
221
Ian Romanicka87ac252010-02-22 13:19:34 -0800222
223static void
224ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
225{
226 if (is_array) {
227 printf("[ ");
228
229 if (array_size)
230 array_size->print();
231
232 printf("] ");
233 }
234}
235
236
Ian Romanicka87ac252010-02-22 13:19:34 -0800237void
238ast_compound_statement::print(void) const
239{
240 const struct simple_node *ptr;
241
242 printf("{\n");
243
244 foreach(ptr, & statements) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800245 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800246 }
247
248 printf("}\n");
249}
250
251
252ast_compound_statement::ast_compound_statement(int new_scope,
253 ast_node *statements)
254{
255 this->new_scope = new_scope;
256 make_empty_list(& this->statements);
257
258 if (statements != NULL) {
259 /* This seems odd, but it works. The simple_list is,
260 * basically, a circular list. insert_at_tail adds
261 * the specified node to the list before the current
262 * head.
263 */
264 insert_at_tail((struct simple_node *) statements,
265 & this->statements);
266 }
267}
268
269
270void
271ast_expression::print(void) const
272{
Ian Romanicka87ac252010-02-22 13:19:34 -0800273 switch (oper) {
274 case ast_assign:
Ian Romanicka87ac252010-02-22 13:19:34 -0800275 case ast_mul_assign:
276 case ast_div_assign:
277 case ast_mod_assign:
278 case ast_add_assign:
279 case ast_sub_assign:
280 case ast_ls_assign:
281 case ast_rs_assign:
282 case ast_and_assign:
283 case ast_xor_assign:
284 case ast_or_assign:
285 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800286 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800287 subexpressions[1]->print();
288 break;
289
290 case ast_field_selection:
291 subexpressions[0]->print();
292 printf(". %s ", primary_expression.identifier);
293 break;
294
295 case ast_plus:
296 case ast_neg:
297 case ast_bit_not:
298 case ast_logic_not:
299 case ast_pre_inc:
300 case ast_pre_dec:
Ian Romanick88349b22010-02-22 19:10:25 -0800301 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800302 subexpressions[0]->print();
303 break;
304
305 case ast_post_inc:
306 case ast_post_dec:
307 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800308 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800309 break;
310
311 case ast_conditional:
312 subexpressions[0]->print();
313 printf("? ");
314 subexpressions[1]->print();
315 printf(": ");
316 subexpressions[1]->print();
317 break;
318
319 case ast_array_index:
320 subexpressions[0]->print();
321 printf("[ ");
322 subexpressions[1]->print();
323 printf("] ");
324 break;
325
326 case ast_function_call: {
327 ast_expression *parameters = subexpressions[1];
328
329 subexpressions[0]->print();
330 printf("( ");
331
332 if (parameters != NULL) {
333 struct simple_node *ptr;
334
335 parameters->print();
336 foreach (ptr, (struct simple_node *) parameters) {
337 printf(", ");
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800338 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800339 }
340 }
341
342 printf(") ");
343 break;
344 }
345
346 case ast_identifier:
347 printf("%s ", primary_expression.identifier);
348 break;
349
350 case ast_int_constant:
351 printf("%d ", primary_expression.int_constant);
352 break;
353
354 case ast_uint_constant:
355 printf("%u ", primary_expression.uint_constant);
356 break;
357
358 case ast_float_constant:
359 printf("%f ", primary_expression.float_constant);
360 break;
361
362 case ast_bool_constant:
363 printf("%s ",
364 primary_expression.bool_constant
365 ? "true" : "false");
366 break;
367
368 case ast_sequence: {
369 struct simple_node *ptr;
370 struct simple_node *const head = first_elem(& expressions);
371
372 printf("( ");
373 foreach (ptr, & expressions) {
374 if (ptr != head)
375 printf(", ");
376
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800377 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800378 }
379 printf(") ");
380 break;
381 }
Ian Romanick88349b22010-02-22 19:10:25 -0800382
383 default:
384 assert(0);
385 break;
Ian Romanicka87ac252010-02-22 13:19:34 -0800386 }
387}
388
389ast_expression::ast_expression(int oper,
390 ast_expression *ex0,
391 ast_expression *ex1,
392 ast_expression *ex2)
393{
394 this->oper = ast_operators(oper);
395 this->subexpressions[0] = ex0;
396 this->subexpressions[1] = ex1;
397 this->subexpressions[2] = ex2;
398 make_empty_list(& expressions);
399}
400
401
402void
403ast_expression_statement::print(void) const
404{
405 if (expression)
406 expression->print();
407
408 printf("; ");
409}
410
411
412ast_expression_statement::ast_expression_statement(ast_expression *ex) :
413 expression(ex)
414{
415 /* empty */
416}
417
418
419void
420ast_function::print(void) const
421{
422 struct simple_node *ptr;
423
424 return_type->print();
425 printf(" %s (", identifier);
426
427 foreach(ptr, & parameters) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800428 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800429 }
430
431 printf(")");
432}
433
434
435ast_function::ast_function(void)
Ian Romanick92318a92010-03-31 18:23:21 -0700436 : is_definition(false), signature(NULL)
Ian Romanicka87ac252010-02-22 13:19:34 -0800437{
438 make_empty_list(& parameters);
439}
440
441
442void
443ast_fully_specified_type::print(void) const
444{
445 _mesa_ast_type_qualifier_print(& qualifier);
446 specifier->print();
447}
448
449
450void
451ast_parameter_declarator::print(void) const
452{
453 type->print();
454 if (identifier)
455 printf("%s ", identifier);
456 ast_opt_array_size_print(is_array, array_size);
457}
458
459
460void
461ast_function_definition::print(void) const
462{
463 prototype->print();
464 body->print();
465}
466
467
468void
469ast_declaration::print(void) const
470{
471 printf("%s ", identifier);
472 ast_opt_array_size_print(is_array, array_size);
473
474 if (initializer) {
475 printf("= ");
476 initializer->print();
477 }
478}
479
480
481ast_declaration::ast_declaration(char *identifier, int is_array,
482 ast_expression *array_size,
483 ast_expression *initializer)
484{
485 this->identifier = identifier;
486 this->is_array = is_array;
487 this->array_size = array_size;
488 this->initializer = initializer;
489}
490
491
492void
493ast_declarator_list::print(void) const
494{
495 struct simple_node *head;
496 struct simple_node *ptr;
497
498 assert(type || invariant);
499
500 if (type)
501 type->print();
502 else
503 printf("invariant ");
504
505 head = first_elem(& declarations);
506 foreach (ptr, & declarations) {
507 if (ptr != head)
508 printf(", ");
509
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800510 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800511 }
512
513 printf("; ");
514}
515
516
517ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
518{
519 this->type = type;
520 make_empty_list(& this->declarations);
521}
522
523void
524ast_jump_statement::print(void) const
525{
526 switch (mode) {
527 case ast_continue:
528 printf("continue; ");
529 break;
530 case ast_break:
531 printf("break; ");
532 break;
533 case ast_return:
534 printf("return ");
535 if (opt_return_value)
536 opt_return_value->print();
537
538 printf("; ");
539 break;
540 case ast_discard:
541 printf("discard; ");
542 break;
543 }
544}
545
546
547ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
548{
549 this->mode = ast_jump_modes(mode);
550
551 if (mode == ast_return)
552 opt_return_value = return_value;
553}
554
555
556void
557ast_selection_statement::print(void) const
558{
559 printf("if ( ");
560 condition->print();
561 printf(") ");
562
563 then_statement->print();
564
565 if (else_statement) {
566 printf("else ");
567 else_statement->print();
568 }
569
570}
571
572
573ast_selection_statement::ast_selection_statement(ast_expression *condition,
574 ast_node *then_statement,
575 ast_node *else_statement)
576{
577 this->condition = condition;
578 this->then_statement = then_statement;
579 this->else_statement = else_statement;
580}
581
582
583void
584ast_iteration_statement::print(void) const
585{
586 switch (mode) {
587 case ast_for:
588 printf("for( ");
589 if (init_statement)
590 init_statement->print();
591 printf("; ");
592
593 if (condition)
594 condition->print();
595 printf("; ");
596
597 if (rest_expression)
598 rest_expression->print();
599 printf(") ");
600
601 body->print();
602 break;
603
604 case ast_while:
605 printf("while ( ");
606 if (condition)
607 condition->print();
608 printf(") ");
609 body->print();
610 break;
611
612 case ast_do_while:
613 printf("do ");
614 body->print();
615 printf("while ( ");
616 if (condition)
617 condition->print();
618 printf("); ");
619 break;
620 }
621}
622
623
624ast_iteration_statement::ast_iteration_statement(int mode,
625 ast_node *init,
626 ast_node *condition,
627 ast_expression *rest_expression,
628 ast_node *body)
629{
630 this->mode = ast_iteration_modes(mode);
631 this->init_statement = init;
632 this->condition = condition;
633 this->rest_expression = rest_expression;
634 this->body = body;
635}
636
637
638void
639ast_struct_specifier::print(void) const
640{
641 struct simple_node *ptr;
642
643 printf("struct %s { ", name);
644 foreach (ptr, & declarations) {
Ian Romanicke41a1cd2010-02-25 12:49:55 -0800645 ((ast_node *)ptr)->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800646 }
647 printf("} ");
648}
649
650
651ast_struct_specifier::ast_struct_specifier(char *identifier,
652 ast_node *declarator_list)
653{
654 name = identifier;
655
656 /* This seems odd, but it works. The simple_list is,
657 * basically, a circular list. insert_at_tail adds
658 * the specified node to the list before the current
659 * head.
660 */
661 insert_at_tail((struct simple_node *) declarator_list,
662 & declarations);
663}
664
665
666static char *
667load_text_file(const char *file_name, size_t *size)
668{
669 char *text = NULL;
670 struct stat st;
671 ssize_t total_read = 0;
672 int fd = open(file_name, O_RDONLY);
673
674 *size = 0;
675 if (fd < 0) {
676 return NULL;
677 }
678
679 if (fstat(fd, & st) == 0) {
680 text = (char *) malloc(st.st_size + 1);
681 if (text != NULL) {
682 do {
683 ssize_t bytes = read(fd, text + total_read,
684 st.st_size - total_read);
685 if (bytes < 0) {
686 free(text);
687 text = NULL;
688 break;
689 }
690
691 if (bytes == 0) {
692 break;
693 }
694
695 total_read += bytes;
696 } while (total_read < st.st_size);
697
698 text[total_read] = '\0';
699 *size = total_read;
700 }
701 }
702
703 close(fd);
704
705 return text;
706}
707
708
709int
710main(int argc, char **argv)
711{
712 struct _mesa_glsl_parse_state state;
713 char *shader;
714 size_t shader_len;
715 struct simple_node *ptr;
Ian Romanick0044e7e2010-03-08 23:44:00 -0800716 exec_list instructions;
Ian Romanicka87ac252010-02-22 13:19:34 -0800717
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800718 if (argc < 3) {
Kenneth Graunke34350be2010-04-07 14:38:03 -0700719 printf("Usage: %s [v|g|f|i] <shader_file>\n", argv[0]);
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800720 return EXIT_FAILURE;
721 }
722
Ian Romanick6aeada72010-04-23 13:37:47 -0700723 memset(& state, 0, sizeof(state));
724
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800725 switch (argv[1][0]) {
726 case 'v':
727 state.target = vertex_shader;
728 break;
729 case 'g':
730 state.target = geometry_shader;
731 break;
732 case 'f':
733 state.target = fragment_shader;
734 break;
Kenneth Graunke34350be2010-04-07 14:38:03 -0700735 case 'i':
736 state.target = ir_shader;
737 break;
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800738 default:
Kenneth Graunke34350be2010-04-07 14:38:03 -0700739 printf("Usage: %s [v|g|f|i] <shader_file>\n", argv[0]);
Ian Romanick8e6cd3b2010-03-10 09:31:30 -0800740 return EXIT_FAILURE;
741 }
742
743 shader = load_text_file(argv[2], & shader_len);
Ian Romanicka87ac252010-02-22 13:19:34 -0800744
745 state.scanner = NULL;
746 make_empty_list(& state.translation_unit);
Ian Romanick8bde4ce2010-03-19 11:57:24 -0700747 state.symbols = new glsl_symbol_table;
Ian Romanick1f585182010-03-11 14:08:33 -0800748 state.error = false;
Ian Romanick5185a5f2010-03-29 15:20:42 -0700749 state.temp_index = 0;
Ian Romanicke9d0f262010-04-05 17:01:53 -0700750 state.loop_or_switch_nesting = NULL;
Ian Romanick0c824652010-04-07 17:13:44 -0700751 state.ARB_texture_rectangle_enable = true;
Ian Romanicka87ac252010-02-22 13:19:34 -0800752
Kenneth Graunke34350be2010-04-07 14:38:03 -0700753 if (state.target != ir_shader) {
754 _mesa_glsl_lexer_ctor(& state, shader, shader_len);
755 _mesa_glsl_parse(& state);
756 _mesa_glsl_lexer_dtor(& state);
Ian Romanicka87ac252010-02-22 13:19:34 -0800757
Kenneth Graunke34350be2010-04-07 14:38:03 -0700758 foreach (ptr, & state.translation_unit) {
759 ((ast_node *)ptr)->print();
760 }
761
762 _mesa_ast_to_hir(&instructions, &state);
763 } else {
Kenneth Graunkee8b39922010-04-07 15:16:20 -0700764 /* FINISHME: We should initialize this to the max GLSL version supported
765 * FINISHME: by the driver. At the moment, we don't know what that is.
766 */
767 state.language_version = 130;
768
Kenneth Graunke34350be2010-04-07 14:38:03 -0700769 _mesa_glsl_read_ir(&state, &instructions, shader);
Ian Romanicka87ac252010-02-22 13:19:34 -0800770 }
771
Eric Anholt62735692010-04-05 15:24:28 -0700772 /* Optimization passes */
773 if (!state.error) {
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700774 bool progress;
775 do {
776 progress = false;
Eric Anholtcad97662010-04-07 11:46:26 -0700777
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700778 progress = do_function_inlining(&instructions) || progress;
Eric Anholt5ba94202010-04-14 17:03:03 -0700779 progress = do_if_simplification(&instructions) || progress;
Eric Anholt7d211042010-04-16 16:43:47 -0700780 progress = do_dead_code_unlinked(&instructions) || progress;
Eric Anholt2a7b2b22010-04-08 13:42:48 -0700781
782 /* Constant folding */
783 ir_constant_folding_visitor constant_folding;
784 visit_exec_list(&instructions, &constant_folding);
785 } while (progress);
Eric Anholt62735692010-04-05 15:24:28 -0700786 }
787
788 /* Print out the resulting IR */
Ian Romanick1c4156f2010-03-10 09:27:03 -0800789 printf("\n\n");
Ian Romanick1c4156f2010-03-10 09:27:03 -0800790
Ian Romanick1f585182010-03-11 14:08:33 -0800791 if (!state.error) {
Ian Romanick36d8a642010-04-28 13:04:15 -0700792 _mesa_print_ir(&instructions, &state);
Ian Romanick1c4156f2010-03-10 09:27:03 -0800793 }
794
Ian Romanick8bde4ce2010-03-19 11:57:24 -0700795 delete state.symbols;
Ian Romanicka87ac252010-02-22 13:19:34 -0800796
Eric Anholt7c15bb22010-03-25 14:37:25 -0700797 return state.error != 0;
Ian Romanicka87ac252010-02-22 13:19:34 -0800798}