From 46384d0dcceeae285dea5566e4c026c971dd8d01 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 18 Feb 2021 13:46:41 -0500 Subject: [PATCH] pan/bi: Fix more jumps to terminal blocks Here's another edge case: there could be instructions in the last block after NIR->BIR but they could be optimized out by backend DCE, causing the block to become a terminal block. Noticed while toying with geometry shaders. Fixes: a805d999c0e ("pan/bi: Fix jumps to terminal block again") Signed-off-by: Alyssa Rosenzweig Reviewed-by: Boris Brezillon Part-of: --- src/panfrost/bifrost/bifrost_compile.c | 7 +++++-- src/panfrost/bifrost/compiler.h | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 50782fb..baf67ff 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -2973,8 +2973,6 @@ bifrost_compile_shader_nir(nir_shader *nir, /* Name blocks now that we're done emitting so the order is * consistent */ block->base.name = block_source_count++; - - bi_lower_branch(block); } /* Runs before copy prop */ @@ -2993,6 +2991,11 @@ bifrost_compile_shader_nir(nir_shader *nir, } } while(progress); + bi_foreach_block(ctx, _block) { + bi_block *block = (bi_block *) _block; + bi_lower_branch(block); + } + if (bifrost_debug & BIFROST_DBG_SHADERS && !skip_internal) bi_print_shader(ctx, stdout); bi_schedule(ctx); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 4030fa4..809500c 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -777,12 +777,16 @@ unsigned bi_clause_quadwords(bi_clause *clause); signed bi_block_offset(bi_context *ctx, bi_clause *start, bi_block *target); bool bi_ec0_packed(unsigned tuple_count); +/* Check if there are no more instructions starting with a given block, this + * needs to recurse in case a shader ends with multiple empty blocks */ + static inline bool bi_is_terminal_block(bi_block *block) { - return block->base.successors[0] == NULL && - block->base.successors[1] == NULL && - list_is_empty(&block->base.instructions); + return (block == NULL) || + (list_is_empty(&block->base.instructions) && + bi_is_terminal_block((bi_block *) block->base.successors[0]) && + bi_is_terminal_block((bi_block *) block->base.successors[1])); } /* Code emit */ -- 2.7.4