summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2019-03-05 15:14:29 +1000
committerDave Airlie <[email protected]>2019-03-21 10:58:06 +1000
commitb95b33a5c777e6c2cb378fb6d4e257b50c3a5a4d (patch)
tree3a635129ecc414b9f777647c5cad7111feaf7f67
parent3b3653c4cfbedf55a00cbddd0f341ebd1de81665 (diff)
nir/deref: remove casts of casts which are likely redundant (v3)
Not sure how ptr_stride should be taken into account if at all here v2: reorder check to avoid src walking (Jason) v3: remove is_cast_cast checks, keep going afterwards (Jason) Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r--src/compiler/nir/nir_deref.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 14d8804c389..174c4a3280e 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -675,18 +675,42 @@ is_deref_ptr_as_array(nir_instr *instr)
nir_instr_as_deref(instr)->deref_type == nir_deref_type_ptr_as_array;
}
+/**
+ * Remove casts that just wrap other casts.
+ */
+static bool
+opt_remove_cast_cast(nir_deref_instr *cast)
+{
+ nir_deref_instr *first_cast = cast;
+
+ while (true) {
+ nir_deref_instr *parent = nir_deref_instr_parent(first_cast);
+ if (parent == NULL || parent->deref_type != nir_deref_type_cast)
+ break;
+ first_cast = parent;
+ }
+ if (cast == first_cast)
+ return false;
+
+ nir_instr_rewrite_src(&cast->instr, &cast->parent,
+ nir_src_for_ssa(first_cast->parent.ssa));
+ return true;
+}
+
static bool
opt_deref_cast(nir_deref_instr *cast)
{
+ bool progress;
+
+ progress = opt_remove_cast_cast(cast);
if (!is_trivial_deref_cast(cast))
- return false;
+ return progress;
bool trivial_array_cast = is_trivial_array_deref_cast(cast);
assert(cast->dest.is_ssa);
assert(cast->parent.is_ssa);
- bool progress = false;
nir_foreach_use_safe(use_src, &cast->dest.ssa) {
/* If this isn't a trivial array cast, we can't propagate into
* ptr_as_array derefs.