Mesa (main): nir: Add a function for sorting variables

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 24 20:25:11 UTC 2021


Module: Mesa
Branch: main
Commit: 81cb20bd17c7ad0ac94f41462685635df25fd16e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=81cb20bd17c7ad0ac94f41462685635df25fd16e

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Fri Nov  6 15:19:53 2020 -0800

nir: Add a function for sorting variables

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10989>

---

 src/compiler/nir/nir.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 src/compiler/nir/nir.h |  4 ++++
 2 files changed, 48 insertions(+)

diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index a15f24eb30a..41fe6ae0cec 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -33,6 +33,7 @@
 #include <assert.h>
 #include <math.h>
 #include "util/u_math.h"
+#include "util/u_qsort.h"
 
 #include "main/menums.h" /* BITFIELD64_MASK */
 
@@ -259,6 +260,49 @@ nir_find_variable_with_driver_location(nir_shader *shader,
    return NULL;
 }
 
+/* Annoyingly, qsort_r is not in the C standard library and, in particular, we
+ * can't count on it on MSV and Android.  So we stuff the CMP function into
+ * each array element.  It's a bit messy and burns more memory but the list of
+ * variables should hever be all that long.
+ */
+struct var_cmp {
+   nir_variable *var;
+   int (*cmp)(const nir_variable *, const nir_variable *);
+};
+
+static int
+var_sort_cmp(const void *_a, const void *_b, void *_cmp)
+{
+   const struct var_cmp *a = _a;
+   const struct var_cmp *b = _b;
+   assert(a->cmp == b->cmp);
+   return a->cmp(a->var, b->var);
+}
+
+void
+nir_sort_variables(nir_shader *shader,
+                   int (*cmp)(const nir_variable *, const nir_variable *))
+{
+   const unsigned num_vars = exec_list_length(&shader->variables);
+   struct var_cmp *vars = ralloc_array(shader, struct var_cmp, num_vars);
+   unsigned i = 0;
+   nir_foreach_variable_in_shader(var, shader) {
+      vars[i++] = (struct var_cmp) {
+         .var = var,
+         .cmp = cmp,
+      };
+   }
+   assert(i == num_vars);
+
+   util_qsort_r(vars, num_vars, sizeof(*vars), var_sort_cmp, cmp);
+
+   exec_list_make_empty(&shader->variables);
+   for (i = 0; i < num_vars; i++)
+      exec_list_push_tail(&shader->variables, &vars[i].var->node);
+
+   ralloc_free(vars);
+}
+
 nir_function *
 nir_function_create(nir_shader *shader, const char *name)
 {
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 6f7732fd8e6..9af1264191c 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -3622,6 +3622,10 @@ nir_variable *nir_find_variable_with_driver_location(nir_shader *shader,
                                                      nir_variable_mode mode,
                                                      unsigned location);
 
+void nir_sort_variables(nir_shader *shader,
+                        int (*compar)(const nir_variable *,
+                                      const nir_variable *));
+
 /** creates a function and adds it to the shader's list of functions */
 nir_function *nir_function_create(nir_shader *shader, const char *name);
 



More information about the mesa-commit mailing list