On Mon, 30 Nov 2015, Gary Funck wrote:

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

This looks worrysome.  I suppose this applies to simplifications
done before lowering only?  If so I wonder if not using regular
plus/minus/convert/nop for operations on UPC shared pointers is
better than introducing this kind of checks.

Richard.

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

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to