nir: Don't replace the nir_shader when NIR_TEST_CLONE=1
authorJason Ekstrand <jason@jlekstrand.net>
Tue, 4 Jun 2019 22:48:33 +0000 (17:48 -0500)
committerJason Ekstrand <jason@jlekstrand.net>
Wed, 5 Jun 2019 20:07:28 +0000 (20:07 +0000)
Instead, we add a new helper which stomps one nir_shader and replaces it
with another.  The new helper effectively just changes which pointer
gets used for the base nir_shader.  It should be 99% as good at testing
cloning but without requiring that everything handle having the shader
swapped out from under it constantly.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108957
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Rob Clark <robdclark@chromium.org>
src/compiler/nir/nir.h
src/compiler/nir/nir_clone.c

index 632cf06c32c36e645689b0b9f2fac83bdee57ecd..12be397ff19c28a33df23c2b4f1d5ff887b7a1d3 100644 (file)
@@ -2918,6 +2918,8 @@ nir_function_impl *nir_function_impl_clone(nir_shader *shader,
 nir_constant *nir_constant_clone(const nir_constant *c, nir_variable *var);
 nir_variable *nir_variable_clone(const nir_variable *c, nir_shader *shader);
 
+void nir_shader_replace(nir_shader *dest, nir_shader *src);
+
 nir_shader *nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s);
 
 #ifndef NDEBUG
@@ -2990,8 +2992,7 @@ static inline bool should_print_nir(void) { return false; }
    nir_validate_shader(nir, "after " #pass);                         \
    if (should_clone_nir()) {                                         \
       nir_shader *clone = nir_shader_clone(ralloc_parent(nir), nir); \
-      ralloc_free(nir);                                              \
-      nir = clone;                                                   \
+      nir_shader_replace(nir, clone);                                \
    }                                                                 \
    if (should_serialize_deserialize_nir()) {                         \
       void *mem_ctx = ralloc_parent(nir);                            \
index c82ee3c5642ab17f7df12cf23cebc5238af04156..803923e2578aad6dfce32db524e53bf9bcf5c54c 100644 (file)
@@ -769,3 +769,42 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s)
 
    return ns;
 }
+
+/** Overwrites dst and replaces its contents with src
+ *
+ * Everything ralloc parented to dst and src itself (but not its children)
+ * will be freed.
+ *
+ * This should only be used by test code which needs to swap out shaders with
+ * a cloned or deserialized version.
+ */
+void
+nir_shader_replace(nir_shader *dst, nir_shader *src)
+{
+   /* Delete all of dest's ralloc children */
+   void *dead_ctx = ralloc_context(NULL);
+   ralloc_adopt(dead_ctx, dst);
+   ralloc_free(dead_ctx);
+
+   /* Re-parent all of src's ralloc children to dst */
+   ralloc_adopt(dst, src);
+
+   memcpy(dst, src, sizeof(*dst));
+
+   /* We have to move all the linked lists over separately because we need the
+    * pointers in the list elements to point to the lists in dst and not src.
+    */
+   exec_list_move_nodes_to(&src->uniforms,      &dst->uniforms);
+   exec_list_move_nodes_to(&src->inputs,        &dst->inputs);
+   exec_list_move_nodes_to(&src->outputs,       &dst->outputs);
+   exec_list_move_nodes_to(&src->shared,        &dst->shared);
+   exec_list_move_nodes_to(&src->globals,       &dst->globals);
+   exec_list_move_nodes_to(&src->system_values, &dst->system_values);
+
+   /* Now move the functions over.  This takes a tiny bit more work */
+   exec_list_move_nodes_to(&src->functions, &dst->functions);
+   nir_foreach_function(function, dst)
+      function->shader = dst;
+
+   ralloc_free(src);
+}