From 0afe6e225406dfc8dd38767c5347935a9e19a13a Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Mon, 17 Mar 2025 13:11:20 +0000 Subject: [PATCH] pco: add helpers for finding non-empty blocks, apply Signed-off-by: Simon Perretta Acked-by: Erik Faye-Lund Part-of: --- src/imagination/pco/pco_internal.h | 50 ++++++++++++++++++++++------- src/imagination/pco/pco_trans_nir.c | 6 ++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index b5a437f3299..a5154ed9595 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -1351,6 +1351,42 @@ PCO_DEFINE_CF_ITER(loop, PCO_CF_NODE_TYPE_LOOP) #undef PCO_DEFINE_CF_ITER +/** + * \brief Returns the next non-empty block. + * + * \param[in] block The current block. + * \return The next non-empty block, or NULL if the end of the function has been + * reached. + */ +static inline pco_block *pco_next_block_nonempty(pco_block *block) +{ + block = pco_next_block(block); + + /* Skip over empty blocks. */ + while (block && exec_list_is_empty(&block->instrs)) + block = pco_next_block(block); + + return block; +} + +/** + * \brief Returns the previous non-empty block. + * + * \param[in] block The current block. + * \return The previous non-empty block, or NULL if the end of the function has + * been reached. + */ +static inline pco_block *pco_prev_block_nonempty(pco_block *block) +{ + block = pco_prev_block(block); + + /* Skip over empty blocks. */ + while (block && exec_list_is_empty(&block->instrs)) + block = pco_prev_block(block); + + return block; +} + /** * \brief Returns the first instruction in a block. * @@ -1389,12 +1425,7 @@ static inline pco_instr *pco_next_instr(pco_instr *instr) if (next_instr) return next_instr; - pco_block *block = pco_next_block(instr->parent_block); - - /* Skip over empty blocks. */ - while (block && exec_list_is_empty(&block->instrs)) - block = pco_next_block(block); - + pco_block *block = pco_next_block_nonempty(instr->parent_block); return !block ? NULL : pco_first_instr(block); } @@ -1414,12 +1445,7 @@ static inline pco_instr *pco_prev_instr(pco_instr *instr) if (prev_instr) return prev_instr; - pco_block *block = pco_prev_block(instr->parent_block); - - /* Skip over empty blocks. */ - while (block && exec_list_is_empty(&block->instrs)) - block = pco_prev_block(block); - + pco_block *block = pco_prev_block_nonempty(instr->parent_block); return !block ? NULL : pco_last_instr(block); } diff --git a/src/imagination/pco/pco_trans_nir.c b/src/imagination/pco/pco_trans_nir.c index a81ea6f0501..4787274457d 100644 --- a/src/imagination/pco/pco_trans_nir.c +++ b/src/imagination/pco/pco_trans_nir.c @@ -1536,6 +1536,12 @@ static unsigned try_collate_vec_srcs(trans_ctx *tctx, bool collated_vector = false; unsigned num_srcs_collated = 0; pco_instr *from = pco_cursor_instr(tctx->b.cursor); + if (!from) { + from = pco_last_instr( + pco_prev_block_nonempty(pco_cursor_block(tctx->b.cursor))); + } + + assert(from); for (unsigned s = 0; s < num_srcs; ++s) { pco_instr *parent_instr = find_parent_instr_from(src[s], from);