[Mesa-dev] [PATCH 90.1/133] SQUASH/nir: Add documentation for nir_split_var_copies
Connor Abbott
cwabbott0 at gmail.com
Wed Jan 14 13:40:12 PST 2015
With this squashed in, patch 90 is
Reviewed-by: Connor Abbott <cwabbott0 at gmail.com>
On Wed, Jan 14, 2015 at 2:57 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> ---
> src/glsl/nir/nir_split_var_copies.c | 96 ++++++++++++++++++++++++++++++-------
> 1 file changed, 78 insertions(+), 18 deletions(-)
>
> diff --git a/src/glsl/nir/nir_split_var_copies.c b/src/glsl/nir/nir_split_var_copies.c
> index 70ce30a..4d663b5 100644
> --- a/src/glsl/nir/nir_split_var_copies.c
> +++ b/src/glsl/nir/nir_split_var_copies.c
> @@ -74,40 +74,81 @@ get_deref_tail(nir_deref *deref)
> return deref;
> }
>
> +/* Recursively constructs deref chains to split a copy instruction into
> + * multiple (if needed) copy instructions with full-length deref chains.
> + * External callers of this function should pass the tail and head of the
> + * deref chains found as the source and destination of the copy instruction
> + * into this function.
> + *
> + * \param old_copy The copy instruction we are splitting
> + * \param dest_head The head of the destination deref chain we are building
> + * \param src_head The head of the source deref chain we are building
> + * \param dest_tail The tail of the destination deref chain we are building
> + * \param src_tail The tail of the source deref chain we are building
> + * \param state The current split_var_copies_state object
> + */
> static void
> -nir_split_var_copy_instr(nir_intrinsic_instr *old_copy,
> - nir_deref *dest_head, nir_deref *src_head,
> - nir_deref *dest_tail, nir_deref *src_tail,
> - struct split_var_copies_state *state)
> +split_var_copy_instr(nir_intrinsic_instr *old_copy,
> + nir_deref *dest_head, nir_deref *src_head,
> + nir_deref *dest_tail, nir_deref *src_tail,
> + struct split_var_copies_state *state)
> {
> assert(src_tail->type == dest_tail->type);
>
> + /* Make sure these really are the tails of the deref chains */
> + assert(dest_tail->child == NULL);
> + assert(src_tail->child == NULL);
> +
> switch (glsl_get_base_type(src_tail->type)) {
> case GLSL_TYPE_ARRAY: {
> + /* Make a wildcard dereference */
> nir_deref_array *deref = nir_deref_array_create(state->dead_ctx);
> deref->deref.type = glsl_get_array_element(src_tail->type);
> deref->deref_array_type = nir_deref_array_type_wildcard;
>
> + /* Set the tail of both as the newly created wildcard deref. It is
> + * safe to use the same wildcard in both places because a) we will be
> + * copying it before we put it in an actual instruction and b)
> + * everything that will potentially add another link in the deref
> + * chain will also add the same thing to both chains.
> + */
> src_tail->child = &deref->deref;
> dest_tail->child = &deref->deref;
> - nir_split_var_copy_instr(old_copy, dest_head, src_head,
> - dest_tail->child, src_tail->child, state);
> +
> + split_var_copy_instr(old_copy, dest_head, src_head,
> + dest_tail->child, src_tail->child, state);
> +
> + /* Set it back to the way we found it */
> src_tail->child = NULL;
> dest_tail->child = NULL;
> break;
> }
>
> case GLSL_TYPE_STRUCT:
> + /* This is the only part that actually does any interesting
> + * splitting. For array types, we just use wildcards and resolve
> + * them later. For structure types, we need to emit one copy
> + * instruction for every structure element. Because we may have
> + * structs inside structs, we just recurse and let the next level
> + * take care of any additional structures.
> + */
> for (unsigned i = 0; i < glsl_get_length(src_tail->type); i++) {
> nir_deref_struct *deref = nir_deref_struct_create(state->dead_ctx, i);
> deref->deref.type = glsl_get_struct_field(src_tail->type, i);
>
> + /* Set the tail of both as the newly created structure deref. It
> + * is safe to use the same wildcard in both places because a) we
> + * will be copying it before we put it in an actual instruction
> + * and b) everything that will potentially add another link in the
> + * deref chain will also add the same thing to both chains.
> + */
> src_tail->child = &deref->deref;
> dest_tail->child = &deref->deref;
>
> - nir_split_var_copy_instr(old_copy, dest_head, src_head,
> - dest_tail->child, src_tail->child, state);
> + split_var_copy_instr(old_copy, dest_head, src_head,
> + dest_tail->child, src_tail->child, state);
> }
> + /* Set it back to the way we found it */
> src_tail->child = NULL;
> dest_tail->child = NULL;
> break;
> @@ -121,22 +162,41 @@ nir_split_var_copy_instr(nir_intrinsic_instr *old_copy,
> deref->deref.type = glsl_get_column_type(src_tail->type);
> deref->deref_array_type = nir_deref_array_type_wildcard;
>
> + /* Set the tail of both as the newly created wildcard deref. It
> + * is safe to use the same wildcard in both places because a) we
> + * will be copying it before we put it in an actual instruction
> + * and b) everything that will potentially add another link in the
> + * deref chain will also add the same thing to both chains.
> + */
> src_tail->child = &deref->deref;
> dest_tail->child = &deref->deref;
> - nir_split_var_copy_instr(old_copy, dest_head, src_head,
> - dest_tail->child, src_tail->child, state);
> +
> + split_var_copy_instr(old_copy, dest_head, src_head,
> + dest_tail->child, src_tail->child, state);
> +
> + /* Set it back to the way we found it */
> src_tail->child = NULL;
> dest_tail->child = NULL;
> } else {
> + /* At this point, we have fully built our deref chains and can
> + * actually add the new copy instruction.
> + */
> nir_intrinsic_instr *new_copy =
> nir_intrinsic_instr_create(state->mem_ctx, nir_intrinsic_copy_var);
>
> + /* We need to make copies because a) this deref chain actually
> + * belongs to the copy instruction and b) the deref chains may
> + * have some of the same links due to the way we constructed them
> + */
> nir_deref *src = nir_copy_deref(state->mem_ctx, src_head);
> nir_deref *dest = nir_copy_deref(state->mem_ctx, dest_head);
>
> new_copy->variables[0] = nir_deref_as_var(dest);
> new_copy->variables[1] = nir_deref_as_var(src);
>
> + /* Emit the copy instruction after the old instruction. We'll
> + * remove the old one later.
> + */
> nir_instr_insert_after(&old_copy->instr, &new_copy->instr);
> }
> break;
> @@ -151,7 +211,7 @@ nir_split_var_copy_instr(nir_intrinsic_instr *old_copy,
> }
>
> static bool
> -nir_split_var_copies_block(nir_block *block, void *void_state)
> +split_var_copies_block(nir_block *block, void *void_state)
> {
> struct split_var_copies_state *state = void_state;
>
> @@ -171,8 +231,8 @@ nir_split_var_copies_block(nir_block *block, void *void_state)
> switch (glsl_get_base_type(src_tail->type)) {
> case GLSL_TYPE_ARRAY:
> case GLSL_TYPE_STRUCT:
> - nir_split_var_copy_instr(intrinsic, dest_head, src_head,
> - dest_tail, src_tail, state);
> + split_var_copy_instr(intrinsic, dest_head, src_head,
> + dest_tail, src_tail, state);
> nir_instr_remove(&intrinsic->instr);
> ralloc_steal(state->dead_ctx, instr);
> break;
> @@ -181,8 +241,8 @@ nir_split_var_copies_block(nir_block *block, void *void_state)
> case GLSL_TYPE_UINT:
> case GLSL_TYPE_BOOL:
> if (glsl_type_is_matrix(src_tail->type)) {
> - nir_split_var_copy_instr(intrinsic, dest_head, src_head,
> - dest_tail, src_tail, state);
> + split_var_copy_instr(intrinsic, dest_head, src_head,
> + dest_tail, src_tail, state);
> nir_instr_remove(&intrinsic->instr);
> ralloc_steal(state->dead_ctx, instr);
> }
> @@ -197,14 +257,14 @@ nir_split_var_copies_block(nir_block *block, void *void_state)
> }
>
> static void
> -nir_split_var_copies_impl(nir_function_impl *impl)
> +split_var_copies_impl(nir_function_impl *impl)
> {
> struct split_var_copies_state state;
>
> state.mem_ctx = ralloc_parent(impl);
> state.dead_ctx = ralloc_context(NULL);
>
> - nir_foreach_block(impl, nir_split_var_copies_block, &state);
> + nir_foreach_block(impl, split_var_copies_block, &state);
>
> ralloc_free(state.dead_ctx);
> }
> @@ -214,6 +274,6 @@ nir_split_var_copies(nir_shader *shader)
> {
> nir_foreach_overload(shader, overload) {
> if (overload->impl)
> - nir_split_var_copies_impl(overload->impl);
> + split_var_copies_impl(overload->impl);
> }
> }
> --
> 2.2.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list