Mesa (glsl2): glsl2: When a "continue" happens in a "for" loop, run the loop expression.

Eric Anholt anholt at kemper.freedesktop.org
Thu Jul 22 20:13:59 UTC 2010


Module: Mesa
Branch: glsl2
Commit: 2d1ed7b1b112cf13dd7eda7f500691f4c98a1ccc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2d1ed7b1b112cf13dd7eda7f500691f4c98a1ccc

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jul 22 12:55:16 2010 -0700

glsl2: When a "continue" happens in a "for" loop, run the loop expression.

Fixes:
glsl1-for-loop with continue

Bug #29097

---

 src/glsl/ast_to_hir.cpp       |   14 ++++++++++++++
 src/glsl/glsl_parser_extras.h |    1 +
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 99a2183..0cb3863 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2308,6 +2308,16 @@ ast_jump_statement::hir(exec_list *instructions,
       } else {
 	 ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
 
+	 /* Inline the for loop expression again, since we don't know
+	  * where near the end of the loop body the normal copy of it
+	  * is going to be placed.
+	  */
+	 if (mode == ast_continue &&
+	     state->loop_or_switch_nesting_ast->rest_expression) {
+	    state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
+								    state);
+	 }
+
 	 if (loop != NULL) {
 	    ir_loop_jump *const jump =
 	       new(ctx) ir_loop_jump((mode == ast_break)
@@ -2422,7 +2432,10 @@ ast_iteration_statement::hir(exec_list *instructions,
    /* Track the current loop and / or switch-statement nesting.
     */
    ir_instruction *const nesting = state->loop_or_switch_nesting;
+   ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;
+
    state->loop_or_switch_nesting = stmt;
+   state->loop_or_switch_nesting_ast = this;
 
    if (mode != ast_do_while)
       condition_to_hir(stmt, state);
@@ -2442,6 +2455,7 @@ ast_iteration_statement::hir(exec_list *instructions,
    /* Restore previous nesting before returning.
     */
    state->loop_or_switch_nesting = nesting;
+   state->loop_or_switch_nesting_ast = nesting_ast;
 
    /* Loops do not have r-values.
     */
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 56f6e18..3865843 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -104,6 +104,7 @@ struct _mesa_glsl_parse_state {
 
    /** Loop or switch statement containing the current instructions. */
    class ir_instruction *loop_or_switch_nesting;
+   class ast_iteration_statement *loop_or_switch_nesting_ast;
 
    /** List of structures defined in user code. */
    const glsl_type **user_structures;




More information about the mesa-commit mailing list