Add TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
authorRichard Henderson <rth@redhat.com>
Mon, 9 Nov 2015 09:18:59 +0000 (01:18 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 9 Nov 2015 09:18:59 +0000 (01:18 -0800)
        * 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

gcc/ChangeLog
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/fold-const.c
gcc/gimple.c
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h

index 93fdcc95610f3ece660386d8ad98a374f3f63971..858f9b8ffd6449d344eb0acaa67e065c88429dd1 100644 (file)
@@ -1,5 +1,14 @@
 2015-11-09  Richard Henderson  <rth@redhat.com>
 
+       * 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.
index f394db7d0a64eec55ccd5b9fb9a60321ae467267..56cf60d004fe948641603f621ac682496e87a9b1 100644 (file)
@@ -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
index d188c57b75c9dbb81caba45d93af5bc9866a7d48..40abf76cdb4de928171b434a6099cfbd06ada965 100644 (file)
@@ -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
index d8a45d998dc9318a5278be93d1eef453cc1be92c..8b437ab8f26b8f795d50dbaac8fd83cfaf5e1d4e 100644 (file)
@@ -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;
 
index 4ce38dadf2fba763e85a75db0c4205ef79277be8..706b126e5bb93b70e64ce75ff25728a57bee85fe 100644 (file)
@@ -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;
 }
 
index c7ec292971448e16f91866548fbba7f2767588d4..fc52798096841e8d6bd28a2cfcf3be31be4b48d7 100644 (file)
@@ -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,
index 14324b7addc0ec5e35209952ae0ee4db57a25e2d..d9108a633bf5418fcade72ae5b56e10bae26addb 100644 (file)
@@ -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.  */
 
index a8e7ebbd8ca624d5aba15b76725516d625d6f644..d93d4d7957cac7c0f782e98be40d9e390dceeb7d 100644 (file)
@@ -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);