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).