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 <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12163>
This commit is contained in:
Bas Nieuwenhuizen 2021-07-26 17:05:20 +02:00 committed by Marge Bot
parent fa6cd6e00d
commit aa8179e33f
1 changed files with 20 additions and 7 deletions

View File

@ -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, &copy->locals);
exec_list_append(&b->impl->registers, &copy->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, &copy->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);