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)