Mesa (master): nir/deref: fix struct wrapper casts. (v3)

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 28 22:12:02 UTC 2019


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Mar  8 13:09:05 2019 +1000

nir/deref: fix struct wrapper casts. (v3)

llvm/spir-v spits out some struct a { struct b {} }, but it
doesn't deref, it casts (struct a) to (struct b), reconstruct
struct derefs instead of casts for these.

v2: use ssa_def_rewrite uses, rework the type restrictions (Jason)
v3: squish more stuff into one function, drop unused temp (Jason)

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/compiler/nir/nir_deref.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 174c4a3280e..460d3bf4656 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -697,11 +697,45 @@ opt_remove_cast_cast(nir_deref_instr *cast)
    return true;
 }
 
+/**
+ * Is this casting a struct to a contained struct.
+ * struct a { struct b field0 };
+ * ssa_5 is structa;
+ * deref_cast (structb *)ssa_5 (function_temp structb);
+ * converts to
+ * deref_struct &ssa_5->field0 (function_temp structb);
+ * This allows subsequent copy propagation to work.
+ */
+static bool
+opt_replace_struct_wrapper_cast(nir_builder *b, nir_deref_instr *cast)
+{
+   nir_deref_instr *parent = nir_src_as_deref(cast->parent);
+   if (!parent)
+      return false;
+
+   if (!glsl_type_is_struct(parent->type))
+      return false;
+
+   if (glsl_get_struct_field_offset(parent->type, 0) != 0)
+      return false;
+
+   if (cast->type != glsl_get_struct_field(parent->type, 0))
+      return false;
+
+   nir_deref_instr *replace = nir_build_deref_struct(b, parent, 0);
+   nir_ssa_def_rewrite_uses(&cast->dest.ssa, nir_src_for_ssa(&replace->dest.ssa));
+   nir_deref_instr_remove_if_unused(cast);
+   return true;
+}
+
 static bool
-opt_deref_cast(nir_deref_instr *cast)
+opt_deref_cast(nir_builder *b, nir_deref_instr *cast)
 {
    bool progress;
 
+   if (opt_replace_struct_wrapper_cast(b, cast))
+      return true;
+
    progress = opt_remove_cast_cast(cast);
    if (!is_trivial_deref_cast(cast))
       return progress;
@@ -798,7 +832,7 @@ nir_opt_deref_impl(nir_function_impl *impl)
             break;
 
          case nir_deref_type_cast:
-            if (opt_deref_cast(deref))
+            if (opt_deref_cast(&b, deref))
                progress = true;
             break;
 




More information about the mesa-commit mailing list