mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-13 21:50:31 +01:00
glsl_to_nir: emit loop continue construct
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39777>
This commit is contained in:
parent
143370f1a7
commit
d66de1bb49
8 changed files with 25 additions and 37 deletions
|
|
@ -1224,8 +1224,6 @@ public:
|
|||
ast_node *condition;
|
||||
ast_expression *rest_expression;
|
||||
|
||||
ir_exec_list rest_instructions;
|
||||
|
||||
ast_node *body;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6806,23 +6806,6 @@ ast_jump_statement::hir(ir_exec_list *instructions,
|
|||
_mesa_glsl_error(& loc, state,
|
||||
"break may only appear in a loop or a switch");
|
||||
} else {
|
||||
/* For a 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. Same goes for the condition for a do-while
|
||||
* loop.
|
||||
*/
|
||||
if (state->loop_nesting_ast != NULL &&
|
||||
mode == ast_continue && !state->switch_state.is_switch_innermost) {
|
||||
if (state->loop_nesting_ast->rest_expression) {
|
||||
clone_ir_list(linalloc, instructions,
|
||||
&state->loop_nesting_ast->rest_instructions);
|
||||
}
|
||||
if (state->loop_nesting_ast->mode ==
|
||||
ast_iteration_statement::ast_do_while) {
|
||||
state->loop_nesting_ast->condition_to_hir(instructions, state);
|
||||
}
|
||||
}
|
||||
|
||||
if (state->switch_state.is_switch_innermost &&
|
||||
mode == ast_continue) {
|
||||
/* Set 'continue_inside' to true. */
|
||||
|
|
@ -7061,16 +7044,6 @@ ast_switch_statement::hir(ir_exec_list *instructions,
|
|||
ir_if *irif = new(linalloc) ir_if(deref_continue_inside);
|
||||
ir_loop_jump *jump = new(linalloc) ir_loop_jump(ir_loop_jump::jump_continue);
|
||||
|
||||
if (state->loop_nesting_ast != NULL) {
|
||||
if (state->loop_nesting_ast->rest_expression) {
|
||||
clone_ir_list(linalloc, &irif->then_instructions,
|
||||
&state->loop_nesting_ast->rest_instructions);
|
||||
}
|
||||
if (state->loop_nesting_ast->mode ==
|
||||
ast_iteration_statement::ast_do_while) {
|
||||
state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state);
|
||||
}
|
||||
}
|
||||
irif->then_instructions.push_tail(jump);
|
||||
instructions->push_tail(irif);
|
||||
}
|
||||
|
|
@ -7419,27 +7392,24 @@ ast_iteration_statement::hir(ir_exec_list *instructions,
|
|||
bool saved_is_switch_innermost = state->switch_state.is_switch_innermost;
|
||||
state->switch_state.is_switch_innermost = false;
|
||||
|
||||
if (rest_expression != NULL)
|
||||
rest_expression->hir(&stmt->continue_instructions, state);
|
||||
|
||||
if (mode != ast_do_while)
|
||||
condition_to_hir(&stmt->body_instructions, state);
|
||||
|
||||
if (rest_expression != NULL)
|
||||
rest_expression->hir(&rest_instructions, state);
|
||||
|
||||
if (body != NULL) {
|
||||
if (mode == ast_do_while)
|
||||
state->symbols->push_scope();
|
||||
|
||||
body->hir(& stmt->body_instructions, state);
|
||||
body->hir(&stmt->body_instructions, state);
|
||||
|
||||
if (mode == ast_do_while)
|
||||
state->symbols->pop_scope();
|
||||
}
|
||||
|
||||
if (rest_expression != NULL)
|
||||
stmt->body_instructions.append_list(&rest_instructions);
|
||||
|
||||
if (mode == ast_do_while)
|
||||
condition_to_hir(&stmt->body_instructions, state);
|
||||
condition_to_hir(&stmt->continue_instructions, state);
|
||||
|
||||
if (mode != ast_do_while)
|
||||
state->symbols->pop_scope();
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ glsl_to_nir(struct gl_shader *gl_shader,
|
|||
ralloc_free(gl_shader->ir);
|
||||
gl_shader->ir = NULL;
|
||||
|
||||
nir_lower_continue_constructs(shader);
|
||||
|
||||
nir_validate_shader(shader, "after glsl to nir, before function inline");
|
||||
if (should_print_nir(shader)) {
|
||||
printf("glsl_to_nir\n");
|
||||
|
|
@ -789,6 +791,8 @@ nir_visitor::visit(ir_loop *ir)
|
|||
{
|
||||
nir_push_loop(&b);
|
||||
visit_exec_list(&ir->body_instructions, this);
|
||||
nir_push_continue(&b, NULL);
|
||||
visit_exec_list(&ir->continue_instructions, this);
|
||||
nir_pop_loop(&b, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1466,6 +1466,8 @@ public:
|
|||
|
||||
/** List of ir_instruction that make up the body of the loop. */
|
||||
ir_exec_list body_instructions;
|
||||
/** List of ir_instruction that make up the continue construct. */
|
||||
ir_exec_list continue_instructions;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ void call_for_basic_blocks(ir_exec_list *instructions,
|
|||
callback(leader, ir, data);
|
||||
leader = NULL;
|
||||
call_for_basic_blocks(&ir_loop->body_instructions, callback, data);
|
||||
call_for_basic_blocks(&ir_loop->continue_instructions, callback, data);
|
||||
} else if (ir->as_jump() || ir->as_call()) {
|
||||
callback(leader, ir, data);
|
||||
leader = NULL;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ ir_loop::clone(linear_ctx *linalloc, struct hash_table *ht) const
|
|||
ir_foreach_in_list(ir_instruction, ir, &this->body_instructions) {
|
||||
new_loop->body_instructions.push_tail(ir->clone(linalloc, ht));
|
||||
}
|
||||
ir_foreach_in_list(ir_instruction, ir, &this->continue_instructions) {
|
||||
new_loop->continue_instructions.push_tail(ir->clone(linalloc, ht));
|
||||
}
|
||||
|
||||
return new_loop;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ ir_loop::accept(ir_hierarchical_visitor *v)
|
|||
if (s == visit_stop)
|
||||
return s;
|
||||
|
||||
s = visit_list_elements(v, &this->continue_instructions);
|
||||
if (s == visit_stop)
|
||||
return s;
|
||||
|
||||
return v->visit_leave(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -652,6 +652,12 @@ ir_print_visitor::visit(ir_loop *ir)
|
|||
inst->accept(this);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(stderr, ") continue (\n");
|
||||
ir_foreach_in_list(ir_instruction, inst, &ir->continue_instructions) {
|
||||
indent();
|
||||
inst->accept(this);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
indentation--;
|
||||
indent();
|
||||
fprintf(f, "))\n");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue