diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 29 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_cfg.c | 2 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_private.h | 3 |
3 files changed, 26 insertions, 8 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index c58cf5cbfdf..2c4f5b0c93e 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -1394,8 +1394,11 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode, const uint32_t *w, unsigned count) { struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type; - struct nir_function *callee = - vtn_value(b, w[3], vtn_value_type_function)->func->impl->function; + struct vtn_function *vtn_callee = + vtn_value(b, w[3], vtn_value_type_function)->func; + struct nir_function *callee = vtn_callee->impl->function; + + vtn_callee->referenced = true; nir_call_instr *call = nir_call_instr_create(b->nb.shader, callee); for (unsigned i = 0; i < call->num_params; i++) { @@ -3366,12 +3369,22 @@ spirv_to_nir(const uint32_t *words, size_t word_count, vtn_build_cfg(b, words, word_end); - foreach_list_typed(struct vtn_function, func, node, &b->functions) { - b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer, - _mesa_key_pointer_equal); - - vtn_function_emit(b, func, vtn_handle_body_instruction); - } + assert(b->entry_point->value_type == vtn_value_type_function); + b->entry_point->func->referenced = true; + + bool progress; + do { + progress = false; + foreach_list_typed(struct vtn_function, func, node, &b->functions) { + if (func->referenced && !func->emitted) { + b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer, + _mesa_key_pointer_equal); + + vtn_function_emit(b, func, vtn_handle_body_instruction); + progress = true; + } + } + } while (progress); assert(b->entry_point->value_type == vtn_value_type_function); nir_function *entry_point = b->entry_point->func->impl->function; diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index 13f02217710..70bbccb7cdd 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -783,4 +783,6 @@ vtn_function_emit(struct vtn_builder *b, struct vtn_function *func, */ if (b->has_loop_continue) nir_repair_ssa_impl(func->impl); + + func->emitted = true; } diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 173a7b3d7c7..751f5011b7d 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -159,6 +159,9 @@ struct vtn_block { struct vtn_function { struct exec_node node; + bool referenced; + bool emitted; + nir_function_impl *impl; struct vtn_block *start_block; |