On Thu, Aug 25, 2016 at 1:25 AM, Kenneth Graunke <kenn...@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 <kenn...@whitecape.org> > Cc: Connor Abbott <cwabbo...@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 <cwabbo...@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 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev