On Sat, Jul 14, 2018 at 4:26 PM Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl>
wrote:

> Reinserting code directly before a jump means the block gets split
> and merged, removing the original block and replacing it in the
> process.
>
> Hence keeping a pointer to the continue block over a reinsert
> causes issues.
>
> This code changes nir_opt_if to simply look for the new continue
> block.
>
> CC: 18.1 <mesa-sta...@lists.freedesktop.org>
> ---
>  src/compiler/nir/nir_opt_if.c | 33 +++++++++++++++++++++++++++------
>  1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
> index a52de120ad6..658ff654169 100644
> --- a/src/compiler/nir/nir_opt_if.c
> +++ b/src/compiler/nir/nir_opt_if.c
> @@ -26,6 +26,28 @@
>  #include "nir_control_flow.h"
>  #include "nir_loop_analyze.h"
>
> +/**
> + * Gets the single block that jumps back to the loop header. Already
> assumes
> + * there is exactly one such block.
> + */
> +static nir_block* find_continue_block(nir_loop *loop)
>

The return type goes on its own line.


> +{
> +   nir_block *header_block = nir_loop_first_block(loop);
> +   nir_block *prev_block =
> +      nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
> +
> +   assert(header_block->predecessors->entries == 2);
> +
> +   nir_block *continue_block = NULL;
> +   struct set_entry *pred_entry;
> +   set_foreach(header_block->predecessors, pred_entry) {
> +      if (pred_entry->key != prev_block)
> +         continue_block = (void *)pred_entry->key;
>

Just return right here.  No need to keep looping or store continue_block
off in a variable.


> +   }
> +
> +   return continue_block;
>

Then this becomes unreachable.

With those nits fixed,

Reviewed-by: Jason Ekstrand <ja...@jlekstrand.net>


> +}
> +
>  /**
>   * This optimization detects if statements at the tops of loops where the
>   * condition is a phi node of two constants and moves half of the if to
> above
> @@ -97,12 +119,7 @@ opt_peel_loop_initial_if(nir_loop *loop)
>     if (header_block->predecessors->entries != 2)
>        return false;
>
> -   nir_block *continue_block = NULL;
> -   struct set_entry *pred_entry;
> -   set_foreach(header_block->predecessors, pred_entry) {
> -      if (pred_entry->key != prev_block)
> -         continue_block = (void *)pred_entry->key;
> -   }
> +   nir_block *continue_block = find_continue_block(loop);
>
>     nir_cf_node *if_node = nir_cf_node_next(&header_block->cf_node);
>     if (!if_node || if_node->type != nir_cf_node_if)
> @@ -193,6 +210,10 @@ opt_peel_loop_initial_if(nir_loop *loop)
>     nir_cf_reinsert(&tmp, nir_before_cf_node(&loop->cf_node));
>
>     nir_cf_reinsert(&header, nir_after_block_before_jump(continue_block));
> +
> +   /* Get continue block again as the previous reinsert might have
> removed the block. */
> +   continue_block = find_continue_block(loop);
> +
>     nir_cf_extract(&tmp, nir_before_cf_list(continue_list),
>                          nir_after_cf_list(continue_list));
>     nir_cf_reinsert(&tmp, nir_after_block_before_jump(continue_block));
> --
> 2.18.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to