diff options
author | Kenneth Graunke <[email protected]> | 2016-08-24 21:33:16 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2016-08-25 19:18:24 -0700 |
commit | c2fd6b0f5d1c964fa63e72d6938721cba9597629 (patch) | |
tree | de8d2a1354cac6400bc4a6051b6a15959cf01ddc | |
parent | 3203fe3d509b6a0e44c82384fba1dcc4c8c43dc6 (diff) |
i965: Safely iterate the predecessors of the end block.
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 <[email protected]>
Reviewed-by: Connor Abbott <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_nir_tcs_workarounds.c | 23 |
1 files 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 6524b7dcb21..3f94f631f73 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]; + 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); |