diff options
author | Dave Airlie <[email protected]> | 2019-03-05 15:14:29 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2019-03-21 10:58:06 +1000 |
commit | b95b33a5c777e6c2cb378fb6d4e257b50c3a5a4d (patch) | |
tree | 3a635129ecc414b9f777647c5cad7111feaf7f67 | |
parent | 3b3653c4cfbedf55a00cbddd0f341ebd1de81665 (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.c | 28 |
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. |