diff mbox

[UPC,17/22] misc/common changes

Message ID 20151201060241.GA31309@intrepid.com
State New
Headers show

Commit Message

Gary Funck Dec. 1, 2015, 6:02 a.m. UTC
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  <gary@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.

Comments

Richard Biener Dec. 2, 2015, 12:15 p.m. UTC | #1
On Tue, Dec 1, 2015 at 7:02 AM, Gary Funck <gary@intrepid.com> 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
> --------
>
> 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.

I think this also shows that using a POINTER_TYPE for a non-pointer
is bogus.  POINTER_TYPE is not for "semantically a pointer" but
for pointers.  Just use RECORD_TYPE here (and of course lower
things earlier).

Richard.

> 2015-11-30  Gary Funck  <gary@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;
>  }
>
Eric Botcazou Dec. 2, 2015, 1:18 p.m. UTC | #2
> I think this also shows that using a POINTER_TYPE for a non-pointer
> is bogus.  POINTER_TYPE is not for "semantically a pointer" but
> for pointers.  Just use RECORD_TYPE here (and of course lower
> things earlier).

FWIW that's what Ada does for its fat pointers.
diff mbox

Patch

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