The following adds a 'base' member to the RTL memory attributes, recording the base value as base_alias_check expects and currently find_base_{value,term} compute. It is expected to either contain a SYMBOL_REF or a special ADDRESS, see base_alias_check for reference.
With this patch nothing sets MEM_BASE but RTL alias analysis would prefer any recorded MEM_BASE over dynamically computing it. * rtl.h (mem_attrs::base): New member. (MEM_BASE): New. * emit-rtl.h (set_mem_base): Declare. * emit-rtl.cc (mem_attrs_eq_p): Handle MEM_BASE. (mem_attrs::mem_attrs): Initialize it. (set_mem_attributes_minus_bitpos): Preserve it. (set_mem_base): New function. * alias.cc (true_dependence_1): Prefer MEM_BASE over using find_base_term. (write_dependence_p): Likewise. (may_alias_p): Likewise. * print-rtl.cc (rtx_writer::print_rtx): Print MEM_BASE. --- gcc/alias.cc | 26 ++++++++++++++++++-------- gcc/emit-rtl.cc | 18 +++++++++++++++++- gcc/emit-rtl.h | 3 +++ gcc/print-rtl.cc | 6 ++++++ gcc/rtl.h | 7 +++++++ 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/gcc/alias.cc b/gcc/alias.cc index 808e2095d9b..48633aff699 100644 --- a/gcc/alias.cc +++ b/gcc/alias.cc @@ -2934,7 +2934,6 @@ true_dependence_1 (const_rtx mem, machine_mode mem_mode, rtx mem_addr, const_rtx x, rtx x_addr, bool mem_canonicalized) { rtx true_mem_addr; - rtx base; int ret; gcc_checking_assert (mem_canonicalized ? (mem_addr != NULL_RTX) @@ -2981,13 +2980,17 @@ true_dependence_1 (const_rtx mem, machine_mode mem_mode, rtx mem_addr, if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return true; - base = find_base_term (x_addr); + rtx base = MEM_BASE (x); + if (!base) + base = find_base_term (x_addr); if (base && (GET_CODE (base) == LABEL_REF || (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base)))) return false; - rtx mem_base = find_base_term (true_mem_addr); + rtx mem_base = MEM_BASE (mem); + if (!mem_base) + mem_base = find_base_term (true_mem_addr); if (! base_alias_check (x_addr, base, true_mem_addr, mem_base, GET_MODE (x), mem_mode)) return false; @@ -3045,7 +3048,6 @@ write_dependence_p (const_rtx mem, { rtx mem_addr; rtx true_mem_addr, true_x_addr; - rtx base; int ret; gcc_checking_assert (x_canonicalized @@ -3088,7 +3090,9 @@ write_dependence_p (const_rtx mem, if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return true; - base = find_base_term (true_mem_addr); + rtx base = MEM_BASE (mem); + if (!base) + base = find_base_term (true_mem_addr); if (! writep && base && (GET_CODE (base) == LABEL_REF @@ -3096,7 +3100,9 @@ write_dependence_p (const_rtx mem, && CONSTANT_POOL_ADDRESS_P (base)))) return false; - rtx x_base = find_base_term (true_x_addr); + rtx x_base = MEM_BASE (x); + if (!x_base) + x_base = find_base_term (true_x_addr); if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base, GET_MODE (x), GET_MODE (mem))) return false; @@ -3211,8 +3217,12 @@ may_alias_p (const_rtx mem, const_rtx x) if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return true; - rtx x_base = find_base_term (x_addr); - rtx mem_base = find_base_term (mem_addr); + rtx x_base = MEM_BASE (x); + if (!x_base) + x_base = find_base_term (x_addr); + rtx mem_base = MEM_BASE (mem); + if (!mem_base) + mem_base = find_base_term (mem_addr); if (! base_alias_check (x_addr, x_base, mem_addr, mem_base, GET_MODE (x), GET_MODE (mem_addr))) return false; diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc index 1856fa4884f..1cf238d9571 100644 --- a/gcc/emit-rtl.cc +++ b/gcc/emit-rtl.cc @@ -368,7 +368,10 @@ mem_attrs_eq_p (const class mem_attrs *p, const class mem_attrs *q) && p->addrspace == q->addrspace && (p->expr == q->expr || (p->expr != NULL_TREE && q->expr != NULL_TREE - && operand_equal_p (p->expr, q->expr, 0)))); + && operand_equal_p (p->expr, q->expr, 0))) + && (p->base == q->base + || (p->base != NULL_RTX && q->base != NULL_RTX + && rtx_equal_p (p->base, q->base)))); } /* Set MEM's memory attributes so that they are the same as ATTRS. */ @@ -1828,6 +1831,7 @@ operand_subword_force (rtx op, poly_uint64 offset, machine_mode mode) mem_attrs::mem_attrs () : expr (NULL_TREE), + base (NULL_RTX), offset (0), size (0), alias (0), @@ -1985,6 +1989,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, /* ??? Can this ever happen? Calling this routine on a MEM that already carries memory attributes should probably be invalid. */ attrs.expr = refattrs->expr; + attrs.base = refattrs->base; attrs.offset_known_p = refattrs->offset_known_p; attrs.offset = refattrs->offset; attrs.size_known_p = refattrs->size_known_p; @@ -1997,6 +2002,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, { defattrs = mode_mem_attrs[(int) GET_MODE (ref)]; gcc_assert (!defattrs->expr); + gcc_assert (!defattrs->base); gcc_assert (!defattrs->offset_known_p); /* Respect mode size. */ @@ -2264,6 +2270,16 @@ clear_mem_size (rtx mem) attrs.size_known_p = false; set_mem_attrs (mem, &attrs); } + +/* Set the BASE of MEM. */ + +void +set_mem_base (rtx mem, rtx base) +{ + mem_attrs attrs (*get_mem_attrs (mem)); + attrs.base = base; + set_mem_attrs (mem, &attrs); +} /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR. (VOIDmode means don't change the mode. diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index 34f44cb2990..d7c307c9da0 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -361,6 +361,9 @@ extern void set_mem_addr_space (rtx, addr_space_t); /* Set the expr for MEM to EXPR. */ extern void set_mem_expr (rtx, tree); +/* Set the base for MEM to BASE. */ +extern void set_mem_base (rtx, rtx); + /* Set the offset for MEM to OFFSET. */ extern void set_mem_offset (rtx, poly_int64); diff --git a/gcc/print-rtl.cc b/gcc/print-rtl.cc index ecb689f56a9..3d7ea8dd59e 100644 --- a/gcc/print-rtl.cc +++ b/gcc/print-rtl.cc @@ -974,6 +974,12 @@ rtx_writer::print_rtx (const_rtx in_rtx) if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx))) fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx)); + if (MEM_BASE (in_rtx)) + { + fputc (' ', m_outfile); + print_rtx (MEM_BASE (in_rtx)); + } + fputc (']', m_outfile); break; diff --git a/gcc/rtl.h b/gcc/rtl.h index 2370d608161..c84334cb945 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -159,6 +159,10 @@ public: (In other words, the MEM might access only part of the object.) */ tree expr; + /* A unique base this MEM accesses. This can be a SYMBOL_REF or + an ADDRESS RTX. */ + rtx base; + /* The offset of the memory reference from the start of EXPR. Only valid if OFFSET_KNOWN_P. */ poly_int64 offset; @@ -2643,6 +2647,9 @@ do { \ refer to part of a DECL. It may also be a COMPONENT_REF. */ #define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr) +/* For a MEM rtx, the ADDRESS or SYMBOL_REF it is based on. */ +#define MEM_BASE(RTX) (get_mem_attrs (RTX)->base) + /* For a MEM rtx, true if its MEM_OFFSET is known. */ #define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset_known_p) -- 2.35.3