From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2049) id A9B53385DC13; Thu, 5 May 2022 12:04:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A9B53385DC13 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Matthew Malcomson To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] Add is_capability argument to addr_space hooks X-Act-Checkin: gcc X-Git-Author: Richard Sandiford X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 125322e97a6df7fdea5f28a4971db1ec7d22046d X-Git-Newrev: 12cd31ada5eecb72724ad76425ced56d9aca10aa Message-Id: <20220505120439.A9B53385DC13@sourceware.org> Date: Thu, 5 May 2022 12:04:39 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 May 2022 12:04:39 -0000 https://gcc.gnu.org/g:12cd31ada5eecb72724ad76425ced56d9aca10aa commit 12cd31ada5eecb72724ad76425ced56d9aca10aa Author: Richard Sandiford 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 (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);