nir: Allow to skip integer ops in nir_lower_to_source_mods
authorGert Wollny <gert.wollny@collabora.com>
Mon, 12 Nov 2018 08:17:34 +0000 (09:17 +0100)
committerGert Wollny <gw.fossdev@gmail.com>
Wed, 14 Nov 2018 07:59:26 +0000 (08:59 +0100)
Some hardware supports source mods only for float operations. Make it
possible to skip lowering to source mods in these cases.

v2: use option flags instead of a boolean (Jason Ekstrand)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir.h
src/compiler/nir/nir_lower_to_source_mods.c
src/intel/compiler/brw_nir.c

index c469e111b2c0df17ac84f8d6cbb82a30f07fba36..e542e08759df46e53d305d625f62e39b8825f988 100644 (file)
@@ -3017,7 +3017,15 @@ typedef struct nir_lower_bitmap_options {
 void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options);
 
 bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset);
-bool nir_lower_to_source_mods(nir_shader *shader);
+
+typedef enum  {
+   nir_lower_int_source_mods = 1 << 0,
+   nir_lower_float_source_mods = 1 << 1,
+   nir_lower_all_source_mods = (1 << 2) - 1
+} nir_lower_to_source_mods_flags;
+
+
+bool nir_lower_to_source_mods(nir_shader *shader, nir_lower_to_source_mods_flags options);
 
 bool nir_lower_gs_intrinsics(nir_shader *shader);
 
index 077ca53704f28d0b5063279cfa2c2a8438d5cba3..657bf8a3d71ea5afe99e1d0064fc0729ca65e1e9 100644 (file)
@@ -34,7 +34,8 @@
  */
 
 static bool
-nir_lower_to_source_mods_block(nir_block *block)
+nir_lower_to_source_mods_block(nir_block *block,
+                               nir_lower_to_source_mods_flags options)
 {
    bool progress = false;
 
@@ -58,10 +59,14 @@ nir_lower_to_source_mods_block(nir_block *block)
 
          switch (nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[i])) {
          case nir_type_float:
+            if (!(options & nir_lower_float_source_mods))
+               continue;
             if (parent->op != nir_op_fmov)
                continue;
             break;
          case nir_type_int:
+            if (!(options & nir_lower_int_source_mods))
+               continue;
             if (parent->op != nir_op_imov)
                continue;
             break;
@@ -97,33 +102,41 @@ nir_lower_to_source_mods_block(nir_block *block)
          progress = true;
       }
 
-      switch (alu->op) {
-      case nir_op_fsat:
-         alu->op = nir_op_fmov;
-         alu->dest.saturate = true;
-         break;
-      case nir_op_ineg:
-         alu->op = nir_op_imov;
-         alu->src[0].negate = !alu->src[0].negate;
-         break;
-      case nir_op_fneg:
-         alu->op = nir_op_fmov;
-         alu->src[0].negate = !alu->src[0].negate;
-         break;
-      case nir_op_iabs:
-         alu->op = nir_op_imov;
-         alu->src[0].abs = true;
-         alu->src[0].negate = false;
-         break;
-      case nir_op_fabs:
-         alu->op = nir_op_fmov;
-         alu->src[0].abs = true;
-         alu->src[0].negate = false;
-         break;
-      default:
-         break;
+      if (options & nir_lower_float_source_mods) {
+         switch (alu->op) {
+         case nir_op_fsat:
+            alu->op = nir_op_fmov;
+            alu->dest.saturate = true;
+            break;
+         case nir_op_fneg:
+            alu->op = nir_op_fmov;
+            alu->src[0].negate = !alu->src[0].negate;
+            break;
+         case nir_op_fabs:
+            alu->op = nir_op_fmov;
+            alu->src[0].abs = true;
+            alu->src[0].negate = false;
+            break;
+         default:
+            break;
+         }
       }
 
+      if (options & nir_lower_int_source_mods) {
+         switch (alu->op) {
+         case nir_op_ineg:
+            alu->op = nir_op_imov;
+            alu->src[0].negate = !alu->src[0].negate;
+            break;
+         case nir_op_iabs:
+            alu->op = nir_op_imov;
+            alu->src[0].abs = true;
+            alu->src[0].negate = false;
+            break;
+         default:
+            break;
+         }
+      }
       /* We've covered sources.  Now we're going to try and saturate the
        * destination if we can.
        */
@@ -136,6 +149,9 @@ nir_lower_to_source_mods_block(nir_block *block)
           nir_type_float)
          continue;
 
+      if (!(options & nir_lower_float_source_mods))
+         continue;
+
       if (!list_empty(&alu->dest.dest.ssa.if_uses))
          continue;
 
@@ -185,12 +201,13 @@ nir_lower_to_source_mods_block(nir_block *block)
 }
 
 static bool
-nir_lower_to_source_mods_impl(nir_function_impl *impl)
+nir_lower_to_source_mods_impl(nir_function_impl *impl,
+                              nir_lower_to_source_mods_flags options)
 {
    bool progress = false;
 
    nir_foreach_block(block, impl) {
-      progress |= nir_lower_to_source_mods_block(block);
+      progress |= nir_lower_to_source_mods_block(block, options);
    }
 
    if (progress)
@@ -201,13 +218,14 @@ nir_lower_to_source_mods_impl(nir_function_impl *impl)
 }
 
 bool
-nir_lower_to_source_mods(nir_shader *shader)
+nir_lower_to_source_mods(nir_shader *shader,
+                         nir_lower_to_source_mods_flags options)
 {
    bool progress = false;
 
    nir_foreach_function(function, shader) {
       if (function->impl) {
-         progress |= nir_lower_to_source_mods_impl(function->impl);
+         progress |= nir_lower_to_source_mods_impl(function->impl, options);
       }
    }
 
index 80fa5a1a81fdde21f9a8ef3335795e8bd39e8f50..10b03ef2fba3afea54fd2d1e01342a85b4663632 100644 (file)
@@ -796,7 +796,7 @@ brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler,
 
    OPT(nir_opt_algebraic_late);
 
-   OPT(nir_lower_to_source_mods);
+   OPT(nir_lower_to_source_mods, nir_lower_all_source_mods);
    OPT(nir_copy_prop);
    OPT(nir_opt_dce);
    OPT(nir_opt_move_comparisons);