[Mesa-dev] [PATCH v2 04/10] nir/alu_to_scalar: Use the nir_pass framework internally

Jason Ekstrand jason at jlekstrand.net
Tue Nov 3 13:41:10 PST 2015


Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>
---
 src/glsl/nir/nir.h                     |  3 +-
 src/glsl/nir/nir_lower_alu_to_scalar.c | 57 ++++++++++++++++++++--------------
 2 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index f2d01e9..b18f1d6 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1599,6 +1599,8 @@ bool nir_function_impl_run_pass(nir_function_impl *impl, const nir_pass *pass,
       return nir_shader_run_pass(shader, &name##_pass, NULL); \
    }
 
+NIR_DECL_PASS(nir_lower_alu_to_scalar)
+
 nir_shader *nir_shader_create(void *mem_ctx,
                               gl_shader_stage stage,
                               const nir_shader_compiler_options *options);
@@ -1942,7 +1944,6 @@ bool nir_remove_dead_variables(nir_shader *shader);
 
 void nir_move_vec_src_uses_to_dest(nir_shader *shader);
 bool nir_lower_vec_to_movs(nir_shader *shader);
-void nir_lower_alu_to_scalar(nir_shader *shader);
 void nir_lower_load_const_to_scalar(nir_shader *shader);
 
 void nir_lower_phis_to_scalar(nir_shader *shader);
diff --git a/src/glsl/nir/nir_lower_alu_to_scalar.c b/src/glsl/nir/nir_lower_alu_to_scalar.c
index 9313fc0..4fec1ce 100644
--- a/src/glsl/nir/nir_lower_alu_to_scalar.c
+++ b/src/glsl/nir/nir_lower_alu_to_scalar.c
@@ -30,6 +30,11 @@
  * arguments with individual per-channel operations.
  */
 
+struct alu_to_scalar_state {
+   nir_builder builder;
+   bool progress;
+};
+
 static void
 nir_alu_ssa_dest_init(nir_alu_instr *instr, unsigned num_components)
 {
@@ -70,7 +75,7 @@ lower_reduction(nir_alu_instr *instr, nir_op chan_op, nir_op merge_op,
    nir_instr_remove(&instr->instr);
 }
 
-static void
+static bool
 lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
 {
    unsigned num_src = nir_op_infos[instr->op].num_inputs;
@@ -86,7 +91,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
    case name##3: \
    case name##4: \
       lower_reduction(instr, chan, merge, b); \
-      return;
+      return true;
 
    switch (instr->op) {
    case nir_op_vec4:
@@ -95,7 +100,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
       /* We don't need to scalarize these ops, they're the ones generated to
        * group up outputs into a value that can be SSAed.
        */
-      return;
+      return false;
 
    case nir_op_unpack_unorm_4x8:
    case nir_op_unpack_snorm_4x8:
@@ -104,13 +109,13 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
       /* There is no scalar version of these ops, unless we were to break it
        * down to bitshifts and math (which is definitely not intended).
        */
-      return;
+      return false;
 
    case nir_op_unpack_half_2x16:
       /* We could split this into unpack_half_2x16_split_[xy], but should
        * we?
        */
-      return;
+      return false;
 
    case nir_op_fdph: {
       nir_ssa_def *sum[4];
@@ -127,7 +132,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
 
       nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(val));
       nir_instr_remove(&instr->instr);
-      return;
+      return true;
    }
 
       LOWER_REDUCTION(nir_op_fdot, nir_op_fmul, nir_op_fadd);
@@ -147,7 +152,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
    }
 
    if (instr->dest.dest.ssa.num_components == 1)
-      return;
+      return false;
 
    unsigned num_components = instr->dest.dest.ssa.num_components;
    nir_ssa_def *comps[] = { NULL, NULL, NULL, NULL };
@@ -182,33 +187,39 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
    nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(vec));
 
    nir_instr_remove(&instr->instr);
+
+   return true;
 }
 
 static bool
-lower_alu_to_scalar_block(nir_block *block, void *builder)
+lower_alu_to_scalar_block(nir_block *block, void *void_state)
 {
+   struct alu_to_scalar_state *state = void_state;
+
    nir_foreach_instr_safe(block, instr) {
-      if (instr->type == nir_instr_type_alu)
-         lower_alu_instr_scalar(nir_instr_as_alu(instr), builder);
+      if (instr->type == nir_instr_type_alu) {
+         if (lower_alu_instr_scalar(nir_instr_as_alu(instr), &state->builder))
+            state->progress = true;
+      }
    }
 
    return true;
 }
 
-static void
-nir_lower_alu_to_scalar_impl(nir_function_impl *impl)
+static bool
+nir_lower_alu_to_scalar_impl(nir_function_impl *impl, void *unused)
 {
-   nir_builder builder;
-   nir_builder_init(&builder, impl);
+   struct alu_to_scalar_state state;
 
-   nir_foreach_block(impl, lower_alu_to_scalar_block, &builder);
-}
+   nir_builder_init(&state.builder, impl);
+   state.progress = false;
 
-void
-nir_lower_alu_to_scalar(nir_shader *shader)
-{
-   nir_foreach_overload(shader, overload) {
-      if (overload->impl)
-         nir_lower_alu_to_scalar_impl(overload->impl);
-   }
+   nir_foreach_block(impl, lower_alu_to_scalar_block, &state);
+
+   return state.progress;
 }
+
+const nir_pass nir_lower_alu_to_scalar_pass = {
+   .impl_pass_func = nir_lower_alu_to_scalar_impl,
+   .metadata_preserved = nir_metadata_block_index | nir_metadata_dominance,
+};
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list