public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Add is_capability argument to addr_space hooks
@ 2022-05-05 12:04 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-05 12:04 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:12cd31ada5eecb72724ad76425ced56d9aca10aa

commit 12cd31ada5eecb72724ad76425ced56d9aca10aa
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Fri Mar 4 17:24:05 2022 +0000

    Add is_capability argument to addr_space hooks
    
    This patch changes the interface of:
    
    * targetm.addr_space.pointer_mode
    * targetm.addr_space.address_mode
    
    so that they take a boolean flag that indicates whether the
    pointer/address is a capability.  The patch also adds various
    helper functions that hopefully make the choice easier.

Diff:
---
 gcc/auto-inc-dec.c         |  6 ++----
 gcc/builtins.c             | 11 +++++++----
 gcc/c/c-decl.c             |  3 +--
 gcc/cfgexpand.c            | 11 ++++++-----
 gcc/config/avr/avr.c       |  4 ++--
 gcc/config/ft32/ft32.c     | 16 ----------------
 gcc/config/gcn/gcn.c       |  4 ++--
 gcc/config/m32c/m32c.c     |  4 ++--
 gcc/config/msp430/msp430.c |  2 +-
 gcc/config/rl78/rl78.c     |  4 ++--
 gcc/doc/tm.texi            | 16 ++++++++++++----
 gcc/emit-rtl.c             |  8 ++++----
 gcc/explow.c               | 10 +++++-----
 gcc/expr.c                 | 19 ++++++++++---------
 gcc/recog.c                |  2 +-
 gcc/rtl.h                  | 27 ++++++++++++++++++++++++++-
 gcc/rtlanal.c              |  2 +-
 gcc/target.def             | 16 ++++++++++++----
 gcc/target.h               | 28 ++++++++++++++++++++++++++++
 gcc/targhooks.c            | 12 ++++++++++--
 gcc/targhooks.h            |  4 ++--
 gcc/tree-ssa-address.c     | 23 +++++++++++++++++++----
 gcc/tree-ssa-address.h     |  2 ++
 gcc/tree-ssa-loop-ivopts.c |  7 ++++---
 gcc/tree.c                 | 46 ++++++++++++++++++++++++++++++++++++++++------
 gcc/tree.h                 |  4 ++++
 gcc/varasm.c               |  7 +------
 27 files changed, 206 insertions(+), 92 deletions(-)

diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 7d0d91403f3..38be4c98484 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -1170,9 +1170,8 @@ find_inc (bool first_try)
 		     we are going to increment the result of the add insn.
 		     For this trick to be correct, the result reg of
 		     the inc must be a valid addressing reg.  */
-		  addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
 		  if (GET_MODE (inc_insn.reg_res)
-		      != targetm.addr_space.address_mode (as))
+		      != mem_address_mode (*mem_insn.mem_loc))
 		    {
 		      if (dump_file)
 			fprintf (dump_file, "base reg mode failure.\n");
@@ -1221,9 +1220,8 @@ find_inc (bool first_try)
 	{
 	  /* For this trick to be correct, the result reg of the inc
 	     must be a valid addressing reg.  */
-	  addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
 	  if (GET_MODE (inc_insn.reg_res)
-	      != targetm.addr_space.address_mode (as))
+	      != mem_address_mode (*mem_insn.mem_loc))
 	    {
 	      if (dump_file)
 		fprintf (dump_file, "base reg mode failure.\n");
diff --git a/gcc/builtins.c b/gcc/builtins.c
index a5858503178..9d58a4909a6 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6655,10 +6655,13 @@ static rtx
 get_builtin_sync_mem (tree loc, machine_mode mode)
 {
   rtx addr, mem;
-  int addr_space = TYPE_ADDR_SPACE (POINTER_TYPE_P (TREE_TYPE (loc))
-				    ? TREE_TYPE (TREE_TYPE (loc))
-				    : TREE_TYPE (loc));
-  scalar_addr_mode addr_mode = targetm.addr_space.address_mode (addr_space);
+  tree loc_type = TREE_TYPE (loc);
+  int addr_space = TYPE_ADDR_SPACE (POINTER_TYPE_P (loc_type)
+				    ? TREE_TYPE (loc_type)
+				    : loc_type);
+  scalar_addr_mode addr_mode = (POINTER_TYPE_P (loc_type)
+				? pointer_address_mode (loc_type)
+				: unqualified_address_mode (loc_type));
 
   addr = expand_expr (loc, NULL_RTX, addr_mode, EXPAND_SUM);
   addr = convert_memory_address (addr_mode, addr);
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 83a720c34dd..1c30003d0d4 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -642,9 +642,8 @@ c_build_pointer_type (tree to_type)
   addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
 					      : TYPE_ADDR_SPACE (to_type);
   machine_mode pointer_mode;
-
   if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
-    pointer_mode = targetm.addr_space.pointer_mode (as);
+    pointer_mode = unqualified_pointer_mode (to_type);
   else
     pointer_mode = c_default_pointer_mode;
   return build_pointer_type_for_mode (to_type, pointer_mode, false);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 5561ed252b3..f9f6d1de7c5 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4054,8 +4054,9 @@ convert_debug_memory_address (scalar_addr_mode mode, rtx x,
 			      addr_space_t as)
 {
 #ifndef POINTERS_EXTEND_UNSIGNED
+  bool is_cap = is_capability_address (x);
   gcc_assert (mode == Pmode
-	      || mode == targetm.addr_space.address_mode (as));
+	      || mode == targetm.addr_space.address_mode (as, is_cap));
   gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
 #else
   rtx temp;
@@ -4510,8 +4511,8 @@ expand_debug_expr (tree exp)
 
       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
 
-      op0 = convert_debug_memory_address (targetm.addr_space.address_mode (as),
-					  op0, as);
+      addr_mode = pointer_address_mode (TREE_TYPE (TREE_OPERAND (exp, 0)));
+      op0 = convert_debug_memory_address (addr_mode, op0, as);
       if (op0 == NULL_RTX)
 	return NULL;
 
@@ -4535,8 +4536,8 @@ expand_debug_expr (tree exp)
 	return NULL;
 
       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
-      op0 = convert_debug_memory_address (targetm.addr_space.address_mode (as),
-					  op0, as);
+      addr_mode = pointer_address_mode (TREE_TYPE (TREE_OPERAND (exp, 0)));
+      op0 = convert_debug_memory_address (addr_mode, op0, as);
       if (op0 == NULL_RTX)
 	return NULL;
 
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 9c0172aa2f8..9ff6d1b4d63 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -12897,7 +12897,7 @@ avr_case_values_threshold (void)
 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'.  */
 
 static scalar_addr_mode
-avr_addr_space_address_mode (addr_space_t as)
+avr_addr_space_address_mode (addr_space_t as, bool = false)
 {
   return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
 }
@@ -12906,7 +12906,7 @@ avr_addr_space_address_mode (addr_space_t as)
 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'.  */
 
 static scalar_addr_mode
-avr_addr_space_pointer_mode (addr_space_t as)
+avr_addr_space_pointer_mode (addr_space_t as, bool = false)
 {
   return avr_addr_space_address_mode (as);
 }
diff --git a/gcc/config/ft32/ft32.c b/gcc/config/ft32/ft32.c
index ff298d639c6..96920f984b4 100644
--- a/gcc/config/ft32/ft32.c
+++ b/gcc/config/ft32/ft32.c
@@ -789,22 +789,6 @@ ft32_valid_pointer_mode (scalar_addr_mode mode)
   return 0;
 }
 
-#undef TARGET_ADDR_SPACE_POINTER_MODE
-#define TARGET_ADDR_SPACE_POINTER_MODE ft32_addr_space_pointer_mode
-static scalar_addr_mode
-ft32_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
-{
-  return Pmode;
-}
-
-#undef TARGET_ADDR_SPACE_ADDRESS_MODE
-#define TARGET_ADDR_SPACE_ADDRESS_MODE ft32_addr_space_address_mode
-static scalar_addr_mode
-ft32_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
-{
-  return Pmode;
-}
-
 #undef TARGET_ADDR_SPACE_SUBSET_P
 #define TARGET_ADDR_SPACE_SUBSET_P ft32_addr_space_subset_p
 static bool
diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index c580120cda2..a737bf26c33 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -1420,7 +1420,7 @@ gcn_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
    Return the appropriate mode for a named address pointer.  */
 
 static scalar_addr_mode
-gcn_addr_space_pointer_mode (addr_space_t addrspace)
+gcn_addr_space_pointer_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
@@ -1443,7 +1443,7 @@ gcn_addr_space_pointer_mode (addr_space_t addrspace)
    Return the appropriate mode for a named address space address.  */
 
 static scalar_addr_mode
-gcn_addr_space_address_mode (addr_space_t addrspace)
+gcn_addr_space_address_mode (addr_space_t addrspace, bool = false)
 {
   return gcn_addr_space_pointer_mode (addrspace);
 }
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 0d511200229..7248f9e9d68 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -1927,7 +1927,7 @@ m32c_legitimize_reload_address (rtx * x,
 #undef TARGET_ADDR_SPACE_POINTER_MODE
 #define TARGET_ADDR_SPACE_POINTER_MODE m32c_addr_space_pointer_mode
 static scalar_addr_mode
-m32c_addr_space_pointer_mode (addr_space_t addrspace)
+m32c_addr_space_pointer_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
@@ -1944,7 +1944,7 @@ m32c_addr_space_pointer_mode (addr_space_t addrspace)
 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
 #define TARGET_ADDR_SPACE_ADDRESS_MODE m32c_addr_space_address_mode
 static scalar_addr_mode
-m32c_addr_space_address_mode (addr_space_t addrspace)
+m32c_addr_space_address_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index bd891136845..e199bb80f61 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -450,7 +450,7 @@ msp430_initial_elimination_offset (int from, int to)
 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
 
 static scalar_addr_mode
-msp430_addr_space_pointer_mode (addr_space_t addrspace)
+msp430_addr_space_pointer_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index e57f1c3b303..c512c1c1c2b 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -1061,7 +1061,7 @@ rl78_hl_b_c_addr_p (rtx op)
 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
 
 static scalar_addr_mode
-rl78_addr_space_address_mode (addr_space_t addrspace)
+rl78_addr_space_address_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
@@ -1101,7 +1101,7 @@ rl78_far_p (rtx x)
 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
 
 static scalar_addr_mode
-rl78_addr_space_pointer_mode (addr_space_t addrspace)
+rl78_addr_space_pointer_mode (addr_space_t addrspace, bool = false)
 {
   switch (addrspace)
     {
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 97fe7eb371b..50fdbd9fceb 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10970,16 +10970,24 @@ named address space #1:
 c_register_addr_space ("__ea", ADDR_SPACE_EA);
 @end smallexample
 
-@deftypefn {Target Hook} scalar_addr_mode TARGET_ADDR_SPACE_POINTER_MODE (addr_space_t @var{address_space})
+@deftypefn {Target Hook} scalar_addr_mode TARGET_ADDR_SPACE_POINTER_MODE (addr_space_t @var{address_space}, bool @var{is_capability})
 Define this to return the machine mode to use for pointers to
 @var{address_space} if the target supports named address spaces.
-The default version of this hook returns @code{ptr_mode}.
+@var{is_capability} is true if the pointer should be a capability or
+false if the pointer should be a normal integer.
+
+The default version of this hook returns @code{TARGET_CAPABILITY_MODE}
+when @var{is_capability} is true and @code{ptr_mode} otherwise.
 @end deftypefn
 
-@deftypefn {Target Hook} scalar_addr_mode TARGET_ADDR_SPACE_ADDRESS_MODE (addr_space_t @var{address_space})
+@deftypefn {Target Hook} scalar_addr_mode TARGET_ADDR_SPACE_ADDRESS_MODE (addr_space_t @var{address_space}, bool @var{is_capability})
 Define this to return the machine mode to use for addresses in
 @var{address_space} if the target supports named address spaces.
-The default version of this hook returns @code{Pmode}.
+@var{is_capability} is true if the address should be a capability or
+false if the address should be a normal integer.
+
+The default version of this hook returns @code{TARGET_CAPABILITY_MODE}
+when @var{is_capability} is true and @code{Pmode} otherwise.
 @end deftypefn
 
 @deftypefn {Target Hook} bool TARGET_ADDR_SPACE_VALID_POINTER_MODE (scalar_addr_mode @var{mode}, addr_space_t @var{as})
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index b10243b5b8c..c494f7cfe4e 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2418,10 +2418,6 @@ adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset,
   scalar_addr_mode address_mode;
   class mem_attrs attrs (*get_mem_attrs (memref)), *defattrs;
   unsigned HOST_WIDE_INT max_align;
-#ifdef POINTERS_EXTEND_UNSIGNED
-  scalar_addr_mode pointer_mode
-    = targetm.addr_space.pointer_mode (attrs.addrspace);
-#endif
 
   /* VOIDmode means no mode change for change_address_1.  */
   if (mode == VOIDmode)
@@ -2450,6 +2446,10 @@ adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset,
      range of the target address space.  */
   address_mode = mem_address_mode (memref);
   offset = trunc_int_for_mode (offset, offset_mode (address_mode));
+#ifdef POINTERS_EXTEND_UNSIGNED
+  auto pointer_mode = address_mode_to_pointer_mode (address_mode,
+						    attrs.addrspace);
+#endif
 
   if (adjust_address)
     {
diff --git a/gcc/explow.c b/gcc/explow.c
index 90cb6e4d956..00e89e32689 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -369,8 +369,8 @@ convert_memory_address_addr_space_1 (scalar_addr_mode to_mode ATTRIBUTE_UNUSED,
      (they're not just simply bits ...).  */
   gcc_assert (! CAPABILITY_MODE_P (to_mode));
 
-  pointer_mode = targetm.addr_space.pointer_mode (as);
-  address_mode = targetm.addr_space.address_mode (as);
+  pointer_mode = unqualified_pointer_mode (as);
+  address_mode = unqualified_address_mode (as);
   from_mode = to_mode == pointer_mode ? address_mode : pointer_mode;
   /* Just assert that the input is as it should be  (X is a memory address in
      the previous mode).  */
@@ -481,7 +481,8 @@ rtx
 memory_address_addr_space (machine_mode mode, rtx x, addr_space_t as)
 {
   rtx oldx = x;
-  scalar_addr_mode address_mode = targetm.addr_space.address_mode (as);
+  bool is_cap = is_capability_address (x);
+  scalar_addr_mode address_mode = targetm.addr_space.address_mode (as, is_cap);
 
   x = convert_memory_address_addr_space (address_mode, x, as);
 
@@ -902,8 +903,7 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode,
     case REFERENCE_TYPE:
     case POINTER_TYPE:
       *punsignedp = POINTERS_EXTEND_UNSIGNED;
-      return targetm.addr_space.address_mode
-	       (TYPE_ADDR_SPACE (TREE_TYPE (type)));
+      return pointer_address_mode (type);
 #endif
 
     default:
diff --git a/gcc/expr.c b/gcc/expr.c
index 6611879d70e..f9ecd700276 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6041,9 +6041,10 @@ store_expr (tree exp, rtx target, int call_param_p,
 			      ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
 	  else
 	    {
-	      machine_mode pointer_mode
-		= targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
-	      const scalar_addr_mode address_mode = mem_address_mode (target);
+	      const auto address_mode = mem_address_mode (target);
+	      const auto as = MEM_ADDR_SPACE (target);
+	      const auto pointer_mode
+		= address_mode_to_pointer_mode (address_mode, as);
 	      const auto om = offset_mode (address_mode);
 
 	      /* Compute the size of the data to copy from the string.  */
@@ -8381,8 +8382,8 @@ expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
   if (POINTER_TYPE_P (TREE_TYPE (exp)))
     {
       as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
-      address_mode = targetm.addr_space.address_mode (as);
-      pointer_mode = targetm.addr_space.pointer_mode (as);
+      address_mode = pointer_address_mode (TREE_TYPE (exp));
+      pointer_mode = SCALAR_ADDR_TYPE_MODE (TREE_TYPE (exp));
     }
 
   /* We can get called with some Weird Things if the user does silliness
@@ -10598,7 +10599,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	  /* Writing into CONST_DECL is always invalid, but handle it
 	     gracefully.  */
 	  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
-	  scalar_addr_mode address_mode = targetm.addr_space.address_mode (as);
+	  scalar_addr_mode address_mode = unqualified_address_mode (as);
 	  op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
 					 EXPAND_NORMAL, as);
 	  op0 = memory_address_addr_space (mode, op0, as);
@@ -10739,10 +10740,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
     case MEM_REF:
       {
 	const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
-	addr_space_t as
-	  = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
 	machine_mode address_mode;
 	tree base = TREE_OPERAND (exp, 0);
+	tree base_type = TREE_TYPE (base);
+	addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base_type));
 	gimple *def_stmt;
 	unsigned align;
 	/* Handle expansion of non-aliased memory with non-BLKmode.  That
@@ -10787,7 +10788,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	    REF_REVERSE_STORAGE_ORDER (exp) = reverse;
 	    return expand_expr (exp, target, tmode, modifier);
 	  }
-	address_mode = targetm.addr_space.address_mode (as);
+	address_mode = pointer_address_mode (base_type);
 	if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
 	  {
 	    tree mask = gimple_assign_rhs2 (def_stmt);
diff --git a/gcc/recog.c b/gcc/recog.c
index 8496e608d31..bed06a3301c 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1948,7 +1948,7 @@ offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
 
   auto address_mode = get_address_mode (y, as);
 #ifdef POINTERS_EXTEND_UNSIGNED
-  machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  auto pointer_mode = address_mode_to_pointer_mode (address_mode, as);
 #endif
 
   /* ??? How much offset does an offsettable BLKmode reference need?
diff --git a/gcc/rtl.h b/gcc/rtl.h
index d83a34752ed..7c4436357f1 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -4568,7 +4568,32 @@ word_register_operation_p (const_rtx x)
       return true;
     }
 }
-    
+
+/* Return true if the address of memory reference MEM has a capability
+   mode.  */
+
+inline bool
+has_capability_address (rtx mem)
+{
+  auto mode = mem_address_mode (mem);
+  return CAPABILITY_MODE_P (mode);
+}
+
+/* Return true if address value X is a capability.  Assume VOIDmode Xs
+   have Pmode.
+
+   It is better to use has_capability_address for existing MEMs, since it
+   takes the address space into account.  */
+
+inline bool
+is_capability_address (rtx x)
+{
+  machine_mode mode = GET_MODE (x);
+  if (mode == VOIDmode)
+    mode = Pmode;
+  return CAPABILITY_MODE_P (mode);
+}
+
 /* gtype-desc.c.  */
 extern void gt_ggc_mx (rtx &);
 extern void gt_pch_nx (rtx &);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 19a818b1bc3..72550069b2e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -5970,7 +5970,7 @@ get_address_mode (const_rtx addr, addr_space_t as)
   auto mode = GET_MODE (addr);
   if (mode != VOIDmode)
     return as_a <scalar_addr_mode> (mode);
-  return targetm.addr_space.address_mode (as);
+  return unqualified_address_mode (as);
 }
 
 /* Return the mode of MEM's address.  */
diff --git a/gcc/target.def b/gcc/target.def
index 8ad345e130a..2c491f772e2 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3310,8 +3310,12 @@ DEFHOOK
 (pointer_mode,
  "Define this to return the machine mode to use for pointers to\n\
 @var{address_space} if the target supports named address spaces.\n\
-The default version of this hook returns @code{ptr_mode}.",
- scalar_addr_mode, (addr_space_t address_space),
+@var{is_capability} is true if the pointer should be a capability or\n\
+false if the pointer should be a normal integer.\n\
+\n\
+The default version of this hook returns @code{TARGET_CAPABILITY_MODE}\n\
+when @var{is_capability} is true and @code{ptr_mode} otherwise.",
+ scalar_addr_mode, (addr_space_t address_space, bool is_capability),
  default_addr_space_pointer_mode)
 
 /* MODE to use for an address in another address space.  */
@@ -3319,8 +3323,12 @@ DEFHOOK
 (address_mode,
  "Define this to return the machine mode to use for addresses in\n\
 @var{address_space} if the target supports named address spaces.\n\
-The default version of this hook returns @code{Pmode}.",
- scalar_addr_mode, (addr_space_t address_space),
+@var{is_capability} is true if the address should be a capability or\n\
+false if the address should be a normal integer.\n\
+\n\
+The default version of this hook returns @code{TARGET_CAPABILITY_MODE}\n\
+when @var{is_capability} is true and @code{Pmode} otherwise.",
+ scalar_addr_mode, (addr_space_t address_space, bool is_capability),
  default_addr_space_address_mode)
 
 /* True if MODE is valid for a pointer in __attribute__((mode("MODE")))
diff --git a/gcc/target.h b/gcc/target.h
index 440cd25f297..344a6b7934b 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -292,6 +292,34 @@ estimated_poly_value (poly_int64 x)
     return targetm.estimated_poly_value (x);
 }
 
+/* Return the mode of an unqualified address in address space AS.
+   The mode is a capability whenever Pmode is a capability.  */
+
+inline scalar_addr_mode
+unqualified_address_mode (addr_space_t as)
+{
+  return targetm.addr_space.address_mode (as, CAPABILITY_MODE_P (Pmode));
+}
+
+/* Return the mode of an unqualified pointer in address space AS.
+   The mode is a capability whenever ptr_mode is a capability.  */
+
+inline scalar_addr_mode
+unqualified_pointer_mode (addr_space_t as)
+{
+  return targetm.addr_space.pointer_mode (as, CAPABILITY_MODE_P (ptr_mode));
+}
+
+/* Convert address mode ADDRESS_MODE to the corresponding pointer mode,
+   given that the address is in address space AS.  */
+
+inline scalar_addr_mode
+address_mode_to_pointer_mode (scalar_addr_mode address_mode, addr_space_t as)
+{
+  bool is_capability = CAPABILITY_MODE_P (address_mode);
+  return targetm.addr_space.pointer_mode (as, is_capability);
+}
+
 #ifdef GCC_TM_H
 
 #ifndef CUMULATIVE_ARGS_MAGIC
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 0862e8e2074..668122b06cd 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1461,8 +1461,12 @@ default_capability_mode ()
    defaulting to ptr_mode for all address spaces.  */
 
 scalar_addr_mode
-default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+default_addr_space_pointer_mode (addr_space_t, bool is_capability)
 {
+  if (is_capability)
+    return targetm.capability_mode ().require ();
+
+  gcc_assert (!CAPABILITY_MODE_P (ptr_mode));
   return ptr_mode;
 }
 
@@ -1470,8 +1474,12 @@ default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
    defaulting to Pmode for all address spaces.  */
 
 scalar_addr_mode
-default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+default_addr_space_address_mode (addr_space_t, bool is_capability)
 {
+  if (is_capability)
+    return targetm.capability_mode ().require ();
+
+  gcc_assert (!CAPABILITY_MODE_P (Pmode));
   return Pmode;
 }
 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index da08722680c..e351257cf5b 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -196,8 +196,8 @@ extern bool default_target_can_inline_p (tree, tree);
 extern bool default_valid_pointer_mode (scalar_addr_mode);
 extern bool default_ref_may_alias_errno (class ao_ref *);
 extern opt_scalar_addr_mode default_capability_mode ();
-extern scalar_addr_mode default_addr_space_pointer_mode (addr_space_t);
-extern scalar_addr_mode default_addr_space_address_mode (addr_space_t);
+extern scalar_addr_mode default_addr_space_pointer_mode (addr_space_t, bool);
+extern scalar_addr_mode default_addr_space_address_mode (addr_space_t, bool);
 extern bool default_addr_space_valid_pointer_mode (scalar_addr_mode,
 						   addr_space_t);
 extern bool default_addr_space_legitimate_address_p (machine_mode, rtx,
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index 1cf31065505..c6ba514a25f 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -192,8 +192,9 @@ rtx
 addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
 		  bool really_expand)
 {
-  scalar_addr_mode address_mode = targetm.addr_space.address_mode (as);
-  scalar_addr_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  bool is_cap = addr->is_capability ();
+  scalar_addr_mode address_mode = targetm.addr_space.address_mode (as, is_cap);
+  scalar_addr_mode pointer_mode = targetm.addr_space.pointer_mode (as, is_cap);
   rtx address, sym, bse, idx, st, off;
   struct mem_addr_template *templ;
 
@@ -578,7 +579,7 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, machine_mode mode,
   valid_mult = valid_mult_list[data_index];
   if (!valid_mult)
     {
-      machine_mode address_mode = targetm.addr_space.address_mode (as);
+      machine_mode address_mode = unqualified_address_mode (as);
       machine_mode addr_mode = noncapability_mode (address_mode);
       rtx reg1 = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
       rtx reg2 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2);
@@ -648,7 +649,7 @@ most_expensive_mult_to_index (tree type, struct mem_address *parts,
      be nice to check.
      */
   addr_space_t as = TYPE_ADDR_SPACE (type);
-  machine_mode address_mode = offset_mode (targetm.addr_space.address_mode (as));
+  machine_mode address_mode = offset_mode (unqualified_address_mode (as));
   HOST_WIDE_INT coef;
   unsigned best_mult_cost = 0, acost;
   tree mult_elt = NULL_TREE, elt;
@@ -1255,4 +1256,18 @@ dump_mem_address (FILE *file, struct mem_address *parts)
     }
 }
 
+/* Return true if the address has a capability type.  */
+
+bool
+mem_address::is_capability () const
+{
+  if (symbol)
+    return tree_is_capability_value (symbol);
+
+  if (base && POINTER_TYPE_P (TREE_TYPE (base)))
+    return tree_is_capability_value (base);
+
+  return CAPABILITY_MODE_P (ptr_mode);
+}
+
 #include "gt-tree-ssa-address.h"
diff --git a/gcc/tree-ssa-address.h b/gcc/tree-ssa-address.h
index 9401888209a..a488e1c1f91 100644
--- a/gcc/tree-ssa-address.h
+++ b/gcc/tree-ssa-address.h
@@ -25,6 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 struct mem_address
 {
   tree symbol, base, index, step, offset;
+
+  bool is_capability () const;
 };
 
 extern rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index f7adbc2ab73..2f45777cca1 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2608,9 +2608,10 @@ addr_offset_valid_p (struct iv_use *use, poly_int64 offset)
   addr = (*addr_list)[list_index];
   if (!addr)
     {
-      addr_mode = targetm.addr_space.address_mode (as);
+      bool is_capability = tree_is_capability_value (use->iv->base);
+      addr_mode = targetm.addr_space.address_mode (as, is_capability);
       reg = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
-      rtx_code code = CAPABILITY_MODE_P (addr_mode) ? POINTER_PLUS : PLUS;
+      rtx_code code = is_capability ? POINTER_PLUS : PLUS;
       addr = gen_rtx_fmt_ee (code, addr_mode, reg, NULL_RTX);
       (*addr_list)[list_index] = addr;
     }
@@ -3738,7 +3739,7 @@ static rtx
 produce_memory_decl_rtl (tree obj, int *regno)
 {
   addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
-  machine_mode address_mode = targetm.addr_space.address_mode (as);
+  machine_mode address_mode = unqualified_address_mode (as);
   rtx x;
 
   gcc_assert (obj);
diff --git a/gcc/tree.c b/gcc/tree.c
index 98d5cebfa4f..a3a7c8972de 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -7893,6 +7893,44 @@ operation_no_trapping_overflow (tree type, enum tree_code code)
     }
 }
 
+/* Return the address mode (i.e. Pmode-like mode) associated with
+   pointer type TYPE.  */
+
+scalar_addr_mode
+pointer_address_mode (const_tree type)
+{
+  if (type == error_mark_node)
+    return unqualified_pointer_mode (addr_space_t (ADDR_SPACE_GENERIC));
+
+  gcc_assert (POINTER_TYPE_P (type));
+  return targetm.addr_space.address_mode (TYPE_ADDR_SPACE (TREE_TYPE (type)),
+					  capability_type_p (type));
+}
+
+/* Return the address mode (i.e. Pmode-like mode) for an unqualified
+   pointer to TO_TYPE.  */
+
+scalar_addr_mode
+unqualified_address_mode (const_tree to_type)
+{
+  if (to_type == error_mark_node)
+    return unqualified_pointer_mode (addr_space_t (ADDR_SPACE_GENERIC));
+
+  return unqualified_address_mode (TYPE_ADDR_SPACE (to_type));
+}
+
+/* Return the pointer mode (i.e. ptr_mode-like mode) for an unqualified
+   pointer to TO_TYPE.  */
+
+scalar_addr_mode
+unqualified_pointer_mode (const_tree to_type)
+{
+  if (to_type == error_mark_node)
+    return unqualified_pointer_mode (addr_space_t (ADDR_SPACE_GENERIC));
+
+  return unqualified_pointer_mode (TYPE_ADDR_SPACE (to_type));
+}
+
 /* Constructors for pointer, array, function, and intcap types.
    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
    constructed by language-dependent code, not here.)  */
@@ -8028,9 +8066,7 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode,
 tree
 build_pointer_type (tree to_type)
 {
-  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
-					      : TYPE_ADDR_SPACE (to_type);
-  machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  auto pointer_mode = unqualified_pointer_mode (to_type);
   return build_pointer_type_for_mode (to_type, pointer_mode, false);
 }
 
@@ -8115,9 +8151,7 @@ build_reference_type_for_mode (tree to_type, machine_mode mode,
 tree
 build_reference_type (tree to_type)
 {
-  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
-					      : TYPE_ADDR_SPACE (to_type);
-  machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  auto pointer_mode = unqualified_pointer_mode (to_type);
   return build_reference_type_for_mode (to_type, pointer_mode, false);
 }
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 674eb1acf64..e5706f13340 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2019,6 +2019,10 @@ extern tree fold_drop_capability (tree);
 extern tree build_replace_address_value_loc (location_t, tree, tree);
 extern bool valid_capability_code_p (tree_code);
 
+extern scalar_addr_mode pointer_address_mode (const_tree);
+extern scalar_addr_mode unqualified_address_mode (const_tree);
+extern scalar_addr_mode unqualified_pointer_mode (const_tree);
+
 extern machine_mode element_mode (const_tree);
 extern machine_mode vector_type_mode (const_tree);
 extern unsigned int vector_element_bits (const_tree);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2e6b98e6ef9..029a1e9fbac 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1506,12 +1506,7 @@ make_decl_rtl (tree decl)
     x = create_block_symbol (name, get_block_for_decl (decl), -1);
   else
     {
-      machine_mode address_mode = Pmode;
-      if (TREE_TYPE (decl) != error_mark_node)
-	{
-	  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
-	  address_mode = targetm.addr_space.address_mode (as);
-	}
+      machine_mode address_mode = unqualified_address_mode (TREE_TYPE (decl));
       x = gen_rtx_SYMBOL_REF (address_mode, name);
     }
   SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-05 12:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 12:04 [gcc(refs/vendors/ARM/heads/morello)] Add is_capability argument to addr_space hooks Matthew Malcomson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).