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