nir: Skip emitting no-op movs from the builder.
authorEric Anholt <eric@anholt.net>
Mon, 16 Sep 2019 21:34:20 +0000 (14:34 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 4 Oct 2019 19:15:01 +0000 (19:15 +0000)
Having passes generate these is just making more work for copy
propagation (and thus probably calling more optimization passes)
later.  Noticed while trying to debug nir_opt_algebraic()
top-to-bottom having O(n^2) behavior due to not finding new matches in
replacement code.

Reviewed-by: Ian Romanick <ian.d.romainck@intel.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/compiler/nir/nir_builder.h
src/compiler/nir/nir_search.c

index 0f300aef15563b9a1a74b942b742a403acf45317..cad0e133cbfcd4d7eea391e64dee227009a019d2 100644 (file)
@@ -458,6 +458,16 @@ static inline nir_ssa_def *
 nir_mov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
 {
    assert(!src.abs && !src.negate);
+   if (src.src.is_ssa && src.src.ssa->num_components == num_components) {
+      bool any_swizzles = false;
+      for (unsigned i = 0; i < num_components; i++) {
+         if (src.swizzle[i] != i)
+            any_swizzles = true;
+      }
+      if (!any_swizzles)
+         return src.src.ssa;
+   }
+
    nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov);
    nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components,
                      nir_src_bit_size(src.src), NULL);
index eb7249cfdecf27e09aae3237eb4ecb7bcee2c46d..de5a8d25adaf6372db4664cdcf9e2c3484559867 100644 (file)
@@ -673,9 +673,8 @@ nir_replace_instr(nir_builder *build, nir_alu_instr *instr,
                                      instr->dest.dest.ssa.bit_size,
                                      &state, &instr->instr);
 
-   /* Inserting a mov may be unnecessary.  However, it's much easier to
-    * simply let copy propagation clean this up than to try to go through
-    * and rewrite swizzles ourselves.
+   /* Note that NIR builder will elide the MOV if it's a no-op, which may
+    * allow more work to be done in a single pass through algebraic.
     */
    nir_ssa_def *ssa_val =
       nir_mov_alu(build, val, instr->dest.dest.ssa.num_components);