i965/vec4: split VEC4_OPCODE_FROM_DOUBLE into one opcode per destination's type
[mesa.git] / src / compiler / nir / nir_lower_phis_to_scalar.c
index 026c8665f91dcc856c03d34f202ace24605b07e9..b12718f27327c01abfe3e07726c1ca46554b9fa1 100644 (file)
@@ -146,7 +146,7 @@ should_lower_phi(nir_phi_instr *phi, struct lower_phis_to_scalar_state *state)
 
    bool scalarizable = true;
 
-   nir_foreach_phi_src(phi, src) {
+   nir_foreach_phi_src(src, phi) {
       scalarizable = is_phi_src_scalarizable(src, state);
       if (!scalarizable)
          break;
@@ -163,13 +163,14 @@ should_lower_phi(nir_phi_instr *phi, struct lower_phis_to_scalar_state *state)
 }
 
 static bool
-lower_phis_to_scalar_block(nir_block *block, void *void_state)
+lower_phis_to_scalar_block(nir_block *block,
+                           struct lower_phis_to_scalar_state *state)
 {
-   struct lower_phis_to_scalar_state *state = void_state;
+   bool progress = false;
 
    /* Find the last phi node in the block */
    nir_phi_instr *last_phi = NULL;
-   nir_foreach_instr(block, instr) {
+   nir_foreach_instr(instr, block) {
       if (instr->type != nir_instr_type_phi)
          break;
 
@@ -179,7 +180,7 @@ lower_phis_to_scalar_block(nir_block *block, void *void_state)
    /* We have to handle the phi nodes in their own pass due to the way
     * we're modifying the linked list of instructions.
     */
-   nir_foreach_instr_safe(block, instr) {
+   nir_foreach_instr_safe(instr, block) {
       if (instr->type != nir_instr_type_phi)
          break;
 
@@ -215,7 +216,7 @@ lower_phis_to_scalar_block(nir_block *block, void *void_state)
 
          vec->src[i].src = nir_src_for_ssa(&new_phi->dest.ssa);
 
-         nir_foreach_phi_src(phi, src) {
+         nir_foreach_phi_src(src, phi) {
             /* We need to insert a mov to grab the i'th component of src */
             nir_alu_instr *mov = nir_alu_instr_create(state->mem_ctx,
                                                       nir_op_imov);
@@ -249,6 +250,8 @@ lower_phis_to_scalar_block(nir_block *block, void *void_state)
       ralloc_steal(state->dead_ctx, phi);
       nir_instr_remove(&phi->instr);
 
+      progress = true;
+
       /* We're using the safe iterator and inserting all the newly
        * scalarized phi nodes before their non-scalarized version so that's
        * ok.  However, we are also inserting vec operations after all of
@@ -259,25 +262,29 @@ lower_phis_to_scalar_block(nir_block *block, void *void_state)
          break;
    }
 
-   return true;
+   return progress;
 }
 
-static void
+static bool
 lower_phis_to_scalar_impl(nir_function_impl *impl)
 {
    struct lower_phis_to_scalar_state state;
+   bool progress = false;
 
    state.mem_ctx = ralloc_parent(impl);
    state.dead_ctx = ralloc_context(NULL);
    state.phi_table = _mesa_hash_table_create(state.dead_ctx, _mesa_hash_pointer,
                                              _mesa_key_pointer_equal);
 
-   nir_foreach_block(impl, lower_phis_to_scalar_block, &state);
+   nir_foreach_block(block, impl) {
+      progress = lower_phis_to_scalar_block(block, &state) || progress;
+   }
 
    nir_metadata_preserve(impl, nir_metadata_block_index |
                                nir_metadata_dominance);
 
    ralloc_free(state.dead_ctx);
+   return progress;
 }
 
 /** A pass that lowers vector phi nodes to scalar
@@ -287,11 +294,15 @@ lower_phis_to_scalar_impl(nir_function_impl *impl)
  * instance, if one of the sources is a non-scalarizable vector, then we
  * don't bother lowering because that would generate hard-to-coalesce movs.
  */
-void
+bool
 nir_lower_phis_to_scalar(nir_shader *shader)
 {
-   nir_foreach_function(shader, function) {
+   bool progress = false;
+
+   nir_foreach_function(function, shader) {
       if (function->impl)
-         lower_phis_to_scalar_impl(function->impl);
+         progress = lower_phis_to_scalar_impl(function->impl) || progress;
    }
+
+   return progress;
 }