From 1be862c0c4965a0184908df736a30d354498ba3d Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 16 Mar 2015 14:55:00 -0700 Subject: [PATCH] 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 --- src/glsl/nir/nir_opt_peephole_select.c | 33 ++++++++++++++++++++------------- 1 file 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 8371350..c9512bd 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, -- 2.7.4