From: Jason Ekstrand Date: Mon, 18 Jan 2016 17:33:56 +0000 (-0800) Subject: nir/spirv: Hanle continues that use SSA values from the loop body X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14ebd0fdd799d4b721633d25a08d966ee8069243;p=mesa.git 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. --- 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 *