OSDN Git Service

nir/peephole_select: Copy instructions into the block before the if
authorJason Ekstrand <jason.ekstrand@intel.com>
Mon, 16 Mar 2015 21:55:00 +0000 (14:55 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 18 Mar 2015 00:11:05 +0000 (17:11 -0700)
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 <cwabbott0@gmail.com>
src/glsl/nir/nir_opt_peephole_select.c

index 8371350..c9512bd 100644 (file)
@@ -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,