From aa8179e33f8b1fce5dd0a1df3cc265cc3e3d9cbd Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 26 Jul 2021 17:05:20 +0200 Subject: [PATCH] nir/inline_functions: Handle halting functions. Without this stitch_blocks complains about ending in a jump with a non-empty block after the inserted body. I hit this with CTS raytracing tests where we tried to inline a function that basically ended up being something like { ignore_ray_intersection halt } I kept the nop path when possible as that does not leave a mess for the optimization loop to optimize. Reviewed-by: Rhys Perry Part-of: --- src/compiler/nir/nir_inline_functions.c | 27 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/compiler/nir/nir_inline_functions.c b/src/compiler/nir/nir_inline_functions.c index b1399897be5..eba53d06029 100644 --- a/src/compiler/nir/nir_inline_functions.c +++ b/src/compiler/nir/nir_inline_functions.c @@ -26,6 +26,12 @@ #include "nir_control_flow.h" #include "nir_vla.h" +static bool function_ends_in_jump(nir_function_impl *impl) +{ + nir_block *last_block = nir_impl_last_block(impl); + return nir_block_ends_in_jump(last_block); +} + void nir_inline_function_impl(struct nir_builder *b, const nir_function_impl *impl, nir_ssa_def **params, @@ -33,11 +39,6 @@ void nir_inline_function_impl(struct nir_builder *b, { nir_function_impl *copy = nir_function_impl_clone(b->shader, impl); - /* Insert a nop at the cursor so we can keep track of where things are as - * we add/remove stuff from the CFG. - */ - nir_intrinsic_instr *nop = nir_nop(b); - exec_list_append(&b->impl->locals, ©->locals); exec_list_append(&b->impl->registers, ©->registers); @@ -104,12 +105,24 @@ void nir_inline_function_impl(struct nir_builder *b, } } + bool nest_if = function_ends_in_jump(copy); + /* Pluck the body out of the function and place it here */ nir_cf_list body; nir_cf_list_extract(&body, ©->body); - nir_cf_reinsert(&body, nir_before_instr(&nop->instr)); - b->cursor = nir_instr_remove(&nop->instr); + if (nest_if) { + nir_if *cf = nir_push_if(b, nir_imm_bool(b, true)); + nir_cf_reinsert(&body, nir_after_cf_list(&cf->then_list)); + nir_pop_if(b, cf); + } else { + /* Insert a nop at the cursor so we can keep track of where things are as + * we add/remove stuff from the CFG. + */ + nir_intrinsic_instr *nop = nir_nop(b); + nir_cf_reinsert(&body, nir_before_instr(&nop->instr)); + b->cursor = nir_instr_remove(&nop->instr); + } } static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);