diff --git a/src/panfrost/bifrost/bi_opt_copy_prop.c b/src/panfrost/bifrost/bi_opt_copy_prop.c index 4601e1230f6..06b0e41e82f 100644 --- a/src/panfrost/bifrost/bi_opt_copy_prop.c +++ b/src/panfrost/bifrost/bi_opt_copy_prop.c @@ -40,16 +40,26 @@ bi_word_node(bi_index idx) return (idx.value << 2) | idx.offset; } -bool +void bi_opt_copy_prop(bi_context *ctx) { - bool progress = false; - bi_index *replacement = calloc(sizeof(bi_index), ((ctx->ssa_alloc + 1) << 2)); bi_foreach_instr_global_safe(ctx, ins) { - if (bi_is_copy(ins)) - replacement[bi_word_node(ins->dest[0])] = ins->src[0]; + if (bi_is_copy(ins)) { + bi_index replace = ins->src[0]; + + /* Peek through one layer so copyprop converges in one + * iteration for chained moves */ + if (bi_is_ssa(replace)) { + bi_index chained = replacement[bi_word_node(replace)]; + + if (!bi_is_null(chained)) + replace = chained; + } + + replacement[bi_word_node(ins->dest[0])] = replace; + } bi_foreach_src(ins, s) { bi_index use = ins->src[s]; @@ -65,5 +75,4 @@ bi_opt_copy_prop(bi_context *ctx) } free(replacement); - return progress; } diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index dec42ca8a99..26ed1b53d1e 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -3035,13 +3035,13 @@ bifrost_compile_shader_nir(nir_shader *nir, /* Runs before copy prop */ bi_opt_push_ubo(ctx); + bi_opt_copy_prop(ctx); bool progress = false; do { progress = false; - progress |= bi_opt_copy_prop(ctx); progress |= bi_opt_dead_code_eliminate(ctx, false); } while(progress); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 04b69339bda..d082a09949d 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -744,7 +744,7 @@ void bi_print_shader(bi_context *ctx, FILE *fp); /* BIR passes */ -bool bi_opt_copy_prop(bi_context *ctx); +void bi_opt_copy_prop(bi_context *ctx); bool bi_opt_dead_code_eliminate(bi_context *ctx, bool soft); void bi_opt_push_ubo(bi_context *ctx); void bi_schedule(bi_context *ctx);