From 79eb57de937da58a97286daa76f3c356d9cc5dbe Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Thu, 15 Aug 2024 08:46:36 +0200 Subject: [PATCH] nir/opt_vectorize: process blocks in source-code order To handle phi nodes, it's important that all sources have been processed before processing the phi node itself. The current traversal order (depth-first on dom_children) does not guarantee this. This patch rewrites the pass to visit blocks in source-code order. Signed-off-by: Job Noorman Reviewed-by: Connor Abbott Part-of: --- src/compiler/nir/nir_opt_vectorize.c | 44 ++++++++++++---------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/compiler/nir/nir_opt_vectorize.c b/src/compiler/nir/nir_opt_vectorize.c index e686dd12a4b..3cd31db3fa8 100644 --- a/src/compiler/nir/nir_opt_vectorize.c +++ b/src/compiler/nir/nir_opt_vectorize.c @@ -342,6 +342,17 @@ vec_instr_set_add_or_rewrite(struct set *instr_set, nir_instr *instr, struct set_entry *entry = _mesa_set_search(instr_set, instr); if (entry) { nir_instr *old_instr = (nir_instr *)entry->key; + + /* We cannot combine the instructions if the old one doesn't dominate + * the new one. Since we will never encounter a block again that is + * dominated by the old instruction, overwrite it with the new one in + * the instruction set. + */ + if (!nir_block_dominates(old_instr->block, instr->block)) { + entry->key = instr; + return false; + } + _mesa_set_remove(instr_set, entry); nir_instr *new_instr = instr_try_combine(instr_set, old_instr, instr); if (new_instr) { @@ -355,30 +366,6 @@ vec_instr_set_add_or_rewrite(struct set *instr_set, nir_instr *instr, return false; } -static bool -vectorize_block(nir_block *block, struct set *instr_set, - nir_vectorize_cb filter, void *data) -{ - bool progress = false; - - nir_foreach_instr_safe(instr, block) { - if (vec_instr_set_add_or_rewrite(instr_set, instr, filter, data)) - progress = true; - } - - for (unsigned i = 0; i < block->num_dom_children; i++) { - nir_block *child = block->dom_children[i]; - progress |= vectorize_block(child, instr_set, filter, data); - } - - nir_foreach_instr_reverse(instr, block) { - if (instr_can_rewrite(instr)) - _mesa_set_remove_key(instr_set, instr); - } - - return progress; -} - static bool nir_opt_vectorize_impl(nir_function_impl *impl, nir_vectorize_cb filter, void *data) @@ -387,8 +374,13 @@ nir_opt_vectorize_impl(nir_function_impl *impl, nir_metadata_require(impl, nir_metadata_dominance); - bool progress = vectorize_block(nir_start_block(impl), instr_set, - filter, data); + bool progress = false; + + nir_foreach_block(block, impl) { + nir_foreach_instr_safe(instr, block) { + progress |= vec_instr_set_add_or_rewrite(instr_set, instr, filter, data); + } + } if (progress) { nir_metadata_preserve(impl, nir_metadata_control_flow);