Re: [UPC 07/22] lowering, pointer-to-shared ops

2015-12-05 Thread Gary Funck
On 12/01/15 12:42:48, Richard Biener wrote:
> On Mon, 30 Nov 2015, Gary Funck wrote:
> [...]
> > +  get_lc_mode_name (mname, (op_mode));
> > +  sprintf (libfunc_name, "__get%s%s%s%s",
> > +   strict_mode ? "s" : "",
> > +   doprofcall ? "g" : "",
> > +  mname,
> > +  (op_mode == BLKmode)
> > +? (doprofcall ? "5" : "3")
> > +: (doprofcall ? "3" : "2"));
> > +  libfunc = identifier_global_value (get_identifier (libfunc_name));
> > +  if (!libfunc)
> > +internal_error ("UPC runtime function %s not found", libfunc_name);
> 
> I think for all these you should use builtins.  You definitely shouldn't
> ICE here if it is an error to not include upc.h (or whatever is required
> to make above lookup succeed).

For UPC, although a reference via a pointer-to-shared will often
access data on another node, fairly often the reference will be
on node or will be local to the current process.  It is a worthwhile
optimization to inline the runtime call because the number of instructions
to test if a reference is on-node or local and to then load/store
directly to that location is small/short relative to the overhead of
making the call.  On some micro-benchmarks, inlining is 30% faster
for get/put accesses.

Inlining is implemented with a pre-include of "gcc-upc.h", which
in turn includes "gcc-upc-lib.h", which defines the API to
the libgupc runtime library.  At optimization levels greater than 0,
gcc-upc-lib.h will implement many UPC runtime procedures as
inline procedures.  This inlining can be disabled with -fupc-no-inline-lib.
The pre-include can be disabled with -fupc-no-pre-include, but
this is typically only done by certain tests.  The pre-include
will be enabled by default if -fupc is asserted.

Thus,

- We need to bring in the inlined runtime procedures via
  the pre-include.

- If we're compiling UPC, then the runtime header file
  will be pre-included, unless explicitly disabled via
  -fupc-no-pre-include (which is ill-advised for regular users).

It is effectively an internal error, if we can't find
the runtime procedures.

Regarding builtins, if we were to contemplate generating
code that makes this locality check and then issuing
a direct access for local/on-node accesses, it would
likely be impractical because different runtime libraries
will implement this locality check and local reference
differently.

- Gary


Re: [UPC 07/22] lowering, pointer-to-shared ops

2015-12-05 Thread Gary Funck
On 12/01/15 12:42:48, Richard Biener wrote:
> On Mon, 30 Nov 2015, Gary Funck wrote:
> [...]
> > +  if (bitpos)
> > +{
> > +  t_offset = size_int (bitpos / BITS_PER_UNIT);
> > +  if (offset)
> > +   t_offset = fold (build_binary_op (loc, PLUS_EXPR,
> > + offset, t_offset, 0));
> 
> Don't use fold ().  If you want a simplified tree don't go
> through build_binary_op but use fold_build2.  In this case
> it looks you want to use size_binop anyway.

OK

Regarding size_binop(), I'll need to review the code.
There are places that we need to retain sign and use
signed size types for example.

> > +}
> > +  else
> > +t_offset = offset;
> > +  {
> > +const tree base_addr_type = TREE_TYPE (base_addr);
> > +const enum tree_code cvt_op =
> > +   lang_hooks.types_compatible_p (upc_char_pts_type_node, base_addr_type)
> > +   ? NOP_EXPR : CONVERT_EXPR;
> 
> NOP and CONVERT are the same.

I haven't followed every GCC changes/re-org closely, but my impression
is that there has been a move to make NOP and CONVERT the same.
Is that correct?

We retain CONVERT's between UPC pointer-to-shared that are not
equivalent and that require some special logic to inter-operate
or convert them.  The UPC lowering pass handles those special cases.
Those conversions are not NOP's.  For example, a floating point
to integer conversion isn't a no-op.

Could use some additional guidance here.



Re: [UPC 07/22] lowering, pointer-to-shared ops

2015-12-01 Thread Richard Biener
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/msg5.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
> 
> 
> The UPC lowering pass traverses the current function tree
> and rewrites UPC related statements and operations into GENERIC.
> The resulting GENERIC tree code will retain UPC pointers-to-shared (PTS)
> types, but all operations such as 'get' and 'put' which indirect
> through a pointer-to-shared have been lowered to use the internal
> representation type.  Most of these operations on UPC pointers-to-shared
> is implemented in c/c-upc-pts-ops.c.
> 
> The UPC lowering pass is implemented by upc_genericize() in
> c/c-upc-low.c.  upc_genericize() is called from finish_function()
> in c/c-decl.c. It is called just prior to calling c_genericize(),
> if -fupc has been asserted.
> 
> The file c/c-upc-rts-names.h defines the names of the UPC runtime
> entry points and variables that implement the runtime ABI.
> To date, there has been no need to implement target dependent names,
> perhaps partly because UPC is supported primarily on POSIX-compliant targets.
> 
> UPC requires some special logic for handling file scoped initializations.
> This is due to the fact that UPC shared addresses are not known
> until runtime and therefore cannot be statically initialized
> in the usual way.  For example, 'addr_x' below must be initialized
> at runtime.
> 
>   shared int x;
>   shared int *addr_x = 
> 
> The routine, upc_check_decl_init(), checks an initialization
> statement to determine if it needs special handling.
> It is called from store_init_value().  If an initialization
> refers to UPC-related constructs that require initialization
> at runtime, then upc_decl_init() is called to save the
> initialization statement on a list.  This list is
> processed by upc_write_global_declarations(), which
> is called via a UPC-specific language hook from
> c_common_parse_file(), just after calling c_parse_file().
> 
> 
> 2015-11-30  Gary Funck  
> 
>   gcc/c-family/
>   * c-upc-pts.h: New.  Define the sizes and types of fields
>   in the UPC pointer-to-shared representation.
>   gcc/c/
>   * c-upc-low.c: New.  Lower UPC constructs to GENERIC.
>   * c-upc-low.h: New.  Prototypes for c-upc-low.c.
>   * c-upc-pts-ops.c: New. Implement UPC pointer-to-shared-operations.
>   * c-upc-pts-ops.h: New. Prototypes for c-upc-pts-ops.c.
>   * c-upc-rts-names.h: New.  Names of some functions in the UPC runtime.
> 
> Index: gcc/c-family/c-upc-pts.h
> ===
> --- gcc/c-family/c-upc-pts.h  (.../trunk) (revision 0)
> +++ gcc/c-family/c-upc-pts.h  (.../branches/gupc) (revision 231080)
> @@ -0,0 +1,40 @@
> +/* Define UPC pointer-to-shared representation characteristics.
> +   Copyright (C) 2008-2015 Free Software Foundation, Inc.
> +   Contributed by Gary Funck 
> + and Nenad Vukicevic .
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +.  */
> +
> +#ifndef GCC_C_FAMILY_UPC_PTS_H
> +#define GCC_C_FAMILY_UPC_PTS_H 1
> +
> +#define UPC_PTS_SIZE(LONG_TYPE_SIZE + POINTER_SIZE)
> +#define UPC_PTS_PHASE_SIZE  (LONG_TYPE_SIZE / 2)
> +#define UPC_PTS_THREAD_SIZE (LONG_TYPE_SIZE / 2)
> +#define UPC_PTS_VADDR_SIZE  POINTER_SIZE
> +#define UPC_PTS_PHASE_TYPE  ((LONG_TYPE_SIZE == 64) \
> +  

[UPC 07/22] lowering, pointer-to-shared ops

2015-11-30 Thread Gary Funck

Background
--

An overview email, describing the UPC-related changes is here:
  https://gcc.gnu.org/ml/gcc-patches/2015-12/msg5.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


The UPC lowering pass traverses the current function tree
and rewrites UPC related statements and operations into GENERIC.
The resulting GENERIC tree code will retain UPC pointers-to-shared (PTS)
types, but all operations such as 'get' and 'put' which indirect
through a pointer-to-shared have been lowered to use the internal
representation type.  Most of these operations on UPC pointers-to-shared
is implemented in c/c-upc-pts-ops.c.

The UPC lowering pass is implemented by upc_genericize() in
c/c-upc-low.c.  upc_genericize() is called from finish_function()
in c/c-decl.c. It is called just prior to calling c_genericize(),
if -fupc has been asserted.

The file c/c-upc-rts-names.h defines the names of the UPC runtime
entry points and variables that implement the runtime ABI.
To date, there has been no need to implement target dependent names,
perhaps partly because UPC is supported primarily on POSIX-compliant targets.

UPC requires some special logic for handling file scoped initializations.
This is due to the fact that UPC shared addresses are not known
until runtime and therefore cannot be statically initialized
in the usual way.  For example, 'addr_x' below must be initialized
at runtime.

  shared int x;
  shared int *addr_x = 

The routine, upc_check_decl_init(), checks an initialization
statement to determine if it needs special handling.
It is called from store_init_value().  If an initialization
refers to UPC-related constructs that require initialization
at runtime, then upc_decl_init() is called to save the
initialization statement on a list.  This list is
processed by upc_write_global_declarations(), which
is called via a UPC-specific language hook from
c_common_parse_file(), just after calling c_parse_file().


2015-11-30  Gary Funck  

gcc/c-family/
* c-upc-pts.h: New.  Define the sizes and types of fields
in the UPC pointer-to-shared representation.
gcc/c/
* c-upc-low.c: New.  Lower UPC constructs to GENERIC.
* c-upc-low.h: New.  Prototypes for c-upc-low.c.
* c-upc-pts-ops.c: New. Implement UPC pointer-to-shared-operations.
* c-upc-pts-ops.h: New. Prototypes for c-upc-pts-ops.c.
* c-upc-rts-names.h: New.  Names of some functions in the UPC runtime.

Index: gcc/c-family/c-upc-pts.h
===
--- gcc/c-family/c-upc-pts.h(.../trunk) (revision 0)
+++ gcc/c-family/c-upc-pts.h(.../branches/gupc) (revision 231080)
@@ -0,0 +1,40 @@
+/* Define UPC pointer-to-shared representation characteristics.
+   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+   Contributed by Gary Funck 
+ and Nenad Vukicevic .
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#ifndef GCC_C_FAMILY_UPC_PTS_H
+#define GCC_C_FAMILY_UPC_PTS_H 1
+
+#define UPC_PTS_SIZE(LONG_TYPE_SIZE + POINTER_SIZE)
+#define UPC_PTS_PHASE_SIZE  (LONG_TYPE_SIZE / 2)
+#define UPC_PTS_THREAD_SIZE (LONG_TYPE_SIZE / 2)
+#define UPC_PTS_VADDR_SIZE  POINTER_SIZE
+#define UPC_PTS_PHASE_TYPE  ((LONG_TYPE_SIZE == 64) \
+   ? "uint32_t" : "uint16_t")
+#define UPC_PTS_THREAD_TYPE ((LONG_TYPE_SIZE == 64) \
+   ? "uint32_t" : "uint16_t")
+#define UPC_PTS_VADDR_TYPE  "char *"
+
+#define UPC_MAX_THREADS (1 << (((UPC_PTS_THREAD_SIZE)