pan/bi: Fix more jumps to terminal blocks
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 18 Feb 2021 18:46:41 +0000 (13:46 -0500)
committerMarge Bot <eric+marge@anholt.net>
Mon, 22 Feb 2021 17:12:55 +0000 (17:12 +0000)
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 <alyssa.rosenzweig@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9137>

src/panfrost/bifrost/bifrost_compile.c
src/panfrost/bifrost/compiler.h

index 50782fb..baf67ff 100644 (file)
@@ -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);
index 4030fa4..809500c 100644 (file)
@@ -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 */