Message ID | 20151201060240.GA31253@intrepid.com |
---|---|
State | New |
Headers | show |
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 <gary@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 > >
On 12/01/15 12:46:01, Richard Biener wrote: > On Mon, 30 Nov 2015, Gary Funck wrote: > > 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. I suppose that is a possibility. We could introduce UPC_POINTER_PLUS, UPC_POINTER_CONVERT, and so-on as needed. Just not sure how many places that for example, UPC_POINTER_PLUS will keep showing up alongside POINTER_PLUS and similarly UPC_POINTER_CONVERT and CONVERT. After lowering, All UPC-specific operations have been replaced with the GENERIC code that implements them. We still retain the UPC pointer-to-shared types in the tree, rather than lowering everything to the internal representation of the pointer-to-shared type. I recall trying to replace pointers-to-shared with their internal representation and ran into some issues. I think one of them is that procedures accepting pointers-to-shared as parameters would have an apparent type mis-match. It might have impacted debug info. generation as well. Just don't recall. - Gary
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