diff mbox series

[1/3,RFC] Add MEM_BASE

Message ID 20240209102827.EDECB3858283@sourceware.org
State New
Headers show
Series [1/3,RFC] Add MEM_BASE | expand

Commit Message

Richard Biener Feb. 9, 2024, 10:28 a.m. UTC
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 mbox series

Patch

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)