From: Richard Henderson Date: Mon, 9 Nov 2015 09:18:59 +0000 (-0800) Subject: Add TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6626f97034083631b76c3db092f4bf1156d9d078;p=gcc.git Add TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID * gimple.c (check_loadstore): Return false when 0 is a valid address. * fold-const.c (const_unop) [ADDR_SPACE_CONVERT_EXPR]: Do not fold null when 0 is valid in the source address space. * target.def (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New. * targhooks.c (default_addr_space_zero_address_valid): New. * targhooks.h (default_addr_space_zero_address_valid): Declare. * doc/tm.texi.in (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): Mark it. * doc/tm.texi: Rebuild. From-SVN: r229999 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93fdcc95610..858f9b8ffd6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2015-11-09 Richard Henderson + * gimple.c (check_loadstore): Return false when 0 is a valid address. + * fold-const.c (const_unop) [ADDR_SPACE_CONVERT_EXPR]: Do not fold + null when 0 is valid in the source address space. + * target.def (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): New. + * targhooks.c (default_addr_space_zero_address_valid): New. + * targhooks.h (default_addr_space_zero_address_valid): Declare. + * doc/tm.texi.in (TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID): Mark it. + * doc/tm.texi: Rebuild. + * cselib.c (add_mem_for_addr): Compare address spaces when matching memories. (cselib_lookup_mem): Likewise. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index f394db7d0a6..56cf60d004f 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10365,6 +10365,11 @@ arithmetic operations. Pointers to a superset address space can be converted to pointers to a subset address space via explicit casts. @end deftypefn +@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID (addr_space_t @var{as}) +Define this to modify the default handling of address 0 for the +address space. Return true if 0 should be considered a valid address. +@end deftypefn + @deftypefn {Target Hook} rtx TARGET_ADDR_SPACE_CONVERT (rtx @var{op}, tree @var{from_type}, tree @var{to_type}) Define this to convert the pointer expression represented by the RTL @var{op} with type @var{from_type} that points to a named address diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index d188c57b75c..40abf76cdb4 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7455,6 +7455,8 @@ c_register_addr_space ("__ea", ADDR_SPACE_EA); @hook TARGET_ADDR_SPACE_SUBSET_P +@hook TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID + @hook TARGET_ADDR_SPACE_CONVERT @node Misc diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d8a45d998dc..8b437ab8f26 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1545,7 +1545,11 @@ const_unop (enum tree_code code, tree type, tree arg0) return fold_convert_const (code, type, arg0); case ADDR_SPACE_CONVERT_EXPR: - if (integer_zerop (arg0)) + /* If the source address is 0, and the source address space + cannot have a valid object at 0, fold to dest type null. */ + if (integer_zerop (arg0) + && !(targetm.addr_space.zero_address_valid + (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))))) return fold_convert_const (code, type, arg0); break; diff --git a/gcc/gimple.c b/gcc/gimple.c index 4ce38dadf2f..706b126e5bb 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-iterator.h" #include "gimple-walk.h" #include "gimplify.h" +#include "target.h" /* All the tuples have their operand vector (if present) at the very bottom @@ -2624,9 +2625,15 @@ nonfreeing_call_p (gimple *call) static bool check_loadstore (gimple *, tree op, tree, void *data) { - if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF) - && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0)) - return true; + if (TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF) + { + /* Some address spaces may legitimately dereference zero. */ + addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op)); + if (targetm.addr_space.zero_address_valid (as)) + return false; + + return operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0); + } return false; } diff --git a/gcc/target.def b/gcc/target.def index c7ec2929714..fc527980968 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3223,6 +3223,15 @@ converted to pointers to a subset address space via explicit casts.", bool, (addr_space_t subset, addr_space_t superset), default_addr_space_subset_p) +/* True if 0 is a valid address in the address space, or false if + 0 is a NULL in the address space. */ +DEFHOOK +(zero_address_valid, + "Define this to modify the default handling of address 0 for the\n\ +address space. Return true if 0 should be considered a valid address.", + bool, (addr_space_t as), + default_addr_space_zero_address_valid) + /* Function to convert an rtl expression from one address space to another. */ DEFHOOK (convert, diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 14324b7addc..d9108a633bf 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1268,6 +1268,15 @@ default_addr_space_subset_p (addr_space_t subset, addr_space_t superset) return (subset == superset); } +/* The default hook for determining if 0 within a named address + space is a valid address. */ + +bool +default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED) +{ + return false; +} + /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be called for targets with only a generic address space. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index a8e7ebbd8ca..d93d4d7957c 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -177,6 +177,7 @@ extern bool default_addr_space_legitimate_address_p (machine_mode, rtx, extern rtx default_addr_space_legitimize_address (rtx, rtx, machine_mode, addr_space_t); extern bool default_addr_space_subset_p (addr_space_t, addr_space_t); +extern bool default_addr_space_zero_address_valid (addr_space_t); extern rtx default_addr_space_convert (rtx, tree, tree); extern unsigned int default_case_values_threshold (void); extern bool default_have_conditional_execution (void);