nir: Copy-propagate vecN operations that are actually moves
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 20 Feb 2015 01:19:22 +0000 (17:19 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 23 Feb 2015 21:19:05 +0000 (13:19 -0800)
We were already do this for ALU operations but we haven't for non-ALU
operations.  This changes that.

total NIR instructions in shared programs: 2039883 -> 2022338 (-0.86%)
NIR instructions in affected programs:     1768850 -> 1751305 (-0.99%)
helped:                                    14244
HURT:                                      124

total FS instructions in shared programs: 4083960 -> 4084036 (0.00%)
FS instructions in affected programs:     7302 -> 7378 (1.04%)
helped:                                   12
HURT:                                     51

Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/nir/nir_opt_copy_propagate.c

index dd0ec01efd63add5901aa0202902682ae9b4b260..ee78e5aa09db7215f65af9abc31ada25429364a3 100644 (file)
@@ -53,22 +53,6 @@ static bool is_move(nir_alu_instr *instr)
 
 }
 
-static bool
-is_swizzleless_move(nir_alu_instr *instr)
-{
-   if (!is_move(instr))
-      return false;
-
-   for (unsigned i = 0; i < 4; i++) {
-      if (!((instr->dest.write_mask >> i) & 1))
-         break;
-      if (instr->src[0].swizzle[i] != i)
-         return false;
-   }
-
-   return true;
-}
-
 static bool is_vec(nir_alu_instr *instr)
 {
    for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
@@ -80,6 +64,35 @@ static bool is_vec(nir_alu_instr *instr)
           instr->op == nir_op_vec4;
 }
 
+static bool
+is_swizzleless_move(nir_alu_instr *instr)
+{
+   if (is_move(instr)) {
+      for (unsigned i = 0; i < 4; i++) {
+         if (!((instr->dest.write_mask >> i) & 1))
+            break;
+         if (instr->src[0].swizzle[i] != i)
+            return false;
+      }
+      return true;
+   } else if (is_vec(instr)) {
+      nir_ssa_def *def = NULL;
+      for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
+         if (instr->src[i].swizzle[0] != i)
+            return false;
+
+         if (def == NULL) {
+            def = instr->src[i].src.ssa;
+         } else if (instr->src[i].src.ssa != def) {
+            return false;
+         }
+      }
+      return true;
+   } else {
+      return false;
+   }
+}
+
 typedef struct {
    nir_ssa_def *def;
    bool found;