Mesa (main): nir,spirv: Preserve inbounds access information

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 17:07:31 UTC 2022


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

Author: Konstantin Seurer <konstantin.seurer at gmail.com>
Date:   Thu May 26 21:12:33 2022 +0200

nir,spirv: Preserve inbounds access information

Preserving information about inbounds access and
the required bit size for the bounds will help
with avoiding 64-bit operations when lowering io.

Signed-off-by: Konstantin Seurer <konstantin.seurer at gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16729>

---

 src/compiler/nir/nir.h             | 1 +
 src/compiler/nir/nir_clone.c       | 1 +
 src/compiler/nir/nir_deref.c       | 2 ++
 src/compiler/nir/nir_instr_set.c   | 3 +++
 src/compiler/nir/nir_serialize.c   | 7 ++++++-
 src/compiler/spirv/vtn_private.h   | 2 ++
 src/compiler/spirv/vtn_variables.c | 3 +++
 7 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 295ab30f24c..b6387fd398e 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1531,6 +1531,7 @@ typedef struct {
    union {
       struct {
          nir_src index;
+         bool in_bounds;
       } arr;
 
       struct {
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c
index 0a58f328507..ee509da06e2 100644
--- a/src/compiler/nir/nir_clone.c
+++ b/src/compiler/nir/nir_clone.c
@@ -331,6 +331,7 @@ clone_deref_instr(clone_state *state, const nir_deref_instr *deref)
    case nir_deref_type_ptr_as_array:
       __clone_src(state, &nderef->instr,
                   &nderef->arr.index, &deref->arr.index);
+      nderef->arr.in_bounds = deref->arr.in_bounds;
       break;
 
    case nir_deref_type_array_wildcard:
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index bb1bb91fdc7..f9d599c02d5 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -1219,6 +1219,8 @@ opt_deref_ptr_as_array(nir_builder *b, nir_deref_instr *deref)
    assert(parent->arr.index.is_ssa);
    assert(deref->arr.index.is_ssa);
 
+   deref->arr.in_bounds &= parent->arr.in_bounds;
+
    nir_ssa_def *new_idx = nir_iadd(b, parent->arr.index.ssa,
                                       deref->arr.index.ssa);
 
diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c
index 443928136fb..9ce5793594e 100644
--- a/src/compiler/nir/nir_instr_set.c
+++ b/src/compiler/nir/nir_instr_set.c
@@ -168,6 +168,7 @@ hash_deref(uint32_t hash, const nir_deref_instr *instr)
    case nir_deref_type_array:
    case nir_deref_type_ptr_as_array:
       hash = hash_src(hash, &instr->arr.index);
+      hash = HASH(hash, instr->arr.in_bounds);
       break;
 
    case nir_deref_type_cast:
@@ -623,6 +624,8 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
       case nir_deref_type_ptr_as_array:
          if (!nir_srcs_equal(deref1->arr.index, deref2->arr.index))
             return false;
+         if (deref1->arr.in_bounds != deref2->arr.in_bounds)
+            return false;
          break;
 
       case nir_deref_type_cast:
diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c
index 4c12afbba87..bd69225dd19 100644
--- a/src/compiler/nir/nir_serialize.c
+++ b/src/compiler/nir/nir_serialize.c
@@ -630,7 +630,8 @@ union packed_instr {
       unsigned deref_type:3;
       unsigned cast_type_same_as_last:1;
       unsigned modes:5; /* See (de|en)code_deref_modes() */
-      unsigned _pad:10;
+      unsigned _pad:9;
+      unsigned in_bounds:1;
       unsigned packed_src_ssa_16bit:1; /* deref_var redefines this */
       unsigned dest:8;
    } deref;
@@ -1039,6 +1040,8 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref)
       header.deref.packed_src_ssa_16bit =
          deref->parent.is_ssa && deref->arr.index.is_ssa &&
          are_object_ids_16bit(ctx);
+
+      header.deref.in_bounds = deref->arr.in_bounds;
    }
 
    write_dest(ctx, &deref->dest, header, deref->instr.type);
@@ -1126,6 +1129,8 @@ read_deref(read_ctx *ctx, union packed_instr header)
          read_src(ctx, &deref->arr.index, &deref->instr);
       }
 
+      deref->arr.in_bounds = header.deref.in_bounds;
+
       parent = nir_src_as_deref(deref->parent);
       if (deref->deref_type == nir_deref_type_array)
          deref->type = glsl_get_array_element(parent->type);
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 6a9d1394760..b4b0513ee07 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -481,6 +481,8 @@ struct vtn_access_chain {
    /* Access qualifiers */
    enum gl_access_qualifier access;
 
+   bool in_bounds;
+
    /** Struct elements and array offsets.
     *
     * This is an array of 1 so that it can conveniently be created on the
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index e8161e2e565..0eb7f60b24c 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -459,6 +459,7 @@ vtn_pointer_dereference(struct vtn_builder *b,
          tail = nir_build_deref_array(&b->nb, tail, arr_index);
          type = type->array_element;
       }
+      tail->arr.in_bounds = deref_chain->in_bounds;
 
       access |= type->access;
    }
@@ -2464,6 +2465,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
 
       struct vtn_pointer *base = vtn_pointer(b, w[3]);
 
+      chain->in_bounds = (opcode == SpvOpInBoundsAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
+
       /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
       access |= base->access & ACCESS_NON_UNIFORM;
 



More information about the mesa-commit mailing list