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 -------- Given that UPC pointers-to-shared (PTS's) have special arithmetic rules and their internal representation is a structure with three separate fields, they are not meaningfully convertible to integers and pointer arithmetic involving PTS's cannot be optimized in the same fashion as normal "C" pointer arithmetic. Further, the representation of a NULL pointer-to-shared is different from a "C" null pointer. Logic has been added to convert.c and jump.c to handle operations involving UPC PTS's. In function.c, UPC pointers-to-shared which have an internal representation that is a 'struct' are treated as aggregates. Also in function.c logic is added that prevents marking them as potential pointer register values. In varasm.c, a check is added for the linker section used by UPC to coalesce file scoped UPC shared variables. This section is used only to assign offsets into UPC's shared data area for the UPC shared variables. When UPC linker scripts are supported, this shared section is not loaded and has an origin of 0. 2015-11-30 Gary Funck <g...@intrepid.com> gcc/ * convert.c (convert_to_pointer): Add check for null UPC pointer-to-shared. (convert_to_integer): Do not optimize pointer subtraction for UPC pointers-to-shared. (convert_to_integer): Issue error for an attempt to convert a UPC pointer-to-shared to an integer. * dojump.c (do_jump): If a UPC pointer-to-shared conversion can change representation, it must be compared in the result type. * function.c (aggregate_value_p): Handle 'struct' pointer-to-shared values as an aggregate when passing them as a return value. (assign_parm_setup_reg): Do not target UPC pointers-to-shared that are represented as a 'struct' into a pointer register. * varasm.c (default_section_type_flags): Handle UPC's shared section as BSS, and if a UPC link script is supported, make it a non-loadable, read-only section. Index: gcc/convert.c =================================================================== --- gcc/convert.c (.../trunk) (revision 231059) +++ gcc/convert.c (.../branches/gupc) (revision 231080) @@ -53,6 +53,14 @@ convert_to_pointer_1 (tree type, tree ex if (TREE_TYPE (expr) == type) return expr; + if (integer_zerop (expr) && POINTER_TYPE_P (type) + && SHARED_TYPE_P (TREE_TYPE (type))) + { + expr = copy_node (upc_null_pts_node); + TREE_TYPE (expr) = build_unshared_type (type); + return expr; + } + switch (TREE_CODE (TREE_TYPE (expr))) { case POINTER_TYPE: @@ -437,6 +445,16 @@ convert_to_integer_1 (tree type, tree ex return error_mark_node; } + /* Can't optimize the conversion of UPC shared pointer difference. */ + if (ex_form == MINUS_EXPR + && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))) + && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_OPERAND (expr, 0)))) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_OPERAND (expr, 1))))) + { + return build1 (CONVERT_EXPR, type, expr); + } + if (ex_form == COMPOUND_EXPR) { tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold); @@ -581,6 +599,12 @@ convert_to_integer_1 (tree type, tree ex { case POINTER_TYPE: case REFERENCE_TYPE: + if (SHARED_TYPE_P (TREE_TYPE (intype))) + { + error ("invalid conversion from a UPC pointer-to-shared " + "to an integer"); + expr = integer_zero_node; + } if (integer_zerop (expr)) return build_int_cst (type, 0); Index: gcc/dojump.c =================================================================== --- gcc/dojump.c (.../trunk) (revision 231059) +++ gcc/dojump.c (.../branches/gupc) (revision 231080) @@ -468,6 +468,10 @@ do_jump (tree exp, rtx_code_label *if_fa < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))) goto normal; case NON_LVALUE_EXPR: + /* if a shared pointer conversion that will change representation, + then we have to compare in the result type. */ + if (PTS_CVT_OP_P (exp)) + goto normal; case ABS_EXPR: case NEGATE_EXPR: case LROTATE_EXPR: Index: gcc/function.c =================================================================== --- gcc/function.c (.../trunk) (revision 231059) +++ gcc/function.c (.../branches/gupc) (revision 231080) @@ -2073,6 +2073,17 @@ aggregate_value_p (const_tree exp, const if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type)) return 1; + /* Pointers-to-shared must be considered as aggregates for + the purpose of passing them as return values, but only + when the underlying mode of the representation would + require that its value be passed on the stack. + This occurs when using the 'struct' representation + of a shared pointer. */ + if (flag_pcc_struct_return && POINTER_TYPE_P (type) + && SHARED_TYPE_P (TREE_TYPE (type)) + && AGGREGATE_TYPE_P (upc_pts_rep_type_node)) + return 1; + if (targetm.calls.return_in_memory (type, fntype)) return 1; @@ -3384,6 +3395,13 @@ assign_parm_setup_reg (struct assign_par set_dst_reg_note (linsn, REG_EQUIV, equiv_stack_parm, parmreg); } + /* Do not target UPC pointers-to-shared values into a pointer + register if they are represented as struct's. */ + if (POINTER_TYPE_P (TREE_TYPE (parm)) + && SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (parm))) + && AGGREGATE_TYPE_P (upc_pts_rep_type_node)) + return; + /* For pointer data type, suggest pointer register. */ if (POINTER_TYPE_P (TREE_TYPE (parm))) mark_reg_pointer (parmreg, Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (.../trunk) (revision 231059) +++ gcc/varasm.c (.../branches/gupc) (revision 231080) @@ -6194,6 +6194,21 @@ default_section_type_flags (tree decl, c || strcmp (name, ".preinit_array") == 0)) flags |= SECTION_NOTYPE; + /* The UPC shared section is not loaded into memory. + It is used only to layout shared variables. */ + if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS))) + { + const char *upc_shared_section_name = + targetm.upc.shared_section_name (); + if (upc_shared_section_name + && (strcmp (name, upc_shared_section_name) == 0)) + { + flags |= SECTION_BSS; + if (targetm.upc.link_script_p ()) + flags = SECTION_DEBUG | (flags & ~SECTION_WRITE); + } + } + return flags; }