nir: Make nir_deref_instr::mode a bitfield

We rename it to "modes" to make it clear that it may contain more than
one mode and adjust all the uses of nir_deref_instr::modes to attempt to
handle multiple modes.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6332>
This commit is contained in:
Jason Ekstrand
2020-10-30 12:14:05 -05:00
committed by Marge Bot
parent 7d5f3b5c0e
commit 9d377c01d0
22 changed files with 106 additions and 103 deletions

View File

@@ -4574,7 +4574,7 @@ static void visit_deref(struct ac_nir_context *ctx, nir_deref_instr *instr)
unsigned address_space; unsigned address_space;
switch (instr->mode) { switch (instr->modes) {
case nir_var_mem_shared: case nir_var_mem_shared:
address_space = AC_ADDR_SPACE_LDS; address_space = AC_ADDR_SPACE_LDS;
break; break;

View File

@@ -484,7 +484,7 @@ add_var_use_deref(nir_deref_instr *deref, struct hash_table *live,
util_dynarray_append(ainfo->deref_list, nir_deref_instr *, deref); util_dynarray_append(ainfo->deref_list, nir_deref_instr *, deref);
} }
assert(deref->mode == deref->var->data.mode); assert(deref->modes == deref->var->data.mode);
_mesa_hash_table_insert(live, deref->var->name, ainfo); _mesa_hash_table_insert(live, deref->var->name, ainfo);
} }

View File

@@ -209,7 +209,7 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
break; break;
} }
nir_deref_instr *cast = nir_build_deref_cast(&b, ptr, deref->mode, nir_deref_instr *cast = nir_build_deref_cast(&b, ptr, deref->modes,
deref->type, 0); deref->type, 0);
/* Set the alignment on the cast so that we get good alignment out /* Set the alignment on the cast so that we get good alignment out
* of nir_lower_explicit_io. Our offset to the start of the UBO * of nir_lower_explicit_io. Our offset to the start of the UBO

View File

@@ -1443,12 +1443,16 @@ typedef struct {
/** The type of this deref instruction */ /** The type of this deref instruction */
nir_deref_type deref_type; nir_deref_type deref_type;
/** The mode of the underlying variable /** Bitmask what modes the underlying variable might be
*
* For OpenCL-style generic pointers, we may not know exactly what mode it
* is at any given point in time in the compile process. This bitfield
* contains the set of modes which it MAY be.
* *
* Generally, this field should not be accessed directly. Use one of the * Generally, this field should not be accessed directly. Use one of the
* nir_deref_mode_ helpers instead. * nir_deref_mode_ helpers instead.
*/ */
nir_variable_mode mode; nir_variable_mode modes;
/** The dereferenced type of the resulting pointer value */ /** The dereferenced type of the resulting pointer value */
const struct glsl_type *type; const struct glsl_type *type;
@@ -1493,8 +1497,8 @@ static inline bool
nir_deref_mode_may_be(const nir_deref_instr *deref, nir_variable_mode modes) nir_deref_mode_may_be(const nir_deref_instr *deref, nir_variable_mode modes)
{ {
assert(!(modes & ~nir_var_all)); assert(!(modes & ~nir_var_all));
assert(deref->mode != 0); assert(deref->modes != 0);
return deref->mode & modes; return deref->modes & modes;
} }
/** Returns true if deref must have one of the given modes /** Returns true if deref must have one of the given modes
@@ -1509,8 +1513,8 @@ static inline bool
nir_deref_mode_must_be(const nir_deref_instr *deref, nir_variable_mode modes) nir_deref_mode_must_be(const nir_deref_instr *deref, nir_variable_mode modes)
{ {
assert(!(modes & ~nir_var_all)); assert(!(modes & ~nir_var_all));
assert(deref->mode != 0); assert(deref->modes != 0);
return !(deref->mode & ~modes); return !(deref->modes & ~modes);
} }
/** Returns true if deref has the given mode /** Returns true if deref has the given mode
@@ -1526,16 +1530,17 @@ static inline bool
nir_deref_mode_is(const nir_deref_instr *deref, nir_variable_mode mode) nir_deref_mode_is(const nir_deref_instr *deref, nir_variable_mode mode)
{ {
assert(util_bitcount(mode) == 1 && (mode & nir_var_all)); assert(util_bitcount(mode) == 1 && (mode & nir_var_all));
assert(deref->modes != 0);
/* This is only for "simple" cases so, if modes might interact with this /* This is only for "simple" cases so, if modes might interact with this
* deref then the deref has to have a single mode. * deref then the deref has to have a single mode.
*/ */
if (nir_deref_mode_may_be(deref, mode)) { if (nir_deref_mode_may_be(deref, mode)) {
assert(util_bitcount(deref->mode) == 1); assert(util_bitcount(deref->modes) == 1);
assert(deref->mode == mode); assert(deref->modes == mode);
} }
return deref->mode == mode; return deref->modes == mode;
} }
/** Returns true if deref has one of the given modes /** Returns true if deref has one of the given modes
@@ -1552,7 +1557,7 @@ nir_deref_mode_is_one_of(const nir_deref_instr *deref, nir_variable_mode modes)
* deref then the deref has to have a single mode. * deref then the deref has to have a single mode.
*/ */
if (nir_deref_mode_may_be(deref, modes)) { if (nir_deref_mode_may_be(deref, modes)) {
assert(util_bitcount(deref->mode) == 1); assert(util_bitcount(deref->modes) == 1);
assert(nir_deref_mode_must_be(deref, modes)); assert(nir_deref_mode_must_be(deref, modes));
} }

View File

@@ -1084,7 +1084,7 @@ nir_build_deref_var(nir_builder *build, nir_variable *var)
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_var); nir_deref_instr_create(build->shader, nir_deref_type_var);
deref->mode = (nir_variable_mode)var->data.mode; deref->modes = (nir_variable_mode)var->data.mode;
deref->type = var->type; deref->type = var->type;
deref->var = var; deref->var = var;
@@ -1109,7 +1109,7 @@ nir_build_deref_array(nir_builder *build, nir_deref_instr *parent,
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_array); nir_deref_instr_create(build->shader, nir_deref_type_array);
deref->mode = parent->mode; deref->modes = parent->modes;
deref->type = glsl_get_array_element(parent->type); deref->type = glsl_get_array_element(parent->type);
deref->parent = nir_src_for_ssa(&parent->dest.ssa); deref->parent = nir_src_for_ssa(&parent->dest.ssa);
deref->arr.index = nir_src_for_ssa(index); deref->arr.index = nir_src_for_ssa(index);
@@ -1147,7 +1147,7 @@ nir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent,
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array); nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array);
deref->mode = parent->mode; deref->modes = parent->modes;
deref->type = parent->type; deref->type = parent->type;
deref->parent = nir_src_for_ssa(&parent->dest.ssa); deref->parent = nir_src_for_ssa(&parent->dest.ssa);
deref->arr.index = nir_src_for_ssa(index); deref->arr.index = nir_src_for_ssa(index);
@@ -1170,7 +1170,7 @@ nir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent)
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard);
deref->mode = parent->mode; deref->modes = parent->modes;
deref->type = glsl_get_array_element(parent->type); deref->type = glsl_get_array_element(parent->type);
deref->parent = nir_src_for_ssa(&parent->dest.ssa); deref->parent = nir_src_for_ssa(&parent->dest.ssa);
@@ -1192,7 +1192,7 @@ nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent,
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_struct); nir_deref_instr_create(build->shader, nir_deref_type_struct);
deref->mode = parent->mode; deref->modes = parent->modes;
deref->type = glsl_get_struct_field(parent->type, index); deref->type = glsl_get_struct_field(parent->type, index);
deref->parent = nir_src_for_ssa(&parent->dest.ssa); deref->parent = nir_src_for_ssa(&parent->dest.ssa);
deref->strct.index = index; deref->strct.index = index;
@@ -1208,13 +1208,13 @@ nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent,
static inline nir_deref_instr * static inline nir_deref_instr *
nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent,
nir_variable_mode mode, const struct glsl_type *type, nir_variable_mode modes, const struct glsl_type *type,
unsigned ptr_stride) unsigned ptr_stride)
{ {
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_cast); nir_deref_instr_create(build->shader, nir_deref_type_cast);
deref->mode = mode; deref->modes = modes;
deref->type = type; deref->type = type;
deref->parent = nir_src_for_ssa(parent); deref->parent = nir_src_for_ssa(parent);
deref->cast.ptr_stride = ptr_stride; deref->cast.ptr_stride = ptr_stride;
@@ -1234,7 +1234,7 @@ nir_alignment_deref_cast(nir_builder *build, nir_deref_instr *parent,
nir_deref_instr *deref = nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_cast); nir_deref_instr_create(build->shader, nir_deref_type_cast);
deref->mode = parent->mode; deref->modes = parent->modes;
deref->type = parent->type; deref->type = parent->type;
deref->parent = nir_src_for_ssa(&parent->dest.ssa); deref->parent = nir_src_for_ssa(&parent->dest.ssa);
deref->cast.ptr_stride = nir_deref_instr_array_stride(deref); deref->cast.ptr_stride = nir_deref_instr_array_stride(deref);

View File

@@ -312,7 +312,7 @@ clone_deref_instr(clone_state *state, const nir_deref_instr *deref)
__clone_dst(state, &nderef->instr, &nderef->dest, &deref->dest); __clone_dst(state, &nderef->instr, &nderef->dest, &deref->dest);
nderef->mode = deref->mode; nderef->modes = deref->modes;
nderef->type = deref->type; nderef->type = deref->type;
if (deref->deref_type == nir_deref_type_var) { if (deref->deref_type == nir_deref_type_var) {

View File

@@ -33,7 +33,7 @@ is_trivial_deref_cast(nir_deref_instr *cast)
if (!parent) if (!parent)
return false; return false;
return cast->mode == parent->mode && return cast->modes == parent->modes &&
cast->type == parent->type && cast->type == parent->type &&
cast->dest.ssa.num_components == parent->dest.ssa.num_components && cast->dest.ssa.num_components == parent->dest.ssa.num_components &&
cast->dest.ssa.bit_size == parent->dest.ssa.bit_size; cast->dest.ssa.bit_size == parent->dest.ssa.bit_size;
@@ -410,17 +410,17 @@ nir_fixup_deref_modes(nir_shader *shader)
if (deref->deref_type == nir_deref_type_cast) if (deref->deref_type == nir_deref_type_cast)
continue; continue;
nir_variable_mode parent_mode; nir_variable_mode parent_modes;
if (deref->deref_type == nir_deref_type_var) { if (deref->deref_type == nir_deref_type_var) {
parent_mode = deref->var->data.mode; parent_modes = deref->var->data.mode;
} else { } else {
assert(deref->parent.is_ssa); assert(deref->parent.is_ssa);
nir_deref_instr *parent = nir_deref_instr *parent =
nir_instr_as_deref(deref->parent.ssa->parent_instr); nir_instr_as_deref(deref->parent.ssa->parent_instr);
parent_mode = parent->mode; parent_modes = parent->modes;
} }
deref->mode = parent_mode; deref->modes = parent_modes;
} }
} }
} }
@@ -430,17 +430,12 @@ static bool
modes_may_alias(nir_variable_mode a, nir_variable_mode b) modes_may_alias(nir_variable_mode a, nir_variable_mode b)
{ {
/* Generic pointers can alias with SSBOs */ /* Generic pointers can alias with SSBOs */
if ((a == nir_var_mem_ssbo || a == nir_var_mem_global) && if ((a & (nir_var_mem_ssbo | nir_var_mem_global)) &&
(b == nir_var_mem_ssbo || b == nir_var_mem_global)) (b & (nir_var_mem_ssbo | nir_var_mem_global)))
return true; return true;
/* In the general case, pointers can only alias if they have the same mode. /* Pointers can only alias if they share a mode. */
* return a & b;
* NOTE: In future, with things like OpenCL generic pointers, this may not
* be true and will have to be re-evaluated. However, with graphics only,
* it should be safe.
*/
return a == b;
} }
static bool static bool
@@ -469,7 +464,7 @@ nir_deref_compare_result
nir_compare_deref_paths(nir_deref_path *a_path, nir_compare_deref_paths(nir_deref_path *a_path,
nir_deref_path *b_path) nir_deref_path *b_path)
{ {
if (!modes_may_alias(b_path->path[0]->mode, a_path->path[0]->mode)) if (!modes_may_alias(b_path->path[0]->modes, a_path->path[0]->modes))
return nir_derefs_do_not_alias; return nir_derefs_do_not_alias;
if (a_path->path[0]->deref_type != b_path->path[0]->deref_type) if (a_path->path[0]->deref_type != b_path->path[0]->deref_type)
@@ -482,8 +477,8 @@ nir_compare_deref_paths(nir_deref_path *a_path,
*/ */
static const nir_variable_mode temp_var_modes = static const nir_variable_mode temp_var_modes =
nir_var_shader_temp | nir_var_function_temp; nir_var_shader_temp | nir_var_function_temp;
if ((a_path->path[0]->mode & temp_var_modes) || if (!(a_path->path[0]->modes & ~temp_var_modes) ||
(b_path->path[0]->mode & temp_var_modes)) !(b_path->path[0]->modes & ~temp_var_modes))
return nir_derefs_do_not_alias; return nir_derefs_do_not_alias;
/* If they are both declared coherent or have coherent somewhere in /* If they are both declared coherent or have coherent somewhere in
@@ -670,7 +665,7 @@ rematerialize_deref_in_block(nir_deref_instr *deref,
nir_builder *b = &state->builder; nir_builder *b = &state->builder;
nir_deref_instr *new_deref = nir_deref_instr *new_deref =
nir_deref_instr_create(b->shader, deref->deref_type); nir_deref_instr_create(b->shader, deref->deref_type);
new_deref->mode = deref->mode; new_deref->modes = deref->modes;
new_deref->type = deref->type; new_deref->type = deref->type;
if (deref->deref_type == nir_deref_type_var) { if (deref->deref_type == nir_deref_type_var) {

View File

@@ -152,7 +152,7 @@ static uint32_t
hash_deref(uint32_t hash, const nir_deref_instr *instr) hash_deref(uint32_t hash, const nir_deref_instr *instr)
{ {
hash = HASH(hash, instr->deref_type); hash = HASH(hash, instr->deref_type);
hash = HASH(hash, instr->mode); hash = HASH(hash, instr->modes);
hash = HASH(hash, instr->type); hash = HASH(hash, instr->type);
if (instr->deref_type == nir_deref_type_var) if (instr->deref_type == nir_deref_type_var)
@@ -602,7 +602,7 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
nir_deref_instr *deref2 = nir_instr_as_deref(instr2); nir_deref_instr *deref2 = nir_instr_as_deref(instr2);
if (deref1->deref_type != deref2->deref_type || if (deref1->deref_type != deref2->deref_type ||
deref1->mode != deref2->mode || deref1->modes != deref2->modes ||
deref1->type != deref2->type) deref1->type != deref2->type)
return false; return false;

View File

@@ -1097,7 +1097,7 @@ build_explicit_io_load(nir_builder *b, nir_intrinsic_instr *intrin,
unsigned num_components) unsigned num_components)
{ {
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
nir_variable_mode mode = deref->mode; nir_variable_mode mode = deref->modes;
nir_intrinsic_op op; nir_intrinsic_op op;
switch (mode) { switch (mode) {
@@ -1241,7 +1241,7 @@ build_explicit_io_store(nir_builder *b, nir_intrinsic_instr *intrin,
uint32_t align_mul, uint32_t align_offset, uint32_t align_mul, uint32_t align_offset,
nir_ssa_def *value, nir_component_mask_t write_mask) nir_ssa_def *value, nir_component_mask_t write_mask)
{ {
nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->mode; nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->modes;
nir_intrinsic_op op; nir_intrinsic_op op;
switch (mode) { switch (mode) {
@@ -1329,7 +1329,7 @@ static nir_ssa_def *
build_explicit_io_atomic(nir_builder *b, nir_intrinsic_instr *intrin, build_explicit_io_atomic(nir_builder *b, nir_intrinsic_instr *intrin,
nir_ssa_def *addr, nir_address_format addr_format) nir_ssa_def *addr, nir_address_format addr_format)
{ {
nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->mode; nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->modes;
const unsigned num_data_srcs = const unsigned num_data_srcs =
nir_intrinsic_infos[intrin->intrinsic].num_srcs - 1; nir_intrinsic_infos[intrin->intrinsic].num_srcs - 1;

View File

@@ -120,10 +120,10 @@ lower_memcpy_impl(nir_function_impl *impl)
copy_type_for_byte_size(copy_size); copy_type_for_byte_size(copy_size);
nir_deref_instr *copy_dst = nir_deref_instr *copy_dst =
nir_build_deref_cast(&b, &dst->dest.ssa, dst->mode, nir_build_deref_cast(&b, &dst->dest.ssa, dst->modes,
copy_type, copy_size); copy_type, copy_size);
nir_deref_instr *copy_src = nir_deref_instr *copy_src =
nir_build_deref_cast(&b, &src->dest.ssa, src->mode, nir_build_deref_cast(&b, &src->dest.ssa, src->modes,
copy_type, copy_size); copy_type, copy_size);
uint64_t index = offset / copy_size; uint64_t index = offset / copy_size;
@@ -141,10 +141,10 @@ lower_memcpy_impl(nir_function_impl *impl)
* emit a loop which copies one byte at a time. * emit a loop which copies one byte at a time.
*/ */
nir_deref_instr *copy_dst = nir_deref_instr *copy_dst =
nir_build_deref_cast(&b, &dst->dest.ssa, dst->mode, nir_build_deref_cast(&b, &dst->dest.ssa, dst->modes,
glsl_uint8_t_type(), 1); glsl_uint8_t_type(), 1);
nir_deref_instr *copy_src = nir_deref_instr *copy_src =
nir_build_deref_cast(&b, &src->dest.ssa, src->mode, nir_build_deref_cast(&b, &src->dest.ssa, src->modes,
glsl_uint8_t_type(), 1); glsl_uint8_t_type(), 1);
nir_variable *i = nir_local_variable_create(impl, nir_variable *i = nir_local_variable_create(impl,

View File

@@ -31,16 +31,16 @@
#include "shader_enums.h" #include "shader_enums.h"
static bool static bool
get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *mode, get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *modes,
bool *reads, bool *writes) bool *reads, bool *writes)
{ {
switch (intrin->intrinsic) { switch (intrin->intrinsic) {
case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_load:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*reads = true; *reads = true;
break; break;
case nir_intrinsic_image_deref_store: case nir_intrinsic_image_deref_store:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_image_deref_atomic_add: case nir_intrinsic_image_deref_atomic_add:
@@ -53,16 +53,16 @@ get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *mode,
case nir_intrinsic_image_deref_atomic_xor: case nir_intrinsic_image_deref_atomic_xor:
case nir_intrinsic_image_deref_atomic_exchange: case nir_intrinsic_image_deref_atomic_exchange:
case nir_intrinsic_image_deref_atomic_comp_swap: case nir_intrinsic_image_deref_atomic_comp_swap:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*reads = true; *reads = true;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_load_ssbo: case nir_intrinsic_load_ssbo:
*mode = nir_var_mem_ssbo; *modes = nir_var_mem_ssbo;
*reads = true; *reads = true;
break; break;
case nir_intrinsic_store_ssbo: case nir_intrinsic_store_ssbo:
*mode = nir_var_mem_ssbo; *modes = nir_var_mem_ssbo;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_ssbo_atomic_add: case nir_intrinsic_ssbo_atomic_add:
@@ -75,16 +75,16 @@ get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *mode,
case nir_intrinsic_ssbo_atomic_xor: case nir_intrinsic_ssbo_atomic_xor:
case nir_intrinsic_ssbo_atomic_exchange: case nir_intrinsic_ssbo_atomic_exchange:
case nir_intrinsic_ssbo_atomic_comp_swap: case nir_intrinsic_ssbo_atomic_comp_swap:
*mode = nir_var_mem_ssbo; *modes = nir_var_mem_ssbo;
*reads = true; *reads = true;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_load_global: case nir_intrinsic_load_global:
*mode = nir_var_mem_global; *modes = nir_var_mem_global;
*reads = true; *reads = true;
break; break;
case nir_intrinsic_store_global: case nir_intrinsic_store_global:
*mode = nir_var_mem_global; *modes = nir_var_mem_global;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_global_atomic_add: case nir_intrinsic_global_atomic_add:
@@ -97,16 +97,16 @@ get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *mode,
case nir_intrinsic_global_atomic_xor: case nir_intrinsic_global_atomic_xor:
case nir_intrinsic_global_atomic_exchange: case nir_intrinsic_global_atomic_exchange:
case nir_intrinsic_global_atomic_comp_swap: case nir_intrinsic_global_atomic_comp_swap:
*mode = nir_var_mem_global; *modes = nir_var_mem_global;
*reads = true; *reads = true;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_load_deref: case nir_intrinsic_load_deref:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*reads = true; *reads = true;
break; break;
case nir_intrinsic_store_deref: case nir_intrinsic_store_deref:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*writes = true; *writes = true;
break; break;
case nir_intrinsic_deref_atomic_add: case nir_intrinsic_deref_atomic_add:
@@ -119,7 +119,7 @@ get_intrinsic_info(nir_intrinsic_instr *intrin, nir_variable_mode *mode,
case nir_intrinsic_deref_atomic_xor: case nir_intrinsic_deref_atomic_xor:
case nir_intrinsic_deref_atomic_exchange: case nir_intrinsic_deref_atomic_exchange:
case nir_intrinsic_deref_atomic_comp_swap: case nir_intrinsic_deref_atomic_comp_swap:
*mode = nir_src_as_deref(intrin->src[0])->mode; *modes = nir_src_as_deref(intrin->src[0])->modes;
*reads = true; *reads = true;
*writes = true; *writes = true;
break; break;
@@ -149,9 +149,9 @@ visit_instr(nir_instr *instr, uint32_t *cur_modes, unsigned vis_avail_sem)
if (!*cur_modes) if (!*cur_modes)
return false; /* early exit */ return false; /* early exit */
nir_variable_mode mode; nir_variable_mode modes;
bool reads = false, writes = false; bool reads = false, writes = false;
if (!get_intrinsic_info(intrin, &mode, &reads, &writes)) if (!get_intrinsic_info(intrin, &modes, &reads, &writes))
return false; return false;
if (!reads && vis_avail_sem == NIR_MEMORY_MAKE_VISIBLE) if (!reads && vis_avail_sem == NIR_MEMORY_MAKE_VISIBLE)
@@ -167,7 +167,7 @@ visit_instr(nir_instr *instr, uint32_t *cur_modes, unsigned vis_avail_sem)
if (access & (ACCESS_NON_READABLE | ACCESS_NON_WRITEABLE | ACCESS_CAN_REORDER | ACCESS_COHERENT)) if (access & (ACCESS_NON_READABLE | ACCESS_NON_WRITEABLE | ACCESS_CAN_REORDER | ACCESS_COHERENT))
return false; return false;
if (*cur_modes & mode) { if (*cur_modes & modes) {
nir_intrinsic_set_access(intrin, access | ACCESS_COHERENT); nir_intrinsic_set_access(intrin, access | ACCESS_COHERENT);
return true; return true;
} }

View File

@@ -513,8 +513,8 @@ get_variable_mode(struct entry *entry)
{ {
if (entry->info->mode) if (entry->info->mode)
return entry->info->mode; return entry->info->mode;
assert(entry->deref); assert(entry->deref && util_bitcount(entry->deref->modes) == 1);
return entry->deref->mode; return entry->deref->modes;
} }
static unsigned static unsigned
@@ -622,7 +622,7 @@ cast_deref(nir_builder *b, unsigned num_components, unsigned bit_size, nir_deref
if (deref->type == type) if (deref->type == type)
return deref; return deref;
return nir_build_deref_cast(b, &deref->dest.ssa, deref->mode, type, 0); return nir_build_deref_cast(b, &deref->dest.ssa, deref->modes, type, 0);
} }
/* Return true if "new_bit_size" is a usable bit size for a vectorized load/store /* Return true if "new_bit_size" is a usable bit size for a vectorized load/store
@@ -697,7 +697,7 @@ static nir_deref_instr *subtract_deref(nir_builder *b, nir_deref_instr *deref, i
} }
deref = nir_build_deref_cast(b, &deref->dest.ssa, deref->mode, deref = nir_build_deref_cast(b, &deref->dest.ssa, deref->modes,
glsl_scalar_type(GLSL_TYPE_UINT8), 1); glsl_scalar_type(GLSL_TYPE_UINT8), 1);
return nir_build_deref_ptr_as_array( return nir_build_deref_ptr_as_array(
b, deref, nir_imm_intN_t(b, -offset, deref->dest.ssa.bit_size)); b, deref, nir_imm_intN_t(b, -offset, deref->dest.ssa.bit_size));
@@ -1263,7 +1263,7 @@ process_block(nir_function_impl *impl, struct vectorize_ctx *ctx, nir_block *blo
nir_variable_mode mode = info->mode; nir_variable_mode mode = info->mode;
if (!mode) if (!mode)
mode = nir_src_as_deref(intrin->src[info->deref_src])->mode; mode = nir_src_as_deref(intrin->src[info->deref_src])->modes;
if (!(mode & aliasing_modes(ctx->modes))) if (!(mode & aliasing_modes(ctx->modes)))
continue; continue;
unsigned mode_index = mode_to_index(mode); unsigned mode_index = mode_to_index(mode);

View File

@@ -72,7 +72,7 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count,
case nir_intrinsic_load_deref: { case nir_intrinsic_load_deref: {
nir_deref_instr *const deref = nir_src_as_deref(intrin->src[0]); nir_deref_instr *const deref = nir_src_as_deref(intrin->src[0]);
switch (deref->mode) { switch (deref->modes) {
case nir_var_shader_in: case nir_var_shader_in:
case nir_var_uniform: case nir_var_uniform:
/* Don't try to remove flow control around an indirect load /* Don't try to remove flow control around an indirect load

View File

@@ -724,7 +724,7 @@ print_deref_instr(nir_deref_instr *instr, print_state *state)
print_deref_link(instr, false, state); print_deref_link(instr, false, state);
fprintf(fp, " (%s %s) ", fprintf(fp, " (%s %s) ",
get_variable_mode_str(instr->mode, true), get_variable_mode_str(instr->modes, true),
glsl_get_type_name(instr->type)); glsl_get_type_name(instr->type));
if (instr->deref_type != nir_deref_type_var && if (instr->deref_type != nir_deref_type_var &&

View File

@@ -108,17 +108,17 @@ remove_dead_var_writes(nir_shader *shader, struct set *live)
!nir_deref_instr_parent(deref)) !nir_deref_instr_parent(deref))
continue; continue;
nir_variable_mode parent_mode; nir_variable_mode parent_modes;
if (deref->deref_type == nir_deref_type_var) if (deref->deref_type == nir_deref_type_var)
parent_mode = deref->var->data.mode; parent_modes = deref->var->data.mode;
else else
parent_mode = nir_deref_instr_parent(deref)->mode; parent_modes = nir_deref_instr_parent(deref)->modes;
/* If the parent mode is 0, then it references a dead variable. /* If the parent mode is 0, then it references a dead variable.
* Flag this deref as dead and remove it. * Flag this deref as dead and remove it.
*/ */
if (parent_mode == 0) { if (parent_modes == 0) {
deref->mode = 0; deref->modes = 0;
nir_instr_remove(&deref->instr); nir_instr_remove(&deref->instr);
} }
break; break;
@@ -130,7 +130,7 @@ remove_dead_var_writes(nir_shader *shader, struct set *live)
intrin->intrinsic != nir_intrinsic_store_deref) intrin->intrinsic != nir_intrinsic_store_deref)
break; break;
if (nir_src_as_deref(intrin->src[0])->mode == 0) if (nir_src_as_deref(intrin->src[0])->modes == 0)
nir_instr_remove(instr); nir_instr_remove(instr);
break; break;
} }

View File

@@ -125,7 +125,7 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
nir_deref_type_cast); nir_deref_type_cast);
nir_deref_instr *deref = nir_instr_as_deref(def->parent_instr); nir_deref_instr *deref = nir_instr_as_deref(def->parent_instr);
cast->mode = deref->mode; cast->modes = deref->modes;
cast->type = deref->type; cast->type = deref->type;
cast->parent = nir_src_for_ssa(block_def); cast->parent = nir_src_for_ssa(block_def);
cast->cast.ptr_stride = nir_deref_instr_array_stride(deref); cast->cast.ptr_stride = nir_deref_instr_array_stride(deref);

View File

@@ -637,7 +637,7 @@ union packed_instr {
unsigned instr_type:4; unsigned instr_type:4;
unsigned deref_type:3; unsigned deref_type:3;
unsigned cast_type_same_as_last:1; unsigned cast_type_same_as_last:1;
unsigned mode:12; /* deref_var redefines this */ unsigned modes:12; /* deref_var redefines this */
unsigned packed_src_ssa_16bit:1; /* deref_var redefines this */ unsigned packed_src_ssa_16bit:1; /* deref_var redefines this */
unsigned _pad:3; /* deref_var redefines this */ unsigned _pad:3; /* deref_var redefines this */
unsigned dest:8; unsigned dest:8;
@@ -984,7 +984,7 @@ static void
write_deref(write_ctx *ctx, const nir_deref_instr *deref) write_deref(write_ctx *ctx, const nir_deref_instr *deref)
{ {
assert(deref->deref_type < 8); assert(deref->deref_type < 8);
assert(deref->mode < (1 << 12)); assert(deref->modes < (1 << 12));
union packed_instr header; union packed_instr header;
header.u32 = 0; header.u32 = 0;
@@ -993,7 +993,7 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref)
header.deref.deref_type = deref->deref_type; header.deref.deref_type = deref->deref_type;
if (deref->deref_type == nir_deref_type_cast) { if (deref->deref_type == nir_deref_type_cast) {
header.deref.mode = deref->mode; header.deref.modes = deref->modes;
header.deref.cast_type_same_as_last = deref->type == ctx->last_type; header.deref.cast_type_same_as_last = deref->type == ctx->last_type;
} }
@@ -1127,12 +1127,12 @@ read_deref(read_ctx *ctx, union packed_instr header)
} }
if (deref_type == nir_deref_type_var) { if (deref_type == nir_deref_type_var) {
deref->mode = deref->var->data.mode; deref->modes = deref->var->data.mode;
} else if (deref->deref_type == nir_deref_type_cast) { } else if (deref->deref_type == nir_deref_type_cast) {
deref->mode = header.deref.mode; deref->modes = header.deref.modes;
} else { } else {
assert(deref->parent.is_ssa); assert(deref->parent.is_ssa);
deref->mode = nir_instr_as_deref(deref->parent.ssa->parent_instr)->mode; deref->modes = nir_instr_as_deref(deref->parent.ssa->parent_instr)->modes;
} }
return deref; return deref;

View File

@@ -250,7 +250,7 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
nir_deref_instr_create(state->shader, nir_deref_type_cast); nir_deref_instr_create(state->shader, nir_deref_type_cast);
nir_deref_instr *instr = nir_instr_as_deref(def->parent_instr); nir_deref_instr *instr = nir_instr_as_deref(def->parent_instr);
cast->mode = instr->mode; cast->modes = instr->modes;
cast->type = instr->type; cast->type = instr->type;
cast->parent = nir_src_for_ssa(&phi->dest.ssa); cast->parent = nir_src_for_ssa(&phi->dest.ssa);
cast->cast.ptr_stride = nir_deref_instr_array_stride(instr); cast->cast.ptr_stride = nir_deref_instr_array_stride(instr);

View File

@@ -407,9 +407,11 @@ validate_var_use(nir_variable *var, validate_state *state)
static void static void
validate_deref_instr(nir_deref_instr *instr, validate_state *state) validate_deref_instr(nir_deref_instr *instr, validate_state *state)
{ {
validate_assert(state, util_bitcount(instr->modes) == 1);
if (instr->deref_type == nir_deref_type_var) { if (instr->deref_type == nir_deref_type_var) {
/* Variable dereferences are stupid simple. */ /* Variable dereferences are stupid simple. */
validate_assert(state, instr->mode == instr->var->data.mode); validate_assert(state, instr->modes == instr->var->data.mode);
validate_assert(state, instr->type == instr->var->type); validate_assert(state, instr->type == instr->var->type);
validate_var_use(instr->var, state); validate_var_use(instr->var, state);
} else if (instr->deref_type == nir_deref_type_cast) { } else if (instr->deref_type == nir_deref_type_cast) {
@@ -419,7 +421,7 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state)
validate_src(&instr->parent, state, 0, 0); validate_src(&instr->parent, state, 0, 0);
/* We just validate that the type and mode are there */ /* We just validate that the type and mode are there */
validate_assert(state, instr->mode); validate_assert(state, instr->modes);
validate_assert(state, instr->type); validate_assert(state, instr->type);
if (instr->cast.align_mul > 0) { if (instr->cast.align_mul > 0) {
validate_assert(state, util_is_power_of_two_nonzero(instr->cast.align_mul)); validate_assert(state, util_is_power_of_two_nonzero(instr->cast.align_mul));
@@ -444,7 +446,7 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state)
nir_deref_instr *parent = nir_instr_as_deref(parent_instr); nir_deref_instr *parent = nir_instr_as_deref(parent_instr);
validate_assert(state, instr->mode == parent->mode); validate_assert(state, instr->modes == parent->modes);
switch (instr->deref_type) { switch (instr->deref_type) {
case nir_deref_type_struct: case nir_deref_type_struct:
@@ -457,11 +459,9 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state)
case nir_deref_type_array: case nir_deref_type_array:
case nir_deref_type_array_wildcard: case nir_deref_type_array_wildcard:
if (instr->mode == nir_var_mem_ubo || if (instr->modes & (nir_var_mem_ubo | nir_var_mem_ssbo |
instr->mode == nir_var_mem_ssbo || nir_var_mem_shared | nir_var_mem_global |
instr->mode == nir_var_mem_shared || nir_var_mem_push_const)) {
instr->mode == nir_var_mem_global ||
instr->mode == nir_var_mem_push_const) {
/* Shared variables and UBO/SSBOs have a bit more relaxed rules /* Shared variables and UBO/SSBOs have a bit more relaxed rules
* because we need to be able to handle array derefs on vectors. * because we need to be able to handle array derefs on vectors.
* Fortunately, nir_lower_io handles these just fine. * Fortunately, nir_lower_io handles these just fine.
@@ -518,10 +518,10 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state)
*/ */
nir_foreach_use(use, &instr->dest.ssa) { nir_foreach_use(use, &instr->dest.ssa) {
if (use->parent_instr->type == nir_instr_type_phi) { if (use->parent_instr->type == nir_instr_type_phi) {
validate_assert(state, instr->mode != nir_var_shader_in && validate_assert(state, !(instr->modes & (nir_var_shader_in |
instr->mode != nir_var_shader_out && nir_var_shader_out |
instr->mode != nir_var_shader_out && nir_var_shader_out |
instr->mode != nir_var_uniform); nir_var_uniform)));
} }
} }
} }
@@ -570,7 +570,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
nir_deref_instr *src = nir_src_as_deref(instr->src[0]); nir_deref_instr *src = nir_src_as_deref(instr->src[0]);
assert(src); assert(src);
validate_assert(state, glsl_type_is_vector_or_scalar(src->type) || validate_assert(state, glsl_type_is_vector_or_scalar(src->type) ||
(src->mode == nir_var_uniform && (src->modes == nir_var_uniform &&
glsl_get_base_type(src->type) == GLSL_TYPE_SUBROUTINE)); glsl_get_base_type(src->type) == GLSL_TYPE_SUBROUTINE));
validate_assert(state, instr->num_components == validate_assert(state, instr->num_components ==
glsl_get_vector_elements(src->type)); glsl_get_vector_elements(src->type));

View File

@@ -430,7 +430,7 @@ vtn_pointer_dereference(struct vtn_builder *b,
/* We start with a deref cast to get the stride. Hopefully, we'll be /* We start with a deref cast to get the stride. Hopefully, we'll be
* able to delete that cast eventually. * able to delete that cast eventually.
*/ */
tail = nir_build_deref_cast(&b->nb, &tail->dest.ssa, tail->mode, tail = nir_build_deref_cast(&b->nb, &tail->dest.ssa, tail->modes,
tail->type, base->ptr_type->stride); tail->type, base->ptr_type->stride);
nir_ssa_def *index = vtn_access_link_as_ssa(b, deref_chain->link[0], 1, nir_ssa_def *index = vtn_access_link_as_ssa(b, deref_chain->link[0], 1,

View File

@@ -1129,7 +1129,8 @@ static void visit_load_var(struct lp_build_nir_context *bld_base,
{ {
nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr); nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
nir_variable *var = nir_deref_instr_get_variable(deref); nir_variable *var = nir_deref_instr_get_variable(deref);
nir_variable_mode mode = deref->mode; assert(util_bitcount(deref->modes) == 1);
nir_variable_mode mode = deref->modes;
unsigned const_index; unsigned const_index;
LLVMValueRef indir_index; LLVMValueRef indir_index;
LLVMValueRef indir_vertex_index = NULL; LLVMValueRef indir_vertex_index = NULL;
@@ -1162,7 +1163,8 @@ visit_store_var(struct lp_build_nir_context *bld_base,
{ {
nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr); nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
nir_variable *var = nir_deref_instr_get_variable(deref); nir_variable *var = nir_deref_instr_get_variable(deref);
nir_variable_mode mode = deref->mode; assert(util_bitcount(deref->modes) == 1);
nir_variable_mode mode = deref->modes;
int writemask = instr->const_index[0]; int writemask = instr->const_index[0];
unsigned bit_size = nir_src_bit_size(instr->src[1]); unsigned bit_size = nir_src_bit_size(instr->src[1]);
LLVMValueRef src = get_src(bld_base, instr->src[1]); LLVMValueRef src = get_src(bld_base, instr->src[1]);

View File

@@ -311,7 +311,8 @@ void ShaderFromNirProcessor::set_var_address(nir_deref_instr *instr)
{ {
auto& dest = instr->dest; auto& dest = instr->dest;
unsigned index = dest.is_ssa ? dest.ssa.index : dest.reg.reg->index; unsigned index = dest.is_ssa ? dest.ssa.index : dest.reg.reg->index;
m_var_mode[instr->var] = instr->mode; assert(util_bitcount(instr->modes) == 1);
m_var_mode[instr->var] = instr->modes;
m_var_derefs[index] = instr->var; m_var_derefs[index] = instr->var;
sfn_log << SfnLog::io << "Add var deref:" << index sfn_log << SfnLog::io << "Add var deref:" << index