On Tue, Sep 22, 2015 at 12:45 PM, Simon Dardis <simon.dar...@imgtec.com> wrote: > I took an attempt at addressing this through the RTL GCSE pass. This attempt > tweaks > mem_attrs_eq_p to return true if its comparing something like poly+8 and MEM > [&poly + 8]. > > Is this a more suitable approach?
I actually recently modified stmt_kills_ref_p for a similar reason... not that I liked that vey much. I think the more suitable approach would be to not have both forms if they are actually equal. Of course that's way more work. So splitting out a function that handles sematic equality compare of MEM_EXPR sounds good to me. No comments on your actual implementation yet, but I think we should do it in a way to be re-usable by stmt_kills_ref_p. Richard. > Thanks, > Simon > > +/* Return true if p and q reference the same location by the same name but > + through VAR_DECL and MEM_REF. */ > + > +static bool > +mem_locations_match_p (const struct mem_attrs *p, const struct mem_attrs *q) > +{ > + HOST_WIDE_INT var_offset; > + tree var, memref; > + > + if (p->expr == NULL_TREE || q->expr == NULL_TREE) > + return false; > + > + if (TREE_CODE (p->expr) == MEM_REF && TREE_CODE (q->expr) == VAR_DECL) > + { > + var = q->expr; > + var_offset = q->offset; > + memref = p->expr; > + } > + else if (TREE_CODE (q->expr) == MEM_REF && TREE_CODE (p->expr) == VAR_DECL) > + { > + var = p->expr; > + var_offset = p->offset; > + memref = q->expr; > + } > + else > + return false; > + > + if (TREE_OPERAND (TREE_OPERAND (memref, 0), 0) != var) > + return false; > + > + if (TREE_TYPE (TREE_TYPE (var)) != TREE_TYPE (memref)) > + return false; > + > + tree offset = TREE_OPERAND (memref, 1); > + if ((TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset) > + && tree_to_shwi (offset) == var_offset) > + || offset == NULL_TREE && var_offset == 0) > + return true; > + > + return false; > + > +} > + > /* Return true if the given memory attributes are equal. */ > > bool > @@ -254,16 +298,16 @@ mem_attrs_eq_p (const struct mem_attrs *p, const struct > mem_attrs *q) > return false; > return (p->alias == q->alias > && p->offset_known_p == q->offset_known_p > - && (!p->offset_known_p || p->offset == q->offset) > && p->size_known_p == q->size_known_p > && (!p->size_known_p || p->size == q->size) > && p->align == q->align > && p->addrspace == q->addrspace > - && (p->expr == q->expr > - || (p->expr != NULL_TREE && q->expr != NULL_TREE > - && operand_equal_p (p->expr, q->expr, 0)))); > + && (mem_locations_match_p (p, q) > + || (!p->offset_known_p || p->offset == q->offset) > + && (p->expr == q->expr > + || (p->expr != NULL_TREE && q->expr != NULL_TREE > + && operand_equal_p (p->expr, q->expr, 0))))); > }