summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2020-03-31 13:49:30 +1100
committerMarge Bot <[email protected]>2020-04-18 11:50:44 +0000
commit6afd0954e12eb75a4ce19580907b1fc4145369b9 (patch)
tree23766aaafbdb156f412ed7f0887eb34c94aab320
parent5d992b539e977ac688e950866a1d872de5acec18 (diff)
glsl: pull mark_array_elements_referenced() out into common helper
We will reuse this helper in the NIR linker in the following patches. Reviewed-by: Alejandro PiƱeiro <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4623>
-rw-r--r--src/compiler/glsl/ir_array_refcount.cpp52
-rw-r--r--src/compiler/glsl/ir_array_refcount.h73
-rw-r--r--src/compiler/glsl/linker_util.cpp87
-rw-r--r--src/compiler/glsl/linker_util.h24
-rw-r--r--src/compiler/glsl/tests/array_refcount_test.cpp15
5 files changed, 130 insertions, 121 deletions
diff --git a/src/compiler/glsl/ir_array_refcount.cpp b/src/compiler/glsl/ir_array_refcount.cpp
index c2295c96ca9..0c18c7e0ecf 100644
--- a/src/compiler/glsl/ir_array_refcount.cpp
+++ b/src/compiler/glsl/ir_array_refcount.cpp
@@ -75,54 +75,6 @@ ir_array_refcount_entry::~ir_array_refcount_entry()
delete [] bits;
}
-
-void
-ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
- unsigned count)
-{
- if (count != array_depth)
- return;
-
- mark_array_elements_referenced(dr, count, 1, 0);
-}
-
-void
-ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
- unsigned count,
- unsigned scale,
- unsigned linearized_index)
-{
- /* Walk through the list of array dereferences in least- to
- * most-significant order. Along the way, accumulate the current
- * linearized offset and the scale factor for each array-of-.
- */
- for (unsigned i = 0; i < count; i++) {
- if (dr[i].index < dr[i].size) {
- linearized_index += dr[i].index * scale;
- scale *= dr[i].size;
- } else {
- /* For each element in the current array, update the count and
- * offset, then recurse to process the remaining arrays.
- *
- * There is some inefficency here if the last element in the
- * array_deref_range list specifies the entire array. In that case,
- * the loop will make recursive calls with count == 0. In the call,
- * all that will happen is the bit will be set.
- */
- for (unsigned j = 0; j < dr[i].size; j++) {
- mark_array_elements_referenced(&dr[i + 1],
- count - (i + 1),
- scale * dr[i].size,
- linearized_index + (j * scale));
- }
-
- return;
- }
- }
-
- BITSET_SET(bits, linearized_index);
-}
-
ir_array_refcount_entry *
ir_array_refcount_visitor::get_variable_entry(ir_variable *var)
{
@@ -224,7 +176,9 @@ ir_array_refcount_visitor::visit_enter(ir_dereference_array *ir)
if (entry == NULL)
return visit_stop;
- entry->mark_array_elements_referenced(derefs, num_derefs);
+ link_util_mark_array_elements_referenced(derefs, num_derefs,
+ entry->array_depth,
+ entry->bits);
return visit_continue;
}
diff --git a/src/compiler/glsl/ir_array_refcount.h b/src/compiler/glsl/ir_array_refcount.h
index ef3fbaa368d..4a9d9017a02 100644
--- a/src/compiler/glsl/ir_array_refcount.h
+++ b/src/compiler/glsl/ir_array_refcount.h
@@ -32,26 +32,10 @@
#include "ir.h"
#include "ir_visitor.h"
+#include "linker_util.h"
#include "compiler/glsl_types.h"
#include "util/bitset.h"
-/**
- * Describes an access of an array element or an access of the whole array
- */
-struct array_deref_range {
- /**
- * Index that was accessed.
- *
- * All valid array indices are less than the size of the array. If index
- * is equal to the size of the array, this means the entire array has been
- * accessed (e.g., due to use of a non-constant index).
- */
- unsigned index;
-
- /** Size of the array. Used for offset calculations. */
- unsigned size;
-};
-
class ir_array_refcount_entry
{
public:
@@ -63,33 +47,11 @@ public:
/** Has the variable been referenced? */
bool is_referenced;
- /**
- * Mark a set of array elements as accessed.
- *
- * If every \c array_deref_range is for a single index, only a single
- * element will be marked. If any \c array_deref_range is for an entire
- * array-of-, then multiple elements will be marked.
- *
- * Items in the \c array_deref_range list appear in least- to
- * most-significant order. This is the \b opposite order the indices
- * appear in the GLSL shader text. An array access like
- *
- * x = y[1][i][3];
- *
- * would appear as
- *
- * { { 3, n }, { m, m }, { 1, p } }
- *
- * where n, m, and p are the sizes of the arrays-of-arrays.
- *
- * The set of marked array elements can later be queried by
- * \c ::is_linearized_index_referenced.
- *
- * \param dr List of array_deref_range elements to be processed.
- * \param count Number of array_deref_range elements to be processed.
- */
- void mark_array_elements_referenced(const array_deref_range *dr,
- unsigned count);
+ /** Count of nested arrays in the type. */
+ unsigned array_depth;
+
+ /** Set of bit-flags to note which array elements have been accessed. */
+ BITSET_WORD *bits;
/** Has a linearized array index been referenced? */
bool is_linearized_index_referenced(unsigned linearized_index) const
@@ -101,8 +63,6 @@ public:
}
private:
- /** Set of bit-flags to note which array elements have been accessed. */
- BITSET_WORD *bits;
/**
* Total number of bits referenced by \c bits.
@@ -111,27 +71,6 @@ private:
*/
unsigned num_bits;
- /** Count of nested arrays in the type. */
- unsigned array_depth;
-
- /**
- * Recursive part of the public mark_array_elements_referenced method.
- *
- * The recursion occurs when an entire array-of- is accessed. See the
- * implementation for more details.
- *
- * \param dr List of array_deref_range elements to be
- * processed.
- * \param count Number of array_deref_range elements to be
- * processed.
- * \param scale Current offset scale.
- * \param linearized_index Current accumulated linearized array index.
- */
- void mark_array_elements_referenced(const array_deref_range *dr,
- unsigned count,
- unsigned scale,
- unsigned linearized_index);
-
friend class array_refcount_test;
};
diff --git a/src/compiler/glsl/linker_util.cpp b/src/compiler/glsl/linker_util.cpp
index 80c9f2872f9..a790de3ca39 100644
--- a/src/compiler/glsl/linker_util.cpp
+++ b/src/compiler/glsl/linker_util.cpp
@@ -287,3 +287,90 @@ link_util_calculate_subroutine_compat(struct gl_shader_program *prog)
}
}
}
+
+/**
+ * Recursive part of the public mark_array_elements_referenced function.
+ *
+ * The recursion occurs when an entire array-of- is accessed. See the
+ * implementation for more details.
+ *
+ * \param dr List of array_deref_range elements to be
+ * processed.
+ * \param count Number of array_deref_range elements to be
+ * processed.
+ * \param scale Current offset scale.
+ * \param linearized_index Current accumulated linearized array index.
+ */
+void
+_mark_array_elements_referenced(const struct array_deref_range *dr,
+ unsigned count, unsigned scale,
+ unsigned linearized_index,
+ BITSET_WORD *bits)
+{
+ /* Walk through the list of array dereferences in least- to
+ * most-significant order. Along the way, accumulate the current
+ * linearized offset and the scale factor for each array-of-.
+ */
+ for (unsigned i = 0; i < count; i++) {
+ if (dr[i].index < dr[i].size) {
+ linearized_index += dr[i].index * scale;
+ scale *= dr[i].size;
+ } else {
+ /* For each element in the current array, update the count and
+ * offset, then recurse to process the remaining arrays.
+ *
+ * There is some inefficency here if the last eBITSET_WORD *bitslement in the
+ * array_deref_range list specifies the entire array. In that case,
+ * the loop will make recursive calls with count == 0. In the call,
+ * all that will happen is the bit will be set.
+ */
+ for (unsigned j = 0; j < dr[i].size; j++) {
+ _mark_array_elements_referenced(&dr[i + 1],
+ count - (i + 1),
+ scale * dr[i].size,
+ linearized_index + (j * scale),
+ bits);
+ }
+
+ return;
+ }
+ }
+
+ BITSET_SET(bits, linearized_index);
+}
+
+/**
+ * Mark a set of array elements as accessed.
+ *
+ * If every \c array_deref_range is for a single index, only a single
+ * element will be marked. If any \c array_deref_range is for an entire
+ * array-of-, then multiple elements will be marked.
+ *
+ * Items in the \c array_deref_range list appear in least- to
+ * most-significant order. This is the \b opposite order the indices
+ * appear in the GLSL shader text. An array access like
+ *
+ * x = y[1][i][3];
+ *
+ * would appear as
+ *
+ * { { 3, n }, { m, m }, { 1, p } }
+ *
+ * where n, m, and p are the sizes of the arrays-of-arrays.
+ *
+ * The set of marked array elements can later be queried by
+ * \c ::is_linearized_index_referenced.
+ *
+ * \param dr List of array_deref_range elements to be processed.
+ * \param count Number of array_deref_range elements to be processed.
+ */
+void
+link_util_mark_array_elements_referenced(const struct array_deref_range *dr,
+ unsigned count, unsigned array_depth,
+ BITSET_WORD *bits)
+{
+ if (count != array_depth)
+ return;
+
+ _mark_array_elements_referenced(dr, count, 1, 0, bits);
+}
diff --git a/src/compiler/glsl/linker_util.h b/src/compiler/glsl/linker_util.h
index 53e0ca315a5..16f5ca9e401 100644
--- a/src/compiler/glsl/linker_util.h
+++ b/src/compiler/glsl/linker_util.h
@@ -24,6 +24,8 @@
#ifndef GLSL_LINKER_UTIL_H
#define GLSL_LINKER_UTIL_H
+#include "util/bitset.h"
+
struct gl_context;
struct gl_shader_program;
struct gl_uniform_storage;
@@ -45,6 +47,23 @@ struct empty_uniform_block {
unsigned slots;
};
+/**
+ * Describes an access of an array element or an access of the whole array
+ */
+struct array_deref_range {
+ /**
+ * Index that was accessed.
+ *
+ * All valid array indices are less than the size of the array. If index
+ * is equal to the size of the array, this means the entire array has been
+ * accessed (e.g., due to use of a non-constant index).
+ */
+ unsigned index;
+
+ /** Size of the array. Used for offset calculations. */
+ unsigned size;
+};
+
void
linker_error(struct gl_shader_program *prog, const char *fmt, ...);
@@ -81,6 +100,11 @@ link_util_check_uniform_resources(struct gl_context *ctx,
void
link_util_calculate_subroutine_compat(struct gl_shader_program *prog);
+void
+link_util_mark_array_elements_referenced(const struct array_deref_range *dr,
+ unsigned count, unsigned array_depth,
+ BITSET_WORD *bits);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/compiler/glsl/tests/array_refcount_test.cpp b/src/compiler/glsl/tests/array_refcount_test.cpp
index 3d2778d46a5..7a69f56c435 100644
--- a/src/compiler/glsl/tests/array_refcount_test.cpp
+++ b/src/compiler/glsl/tests/array_refcount_test.cpp
@@ -283,7 +283,8 @@ TEST_F(array_refcount_test, mark_array_elements_referenced_simple)
};
const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5);
- entry.mark_array_elements_referenced(dr, 3);
+ link_util_mark_array_elements_referenced(dr, 3, entry.array_depth,
+ entry.bits);
for (unsigned i = 0; i < total_elements; i++)
EXPECT_EQ(i == accessed_element, entry.is_linearized_index_referenced(i));
@@ -302,7 +303,8 @@ TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_array)
{ 0, 5 }, { 1, 4 }, { 3, 3 }
};
- entry.mark_array_elements_referenced(dr, 3);
+ link_util_mark_array_elements_referenced(dr, 3, entry.array_depth,
+ entry.bits);
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 4; j++) {
@@ -330,7 +332,8 @@ TEST_F(array_refcount_test, mark_array_elements_referenced_whole_second_array)
{ 0, 5 }, { 4, 4 }, { 1, 3 }
};
- entry.mark_array_elements_referenced(dr, 3);
+ link_util_mark_array_elements_referenced(dr, 3, entry.array_depth,
+ entry.bits);
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 4; j++) {
@@ -358,7 +361,8 @@ TEST_F(array_refcount_test, mark_array_elements_referenced_whole_third_array)
{ 5, 5 }, { 2, 4 }, { 1, 3 }
};
- entry.mark_array_elements_referenced(dr, 3);
+ link_util_mark_array_elements_referenced(dr, 3, entry.array_depth,
+ entry.bits);
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 4; j++) {
@@ -386,7 +390,8 @@ TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_and_third
{ 5, 5 }, { 3, 4 }, { 3, 3 }
};
- entry.mark_array_elements_referenced(dr, 3);
+ link_util_mark_array_elements_referenced(dr, 3, entry.array_depth,
+ entry.bits);
for (unsigned i = 0; i < 3; i++) {
for (unsigned j = 0; j < 4; j++) {