From 14ebd0fdd799d4b721633d25a08d966ee8069243 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 18 Jan 2016 09:33:56 -0800 Subject: [PATCH] nir/spirv: Hanle continues that use SSA values from the loop body Instead of emitting the continue before the loop body we emit it afterwards. Then, once we've finished with the entire function, we run nir_repair_ssa to add whatever phi nodes are needed. --- src/glsl/nir/spirv/vtn_cfg.c | 19 +++++++++++++++---- src/glsl/nir/spirv/vtn_private.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/glsl/nir/spirv/vtn_cfg.c b/src/glsl/nir/spirv/vtn_cfg.c index b3061ce47bb..a57a44363dd 100644 --- a/src/glsl/nir/spirv/vtn_cfg.c +++ b/src/glsl/nir/spirv/vtn_cfg.c @@ -559,6 +559,9 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list, nir_loop *loop = nir_loop_create(b->shader); nir_cf_node_insert(b->nb.cursor, &loop->cf_node); + b->nb.cursor = nir_after_cf_list(&loop->body); + vtn_emit_cf_list(b, &vtn_loop->body, NULL, NULL, handler); + if (!list_empty(&vtn_loop->cont_body)) { /* If we have a non-trivial continue body then we need to put * it at the beginning of the loop with a flag to ensure that @@ -570,7 +573,7 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list, b->nb.cursor = nir_before_cf_node(&loop->cf_node); nir_store_var(&b->nb, do_cont, nir_imm_int(&b->nb, NIR_FALSE), 1); - b->nb.cursor = nir_after_cf_list(&loop->body); + b->nb.cursor = nir_before_cf_list(&loop->body); nir_if *cont_if = nir_if_create(b->shader); cont_if->condition = nir_src_for_ssa(nir_load_var(&b->nb, do_cont)); nir_cf_node_insert(b->nb.cursor, &cont_if->cf_node); @@ -580,10 +583,9 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list, b->nb.cursor = nir_after_cf_node(&cont_if->cf_node); nir_store_var(&b->nb, do_cont, nir_imm_int(&b->nb, NIR_TRUE), 1); - } - b->nb.cursor = nir_after_cf_list(&loop->body); - vtn_emit_cf_list(b, &vtn_loop->body, NULL, NULL, handler); + b->has_loop_continue = true; + } b->nb.cursor = nir_after_cf_node(&loop->cf_node); break; @@ -672,5 +674,14 @@ vtn_function_emit(struct vtn_builder *b, struct vtn_function *func, { nir_builder_init(&b->nb, func->impl); b->nb.cursor = nir_after_cf_list(&func->impl->body); + b->has_loop_continue = false; + vtn_emit_cf_list(b, &func->body, NULL, NULL, instruction_handler); + + /* Continue blocks for loops get inserted before the body of the loop + * but instructions in the continue may use SSA defs in the loop body. + * Therefore, we need to repair SSA to insert the needed phi nodes. + */ + if (b->has_loop_continue) + nir_repair_ssa_impl(func->impl); } diff --git a/src/glsl/nir/spirv/vtn_private.h b/src/glsl/nir/spirv/vtn_private.h index 129414a4001..f91330ad486 100644 --- a/src/glsl/nir/spirv/vtn_private.h +++ b/src/glsl/nir/spirv/vtn_private.h @@ -334,6 +334,8 @@ struct vtn_builder { /* Current function parameter index */ unsigned func_param_idx; + + bool has_loop_continue; }; static inline struct vtn_value * -- 2.30.2