From: Ian Romanick Date: Tue, 6 Apr 2010 01:07:27 +0000 (-0700) Subject: Generate correct IR for do-while loops X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8c46ed24906ee10dd2f2cfaf4cf9803eca1ba523;p=mesa.git Generate correct IR for do-while loops Previously the same code was generated for a while loop and a do-while loop. This pulls the code that generates the conditional break into a separate method. This method is called either at the beginning or the end depending on the loop type. Reported-by: Kenneth Graunke --- diff --git a/ast.h b/ast.h index ba500dc773a..d899fb1d090 100644 --- a/ast.h +++ b/ast.h @@ -572,6 +572,15 @@ public: ast_expression *rest_expression; ast_node *body; + +private: + /** + * Generate IR from the condition of a loop + * + * This is factored out of ::hir because some loops have the condition + * test at the top (for and while), and others have it at the end (do-while). + */ + void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *); }; diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index ae5a8d51f78..6afd7eafec1 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -2104,27 +2104,10 @@ ast_selection_statement::hir(exec_list *instructions, } -ir_rvalue * -ast_iteration_statement::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) +void +ast_iteration_statement::condition_to_hir(ir_loop *stmt, + struct _mesa_glsl_parse_state *state) { - /* For loops start a new scope, but while and do-while loops do not. - */ - if (mode == ast_for) - state->symbols->push_scope(); - - if (init_statement != NULL) - init_statement->hir(instructions, state); - - ir_loop *const stmt = new ir_loop(); - instructions->push_tail(stmt); - - /* Track the current loop and / or switch-statement nesting. - */ - ir_instruction *const nesting = state->loop_or_switch_nesting; - state->loop_or_switch_nesting = stmt; - - if (condition != NULL) { ir_rvalue *const cond = condition->hir(& stmt->body_instructions, state); @@ -2152,6 +2135,31 @@ ast_iteration_statement::hir(exec_list *instructions, stmt->body_instructions.push_tail(if_stmt); } } +} + + +ir_rvalue * +ast_iteration_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* For loops start a new scope, but while and do-while loops do not. + */ + if (mode == ast_for) + state->symbols->push_scope(); + + if (init_statement != NULL) + init_statement->hir(instructions, state); + + ir_loop *const stmt = new ir_loop(); + instructions->push_tail(stmt); + + /* Track the current loop and / or switch-statement nesting. + */ + ir_instruction *const nesting = state->loop_or_switch_nesting; + state->loop_or_switch_nesting = stmt; + + if (mode != ast_do_while) + condition_to_hir(stmt, state); if (body != NULL) { ast_node *node = (ast_node *) body; @@ -2164,6 +2172,9 @@ ast_iteration_statement::hir(exec_list *instructions, if (rest_expression != NULL) rest_expression->hir(& stmt->body_instructions, state); + if (mode == ast_do_while) + condition_to_hir(stmt, state); + if (mode == ast_for) state->symbols->pop_scope();