diff --git a/src/panfrost/bifrost/bi_opt_dce.c b/src/panfrost/bifrost/bi_opt_dce.c index a86bb7740e6..517ff11fcc3 100644 --- a/src/panfrost/bifrost/bi_opt_dce.c +++ b/src/panfrost/bifrost/bi_opt_dce.c @@ -25,8 +25,16 @@ #include "compiler.h" #include "util/u_memory.h" +/* A simple liveness-based dead code elimination pass. In 'soft' mode, dead + * instructions are kept but write to null, which is required for correct + * operation post-schedule pass (where dead instructions correspond to + * instructions whose destinations are consumed immediately as a passthrough + * register. If the destinations are not garbage collected, impossible register + * encodings will result.) + */ + bool -bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block) +bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block, bool soft) { bool progress = false; unsigned temp_count = bi_max_temp(ctx); @@ -40,7 +48,11 @@ bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block) unsigned index = bi_get_node(ins->dest[0]); if (index < temp_count && !live[index]) { - bi_remove_instruction(ins); + if (soft) + ins->dest[0] = bi_null(); + else + bi_remove_instruction(ins); + progress |= true; } diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 03c8f76d620..6e34ab74061 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -2389,7 +2389,7 @@ bifrost_compile_shader_nir(void *mem_ctx, nir_shader *nir, bi_foreach_block(ctx, _block) { bi_block *block = (bi_block *) _block; - progress |= bi_opt_dead_code_eliminate(ctx, block); + progress |= bi_opt_dead_code_eliminate(ctx, block, false); } } while(progress); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index fb5204519f7..db8da729b69 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -703,7 +703,7 @@ void bi_print_shader(bi_context *ctx, FILE *fp); /* BIR passes */ -bool bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block); +bool bi_opt_dead_code_eliminate(bi_context *ctx, bi_block *block, bool soft); void bi_schedule(bi_context *ctx); void bi_register_allocate(bi_context *ctx);