[Mesa-dev] [PATCH] i965: Safely iterate the predecessors of the end block.
Connor Abbott
cwabbott0 at gmail.com
Thu Aug 25 05:50:01 UTC 2016
On Thu, Aug 25, 2016 at 1:25 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> We want to insert code in each of the predecessors of the end block.
> This code includes a nir_if, which would split the block, altering
> the set. To avoid that, I emitted a dead constant at the end of each
> block before splitting it, so that the set of predecessors remained
> unchanged. This was admittedly ugly.
>
> Connor suggested instead saving a copy of the set, so we can iterate
> it safely. This is also a little ugly, but a much better plan.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> Cc: Connor Abbott <cwabbott0 at gmail.com>
> ---
> .../drivers/dri/i965/brw_nir_tcs_workarounds.c | 23 +++++++++++++---------
> 1 file changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c b/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c
> index 6524b7d..3f94f63 100644
> --- a/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c
> +++ b/src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c
> @@ -102,14 +102,7 @@ store_output(nir_builder *b, nir_ssa_def *value, int offset, unsigned comps)
> static void
> emit_quads_workaround(nir_builder *b, nir_block *block)
> {
> - /* We're going to insert a new if-statement in a predecessor of the end
> - * block. This would normally create a new block (after the if) which
> - * would then become the predecessor of the end block, causing our set
> - * walking to get screwed up. To avoid this, just emit a constant at
> - * the end of our current block, and insert the if before that.
> - */
> b->cursor = nir_after_block_before_jump(block);
> - b->cursor = nir_before_instr(nir_imm_int(b, 0)->parent_instr);
>
> nir_ssa_def *inner = load_output(b, 2, 0);
> nir_ssa_def *outer = load_output(b, 4, 1);
> @@ -139,10 +132,22 @@ brw_nir_apply_tcs_quads_workaround(nir_shader *nir)
> nir_builder b;
> nir_builder_init(&b, impl);
>
> + /* emit_quads_workaround() inserts an if statement into each block,
> + * which splits it in two. This changes the set of predecessors of
> + * the end block. We want to process the original set, so to be safe,
> + * save it off to an array first.
> + */
> + const unsigned num_end_preds = impl->end_block->predecessors->entries;
> + nir_block *end_preds[num_end_preds];
I think we need to use NIR_VLA here to make MSVC happy. Otherwise,
Reviewed-by: Connor Abbott <cwabbott0 at gmail.com>
> + unsigned i = 0;
> struct set_entry *entry;
> +
> set_foreach(impl->end_block->predecessors, entry) {
> - nir_block *pred = (nir_block *) entry->key;
> - emit_quads_workaround(&b, pred);
> + end_preds[i++] = (nir_block *) entry->key;
> + }
> +
> + for (i = 0; i < num_end_preds; i++) {
> + emit_quads_workaround(&b, end_preds[i]);
> }
>
> nir_metadata_preserve(impl, 0);
> --
> 2.9.3
>
More information about the mesa-dev
mailing list