mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 12:50:10 +01:00
nir: Make nir_deref_path_init skip trivial casts
In a NIR generated using SPIR-V initializers to variables, copy
propagation can end up transforming
vec1 32 ssa_33 = deref_var &@1 (shared mat2x4)
vec1 32 ssa_35 = mov ssa_33
vec1 32 ssa_7 = deref_cast (mat2x4 *)ssa_35 (shared mat2x4) /* ptr_stride=0 */
into
vec1 32 ssa_33 = deref_var &@1 (shared mat2x4)
vec1 32 ssa_7 = deref_cast (mat2x4 *)ssa_33 (shared mat2x4) /* ptr_stride=0 */
Before the optimization, the "head" of a path of deref that uses ssa_7
will be the cast. After, it will be the variable in ssa_33. Since
the types are the same, this is a trivial cast that would be picked up
by nir_opt_deref.
If we need to compare such deref-chain after optimization with another
deref-chain for the same variable, the compare function will get
confused by the cast in the middle.
One alternative would be to add nir_opt_deref to places that compare
derefs, but that might not scale well, so skip the trivial casts when
generating the paths instead.
Motivated by the discussion in
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3047#note_383660.
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3420>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3420>
This commit is contained in:
parent
db19e96c8c
commit
8548fe19f0
1 changed files with 19 additions and 14 deletions
|
|
@ -26,6 +26,19 @@
|
|||
#include "nir_deref.h"
|
||||
#include "util/hash_table.h"
|
||||
|
||||
static bool
|
||||
is_trivial_deref_cast(nir_deref_instr *cast)
|
||||
{
|
||||
nir_deref_instr *parent = nir_src_as_deref(cast->parent);
|
||||
if (!parent)
|
||||
return false;
|
||||
|
||||
return cast->mode == parent->mode &&
|
||||
cast->type == parent->type &&
|
||||
cast->dest.ssa.num_components == parent->dest.ssa.num_components &&
|
||||
cast->dest.ssa.bit_size == parent->dest.ssa.bit_size;
|
||||
}
|
||||
|
||||
void
|
||||
nir_deref_path_init(nir_deref_path *path,
|
||||
nir_deref_instr *deref, void *mem_ctx)
|
||||
|
|
@ -44,6 +57,8 @@ nir_deref_path_init(nir_deref_path *path,
|
|||
|
||||
*tail = NULL;
|
||||
for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
|
||||
if (d->deref_type == nir_deref_type_cast && is_trivial_deref_cast(d))
|
||||
continue;
|
||||
count++;
|
||||
if (count <= max_short_path_len)
|
||||
*(--head) = d;
|
||||
|
|
@ -64,8 +79,11 @@ nir_deref_path_init(nir_deref_path *path,
|
|||
path->path = ralloc_array(mem_ctx, nir_deref_instr *, count + 1);
|
||||
head = tail = path->path + count;
|
||||
*tail = NULL;
|
||||
for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d))
|
||||
for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
|
||||
if (d->deref_type == nir_deref_type_cast && is_trivial_deref_cast(d))
|
||||
continue;
|
||||
*(--head) = d;
|
||||
}
|
||||
|
||||
done:
|
||||
assert(head == path->path);
|
||||
|
|
@ -735,19 +753,6 @@ nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl)
|
|||
return state.progress;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_trivial_deref_cast(nir_deref_instr *cast)
|
||||
{
|
||||
nir_deref_instr *parent = nir_src_as_deref(cast->parent);
|
||||
if (!parent)
|
||||
return false;
|
||||
|
||||
return cast->mode == parent->mode &&
|
||||
cast->type == parent->type &&
|
||||
cast->dest.ssa.num_components == parent->dest.ssa.num_components &&
|
||||
cast->dest.ssa.bit_size == parent->dest.ssa.bit_size;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_trivial_array_deref_cast(nir_deref_instr *cast)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue