Background
----------

An overview email, describing the UPC-related changes is here:
  https://gcc.gnu.org/ml/gcc-patches/2015-12/msg00005.html

The GUPC branch is described here:
  http://gcc.gnu.org/projects/gupc.html

The UPC-related source code differences are summarized here:
  http://gccupc.org/gupc-changes

All languages (c, c++, fortran, go, lto, objc, obj-c++) have been
bootstrapped; no test suite regressions were introduced,
relative to the GCC trunk.

If you are on the cc-list, your name was chosen either
because you are listed as a maintainer for the area that
applies to the patches described in this email, or you
were a frequent contributor of patches made to files listed
in this email.

In the change log entries included in each patch, the directory
containing the affected files is listed, followed by the files.
When the patches are applied, the change log entries will be
distributed to the appropriate ChangeLog file.

Overview
--------

UPC pointers-to-shared (aka shared pointers) are not interchangeable
with integers as they are in regular "C".  Therefore, additions
and subtraction operations which involve UPC shared pointers
should not be further simplified.

2015-11-30  Gary Funck  <g...@intrepid.com>

        gcc/
        * fold-const.c (fold_unary_loc): Do not perform this simplification
        if either of the types are UPC pointer-to-shared types.
        (fold_binary_loc): Disable optimizations involving UPC
        pointers-to-shared because integers are not interoperable
        with UPC pointers-to-shared.
        * match.pd: Do not simplify POINTER_PLUS operations which
        involve UPC pointers-to-shared.  Do not simplify integral
        conversions involving UPC pointers-to-shared.  For a chain
        of two conversions, do not simplify conversions involving
        UPC pointers-to-shared unless they meet specific criteria.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (.../trunk)     (revision 231059)
+++ gcc/fold-const.c    (.../branches/gupc)     (revision 231080)
@@ -7805,10 +7805,16 @@ fold_unary_loc (location_t loc, enum tre
 
       /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type, when the new
         cast (T1)X will fold away.  We assume that this happens when X itself
-        is a cast.  */
+        is a cast.
+        
+        Do not perform this simplification if either of the types 
+        are UPC pointer-to-shared types.  */
       if (POINTER_TYPE_P (type)
          && TREE_CODE (arg0) == POINTER_PLUS_EXPR
-         && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0)))
+         && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0))
+         && !SHARED_TYPE_P (TREE_TYPE (type))
+         && !SHARED_TYPE_P (TREE_TYPE (
+                                  TREE_TYPE (TREE_OPERAND (arg0, 0)))))
        {
          tree arg00 = TREE_OPERAND (arg0, 0);
          tree arg01 = TREE_OPERAND (arg0, 1);
@@ -9271,6 +9277,14 @@ fold_binary_loc (location_t loc,
       return NULL_TREE;
 
     case PLUS_EXPR:
+      /* Disable further optimizations involving UPC shared pointers,
+         because integers are not interoperable with shared pointers.  */
+      if ((TREE_TYPE (arg0) && POINTER_TYPE_P (TREE_TYPE (arg0))
+          && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
+         || (TREE_TYPE (arg1) && POINTER_TYPE_P (TREE_TYPE (arg1))
+             && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg1)))))
+        return NULL_TREE;
+
       if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
        {
          /* X + (X / CST) * -CST is X % CST.  */
@@ -9679,6 +9693,16 @@ fold_binary_loc (location_t loc,
       return NULL_TREE;
 
     case MINUS_EXPR:
+
+      /* Disable further optimizations involving UPC shared pointers,
+         because integers are not interoperable with shared pointers.
+        (The test below also detects pointer difference between
+        shared pointers, which cannot be folded.  */
+
+      if (TREE_TYPE (arg0) && POINTER_TYPE_P (TREE_TYPE (arg0))
+          && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
+        return NULL_TREE;
+
       /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
       if (TREE_CODE (arg0) == NEGATE_EXPR
          && negate_expr_p (op1)
Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (.../trunk)     (revision 231059)
+++ gcc/match.pd        (.../branches/gupc)     (revision 231080)
@@ -931,10 +931,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (!fail && wi::bit_and (@1, zero_mask_not) == 0)
     (inner_op @2 { wide_int_to_tree (type, cst_emit); }))))))
 
-/* Associate (p +p off1) +p off2 as (p +p (off1 + off2)).  */
-(simplify
-  (pointer_plus (pointer_plus:s @0 @1) @3)
-  (pointer_plus @0 (plus @1 @3)))
+/* Associate (p +p off1) +p off2 as (p +p (off1 + off2)).
+   (Do not apply this simplification to UPC pointers-to-shared
+   because they are not directly convertible to integers.)  */
+(simplify
+  (pointer_plus (pointer_plus:s@2 @0 @1) @3)
+  (if (!SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@2))))
+   (pointer_plus @0 (plus @1 @3))))
 
 /* Pattern match
      tem1 = (long) ptr1;
@@ -1428,19 +1431,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (view_convert @0))
 
 /* For integral conversions with the same precision or pointer
-   conversions use a NOP_EXPR instead.  */
+   conversions use a NOP_EXPR instead.
+   (Do not apply this simplification to UPC pointers-to-shared
+   because they are not directly convertible to integers.)  */
 (simplify
   (view_convert @0)
-  (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
-       && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0)))
+  (if ((INTEGRAL_TYPE_P (type)
+        || (POINTER_TYPE_P (type)
+           && !SHARED_TYPE_P (TREE_TYPE (type))))
+       && (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+           || (POINTER_TYPE_P (TREE_TYPE (@0))
+              && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@0)))))
        && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0)))
    (convert @0)))
 
-/* Strip inner integral conversions that do not change precision or size.  */
+/* Strip inner integral conversions that do not change precision or size.
+   (Do not apply this simplification to UPC pointers-to-shared
+   because they are not directly convertible to integers.)  */
 (simplify
   (view_convert (convert@0 @1))
-  (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0)))
-       && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1)))
+  (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        || (POINTER_TYPE_P (TREE_TYPE (@0))
+           && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@0)))))
+       && (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+           || (POINTER_TYPE_P (TREE_TYPE (@1))
+              && !SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (@1)))))
        && (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1)))
        && (TYPE_SIZE (TREE_TYPE (@0)) == TYPE_SIZE (TREE_TYPE (@1))))
    (view_convert @1)))
@@ -1481,6 +1496,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       int final_vec = VECTOR_TYPE_P (type);
       unsigned int final_prec = TYPE_PRECISION (type);
       int final_unsignedp = TYPE_UNSIGNED (type);
+      int final_pts = final_ptr
+                      && SHARED_TYPE_P (TREE_TYPE (type));
+      int inter_pts = inter_ptr
+                      && SHARED_TYPE_P (TREE_TYPE (inter_type));
+      int inside_pts = inside_ptr
+                        && SHARED_TYPE_P (TREE_TYPE (inside_type));
     }
    (switch
     /* In addition to the cases of two conversions in a row
@@ -1529,7 +1550,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        - the initial type is a pointer type and the precisions of the
          intermediate and final types differ, or
        - the final type is a pointer type and the precisions of the
-         initial and intermediate types differ.  */
+         initial and intermediate types differ, or
+       - the final type, intermediate type, and initial type are not either
+         all regular C pointer types or all UPC pointer-to-shared types, or
+       - the final type is a UPC pointer-to-shared and the intermediate type
+         is a UPC-pointer-to-shared and their target types differ, or
+       - the final type is a UPC pointer-to-shared and the intermediate type
+         is a UPC-pointer-to-shared and their target types differ.  */
     (if (! inside_float && ! inter_float && ! final_float
         && ! inside_vec && ! inter_vec && ! final_vec
         && (inter_prec >= inside_prec || inter_prec >= final_prec)
@@ -1541,7 +1568,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         && ! (inside_ptr && inter_prec != final_prec)
         && ! (final_ptr && inside_prec != inter_prec)
         && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
-              && TYPE_MODE (type) == TYPE_MODE (inter_type)))
+              && TYPE_MODE (type) == TYPE_MODE (inter_type))
+        && (final_pts == inter_pts) && (inter_pts == inside_pts)
+        && ! (inter_pts
+              && (TREE_TYPE (inter_type) != TREE_TYPE (inside_type)))
+        && ! (final_pts && (TREE_TYPE (type) != TREE_TYPE (inter_type))))
      (ocvt @0))
 
     /* A truncation to an unsigned type (a zero-extension) should be

Reply via email to