<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Fri, Sep 14, 2018 at 10:45 PM Caio Marcelo de Oliveira Filho <<a href="mailto:caio.oliveira@intel.com">caio.oliveira@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Add basic helpers for doing tests on the vars related optimization<br>
passes.  The main goal is to lower the barrier to create tests during<br>
development and debugging of the passes.  Full coverage is not a<br>
requirement.<br>
---<br>
 src/compiler/<a href="http://Makefile.nir.am" rel="noreferrer" target="_blank">Makefile.nir.am</a>          |  34 +++--<br>
 src/compiler/nir/meson.build          |  11 ++<br>
 src/compiler/nir/tests/vars_tests.cpp | 199 ++++++++++++++++++++++++++<br>
 3 files changed, 233 insertions(+), 11 deletions(-)<br>
 create mode 100644 src/compiler/nir/tests/vars_tests.cpp<br>
<br>
diff --git a/src/compiler/<a href="http://Makefile.nir.am" rel="noreferrer" target="_blank">Makefile.nir.am</a> b/src/compiler/<a href="http://Makefile.nir.am" rel="noreferrer" target="_blank">Makefile.nir.am</a><br>
index 4ccd7f36be9..c646c6bdc1e 100644<br>
--- a/src/compiler/<a href="http://Makefile.nir.am" rel="noreferrer" target="_blank">Makefile.nir.am</a><br>
+++ b/src/compiler/<a href="http://Makefile.nir.am" rel="noreferrer" target="_blank">Makefile.nir.am</a><br>
@@ -60,25 +60,37 @@ nir/nir_opt_algebraic.c: nir/nir_opt_algebraic.py nir/nir_algebraic.py<br>
        $(MKDIR_GEN)<br>
        $(PYTHON_GEN) $(srcdir)/nir/nir_opt_algebraic.py > $@ || ($(RM) $@; false)<br>
<br>
-check_PROGRAMS += nir/tests/control_flow_tests<br>
+check_PROGRAMS += \<br>
+       nir/tests/control_flow_tests \<br>
+       nir/tests/vars_tests<br>
<br>
-nir_tests_control_flow_tests_CPPFLAGS = \<br>
+NIR_TESTS_CPPFLAGS = \<br>
        $(AM_CPPFLAGS) \<br>
        -I$(top_builddir)/src/compiler/nir \<br>
        -I$(top_srcdir)/src/compiler/nir<br>
-<br>
-nir_tests_control_flow_tests_SOURCES =                 \<br>
-       nir/tests/control_flow_tests.cpp<br>
-nir_tests_control_flow_tests_CFLAGS =                  \<br>
+NIR_TESTS_CFLAGS = \<br>
        $(PTHREAD_CFLAGS)<br>
-nir_tests_control_flow_tests_LDADD =                   \<br>
-       $(top_builddir)/src/gtest/<a href="http://libgtest.la" rel="noreferrer" target="_blank">libgtest.la</a>           \<br>
-       nir/<a href="http://libnir.la" rel="noreferrer" target="_blank">libnir.la</a>   \<br>
-       $(top_builddir)/src/util/<a href="http://libmesautil.la" rel="noreferrer" target="_blank">libmesautil.la</a>         \<br>
+NIR_TESTS_LDADD = \<br>
+       $(top_builddir)/src/gtest/<a href="http://libgtest.la" rel="noreferrer" target="_blank">libgtest.la</a> \<br>
+       nir/<a href="http://libnir.la" rel="noreferrer" target="_blank">libnir.la</a> \<br>
+       $(top_builddir)/src/util/<a href="http://libmesautil.la" rel="noreferrer" target="_blank">libmesautil.la</a> \<br>
        $(PTHREAD_LIBS)<br>
<br>
<br>
-TESTS += nir/tests/control_flow_tests<br>
+nir_tests_control_flow_tests_CPPFLAGS = $(NIR_TESTS_CPPFLAGS)<br>
+nir_tests_control_flow_tests_SOURCES = nir/tests/control_flow_tests.cpp<br>
+nir_tests_control_flow_tests_CFLAGS = $(NIR_TESTS_CFLAGS)<br>
+nir_tests_control_flow_tests_LDADD = $(NIR_TESTS_LDADD)<br>
+<br>
+nir_tests_vars_tests_CPPFLAGS = $(NIR_TESTS_CPPFLAGS)<br>
+nir_tests_vars_tests_SOURCES = nir/tests/vars_tests.cpp<br>
+nir_tests_vars_tests_CFLAGS = $(NIR_TESTS_CFLAGS)<br>
+nir_tests_vars_tests_LDADD = $(NIR_TESTS_LDADD)<br>
+<br>
+<br>
+TESTS += \<br>
+        nir/tests/control_flow_tests \<br>
+        nir/tests/vars_tests<br>
<br>
<br>
 BUILT_SOURCES += \<br>
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build<br>
index 090aa7a628f..1a7fa2d3327 100644<br>
--- a/src/compiler/nir/meson.build<br>
+++ b/src/compiler/nir/meson.build<br>
@@ -245,4 +245,15 @@ if with_tests<br>
       link_with : libmesa_util,<br>
     )<br>
   )<br>
+  test(<br>
+    'nir_vars',<br>
+    executable(<br>
+      'nir_vars_test',<br>
+      files('tests/vars_tests.cpp'),<br>
+      cpp_args : [cpp_vis_args, cpp_msvc_compat_args],<br>
+      include_directories : [inc_common],<br>
+      dependencies : [dep_thread, idep_gtest, idep_nir],<br>
+      link_with : libmesa_util,<br>
+    )<br>
+  )<br>
 endif<br>
diff --git a/src/compiler/nir/tests/vars_tests.cpp b/src/compiler/nir/tests/vars_tests.cpp<br>
new file mode 100644<br>
index 00000000000..7fbdb514349<br>
--- /dev/null<br>
+++ b/src/compiler/nir/tests/vars_tests.cpp<br>
@@ -0,0 +1,199 @@<br>
+/*<br>
+ * Copyright © 2018 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ */<br>
+<br>
+#include <gtest/gtest.h><br>
+<br>
+#include "nir.h"<br>
+#include "nir_builder.h"<br>
+<br>
+namespace {<br>
+<br>
+class nir_vars_test : public ::testing::Test {<br>
+protected:<br>
+   nir_vars_test();<br>
+   ~nir_vars_test();<br>
+<br>
+   nir_variable *create_int(nir_variable_mode mode, const char *name) {<br>
+      if (mode == nir_var_local)<br>
+         return nir_local_variable_create(b->impl, glsl_int_type(), name);<br>
+      return nir_variable_create(b->shader, mode, glsl_int_type(), name);<br>
+   }<br>
+<br>
+   nir_variable *create_ivec2(nir_variable_mode mode, const char *name) {<br>
+      const glsl_type *var_type = glsl_vector_type(GLSL_TYPE_INT, 2);<br>
+      if (mode == nir_var_local)<br>
+         return nir_local_variable_create(b->impl, var_type, name);<br>
+      return nir_variable_create(b->shader, mode, var_type, name);<br>
+   }<br>
+<br>
+   nir_variable **create_many_int(nir_variable_mode mode, const char *prefix, unsigned count) {<br>
+      nir_variable **result = (nir_variable **)linear_alloc_child(lin_ctx, sizeof(nir_variable *) * count);<br>
+      for (unsigned i = 0; i < count; i++)<br>
+         result[i] = create_int(mode, linear_asprintf(lin_ctx, "%s%u", prefix, i));<br>
+      return result;<br>
+   }<br>
+<br>
+   nir_variable **create_many_ivec2(nir_variable_mode mode, const char *prefix, unsigned count) {<br>
+      nir_variable **result = (nir_variable **)linear_alloc_child(lin_ctx, sizeof(nir_variable *) * count);<br>
+      for (unsigned i = 0; i < count; i++)<br>
+         result[i] = create_ivec2(mode, linear_asprintf(lin_ctx, "%s%u", prefix, i));<br>
+      return result;<br>
+   }<br>
+<br>
+   unsigned count_intrinsics(nir_intrinsic_op intrinsic);<br>
+<br>
+   nir_intrinsic_instr *find_next_intrinsic(nir_intrinsic_op intrinsic,<br>
+                                            nir_intrinsic_instr *after);<br>
+<br>
+   void *mem_ctx;<br>
+   void *lin_ctx;<br>
+<br>
+   nir_builder *b;<br>
+};<br>
+<br>
+nir_vars_test::nir_vars_test()<br>
+{<br>
+   mem_ctx = ralloc_context(NULL);<br>
+   lin_ctx = linear_alloc_parent(mem_ctx, 0);<br>
+   static const nir_shader_compiler_options options = { };<br>
+   b = rzalloc(mem_ctx, nir_builder);<br>
+   nir_builder_init_simple_shader(b, mem_ctx, MESA_SHADER_FRAGMENT, &options);<br>
+}<br>
+<br>
+nir_vars_test::~nir_vars_test()<br>
+{<br>
+   if (HasFailure()) {<br>
+      printf("\nShader from the failed test:\n\n");<br>
+      nir_print_shader(b->shader, stdout);<br>
+   }<br>
+<br>
+   ralloc_free(mem_ctx);<br>
+}<br>
+<br>
+unsigned<br>
+nir_vars_test::count_intrinsics(nir_intrinsic_op intrinsic)<br>
+{<br>
+   unsigned count = 0;<br>
+   nir_foreach_block(block, b->impl) {<br>
+      nir_foreach_instr(instr, block) {<br>
+         if (instr->type != nir_instr_type_intrinsic)<br>
+            continue;<br>
+         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);<br>
+         if (intrin->intrinsic == intrinsic)<br>
+            count++;<br>
+      }<br>
+   }<br>
+   return count;<br>
+}<br>
+<br>
+nir_intrinsic_instr *<br>
+nir_vars_test::find_next_intrinsic(nir_intrinsic_op intrinsic,<br>
+                                   nir_intrinsic_instr *after)<br>
+{<br>
+   bool seen = after == NULL;<br>
+   nir_foreach_block(block, b->impl) {<br></blockquote><div><br></div><div>You could add</div><div><br></div><div>if (!seen && after && block != after->block)</div><div>   continue;</div><div><br></div><div>and we can avoid walking every block.  Doesn't really matter but you could.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      nir_foreach_instr(instr, block) {<br>
+         if (instr->type != nir_instr_type_intrinsic)<br>
+            continue;<br>
+         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);<br>
+         if (!seen) {<br>
+            seen = (after == intrin);<br>
+            continue;<br>
+         }<br>
+         if (intrin->intrinsic == intrinsic)<br>
+            return intrin;<br>
+      }<br>
+   }<br>
+   return NULL;<br>
+}<br>
+<br>
+nir_ssa_def *<br>
+nir_imm_ivec2(nir_builder *build, int x, int y)<br>
+{<br>
+   nir_const_value v;<br>
+<br>
+   memset(&v, 0, sizeof(v));<br>
+   v.i32[0] = x;<br>
+   v.i32[1] = y;<br>
+<br>
+   return nir_build_imm(build, 2, 32, v);<br>
+}<br></blockquote><div><br></div><div>This could be added to nir_builder.h...</div><div><br></div><div>None of my comments are interesting</div><div><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+/* Allow grouping the tests while still sharing the helpers. */<br>
+class nir_copy_prop_vars_test : public nir_vars_test {};<br>
+<br>
+} // namespace<br>
+<br>
+TEST_F(nir_copy_prop_vars_test, simple_copies)<br>
+{<br>
+   nir_variable *in   = create_int(nir_var_shader_in,  "in");<br>
+   nir_variable *temp = create_int(nir_var_local,      "temp");<br>
+   nir_variable *out  = create_int(nir_var_shader_out, "out");<br>
+<br>
+   nir_copy_var(b, temp, in);<br>
+   nir_copy_var(b, out, temp);<br>
+<br>
+   nir_validate_shader(b->shader);<br>
+<br>
+   bool progress = nir_opt_copy_prop_vars(b->shader);<br>
+   EXPECT_TRUE(progress);<br>
+<br>
+   nir_validate_shader(b->shader);<br>
+<br>
+   nir_intrinsic_instr *copy = NULL;<br>
+   copy = find_next_intrinsic(nir_intrinsic_copy_deref, copy);<br>
+   ASSERT_TRUE(copy->src[1].is_ssa);<br>
+   nir_ssa_def *first_src = copy->src[1].ssa;<br>
+<br>
+   copy = find_next_intrinsic(nir_intrinsic_copy_deref, copy);<br>
+   ASSERT_TRUE(copy->src[1].is_ssa);<br>
+   EXPECT_EQ(copy->src[1].ssa, first_src);<br>
+}<br>
+<br>
+TEST_F(nir_copy_prop_vars_test, simple_store_load)<br>
+{<br>
+   nir_variable **v = create_many_ivec2(nir_var_local, "v", 2);<br>
+   unsigned mask = 1 | 2;<br>
+<br>
+   nir_ssa_def *stored_value = nir_imm_ivec2(b, 10, 20);<br>
+   nir_store_var(b, v[0], stored_value, mask);<br>
+<br>
+   nir_ssa_def *read_value = nir_load_var(b, v[0]);<br>
+   nir_store_var(b, v[1], read_value, mask);<br>
+<br>
+   nir_validate_shader(b->shader);<br>
+<br>
+   bool progress = nir_opt_copy_prop_vars(b->shader);<br>
+   EXPECT_TRUE(progress);<br>
+<br>
+   nir_validate_shader(b->shader);<br>
+<br>
+   ASSERT_EQ(count_intrinsics(nir_intrinsic_store_deref), 2);<br>
+<br>
+   nir_intrinsic_instr *store = NULL;<br>
+   for (int i = 0; i < 2; i++) {<br>
+      store = find_next_intrinsic(nir_intrinsic_store_deref, store);<br>
+      ASSERT_TRUE(store->src[1].is_ssa);<br>
+      EXPECT_EQ(store->src[1].ssa, stored_value);<br>
+   }<br>
+}<br>
-- <br>
2.19.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div></div>