summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-03-16 14:55:00 -0700
committerJason Ekstrand <[email protected]>2015-03-17 17:11:05 -0700
commit1be862c0c4965a0184908df736a30d354498ba3d (patch)
tree42c00f8b5eb2dc39488db3a86f51aa0595921f7f /src
parent8cf40ed05dbd3a62ee817e7ebc9409cf327c10ce (diff)
nir/peephole_select: Copy instructions into the block before the if
Previously we tried to do poor-man's copy propagation as we created the select instructions. Instead, this commit just moves the instructions from the blocks inside the if into the block before. Copy propagation will take care of making sure we don't have any extra mov's in there for us. Reviewed-by: Connor Abbott <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/nir/nir_opt_peephole_select.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/glsl/nir/nir_opt_peephole_select.c b/src/glsl/nir/nir_opt_peephole_select.c
index 837135046bd..c9512bd62c9 100644
--- a/src/glsl/nir/nir_opt_peephole_select.c
+++ b/src/glsl/nir/nir_opt_peephole_select.c
@@ -135,6 +135,25 @@ nir_opt_peephole_select_block(nir_block *block, void *void_state)
* selects.
*/
+ nir_block *prev_block = nir_cf_node_as_block(nir_cf_node_prev(prev_node));
+ assert(prev_block->cf_node.type == nir_cf_node_block);
+
+ /* First, we move the remaining instructions from the blocks to the
+ * block before. We have already guaranteed that this is safe by
+ * calling block_check_for_allowed_instrs()
+ */
+ nir_foreach_instr_safe(then_block, instr) {
+ exec_node_remove(&instr->node);
+ instr->block = prev_block;
+ exec_list_push_tail(&prev_block->instr_list, &instr->node);
+ }
+
+ nir_foreach_instr_safe(else_block, instr) {
+ exec_node_remove(&instr->node);
+ instr->block = prev_block;
+ exec_list_push_tail(&prev_block->instr_list, &instr->node);
+ }
+
nir_foreach_instr_safe(block, instr) {
if (instr->type != nir_instr_type_phi)
break;
@@ -151,19 +170,7 @@ nir_opt_peephole_select_block(nir_block *block, void *void_state)
assert(src->src.is_ssa);
unsigned idx = src->pred == then_block ? 1 : 2;
-
- if (src->src.ssa->parent_instr->block == src->pred) {
- /* We already know that this instruction must be a move with
- * this phi's in this block as its only users.
- */
- nir_alu_instr *mov = nir_instr_as_alu(src->src.ssa->parent_instr);
- assert(mov->instr.type == nir_instr_type_alu);
- assert(mov->op == nir_op_fmov || mov->op == nir_op_imov);
-
- nir_alu_src_copy(&sel->src[idx], &mov->src[0], state->mem_ctx);
- } else {
- nir_src_copy(&sel->src[idx].src, &src->src, state->mem_ctx);
- }
+ nir_src_copy(&sel->src[idx].src, &src->src, state->mem_ctx);
}
nir_ssa_dest_init(&sel->instr, &sel->dest.dest,