What follows is an abridged email that outlines my ideas of how GCC UPC's GASP support should look from a user's point of view. I wrote this before I started my implementation to get a good idea of how best to get GASP support working with our PPW performance tool, especially because GCC UPC can be used as a frontend to Berkeley UPC. It's probably not of much interest to anyone not working on Berkeley UPC and GCC UPC, but I provide it here nonetheless.

From: Adam Leko
Subject: Re: GCC/UPC + GASP, take 2

It's probably best to illustrate what I'm envisioning by giving a
hypothetical scenario of how a new version of GCC-UPC with GASP
support might look and feel from a user's perspective:

Joe User downloads a shiny new copy of GCC UPC source code from the
website, and configures it as usual:

  wget 'http://intrepid.com/blah/upc-new-version.tar.gz'
  tar xvzf upc-new-version.tar.gz
  cd upc-X.Y
  mkdir bld
  cd bld
  ../configure --prefix=/foo/bar

This would configure GCC UPC with GASP support turned on, although the
user wouldn't know or care about this because nothing different happens
unless special flags are given during compilation.

So Joe User compiles all his regular UPC codes without any issues and
everything is peachy:

  upc -O3 -o mm mm.upc
  ./mm -n 4
  etc...

After debugging his program, Joe User notices he has a performance
problem that he's not able to track down.  He finds out about PPW and
downloads + installs it.  Our PPW autoconf script is able to find where
GCC-UPC is installs and that it has GASP support (it can already do
this), so nothing special is needed other than maybe pointing PPW to
where GCC UPC is installed if it's not in $PATH.

So now Joe User recompiles his application with PPW's thin wrapper
scripts, runs the app, and views the performance data:

  ppwupcc --inst -O3 -o mm mm.upc
  ppwrun -profile -output=mm.par ./mm -n 4
  ppw mm.par

"ppwupcc" is a script that takes care of calling upc with the
appropriate -finstrument-gasp argument, which tells upc to compile
against the gasp-enabled version of the libupc functions.  There's also
a -finstrument-gasp-functions flag that tells GCC UPC to instrument
function exit and entry points.

So now Joe User wants to run his app across a cluster.  He installs
Berkeley UPC with GCC as the frontend, and without having to recompile
GCC UPC he configures Berkeley UPC and points it at his GCC UPC install
tree.  Here he also has the option of installing Berkeley UPC with GASP
support, and "under the covers" the upcc script will compile with the
upc frontend using the same -finstrument-gasp flag when it sees a --inst
GASP flag.

... And of course, eventually they can do all of the above, except that
the shared access libupc calls will be inlined too...

=========

Now for some nitty-gritty details about how libupc and the UPC gimplify
process needs to be changed to support the above operation:

1) Add all standard GASP support code (headers, etc) needed that is
mentioned in my GCC UPC webpage

  http://www.hcs.ufl.edu/~leko/gccupc/

2) Add the following flags to the GCC UPC frontend:

 -finstrument-gasp flag
 -finstrument-gasp-functions flag
 #pragma pupc

3) When necessary, rewrite all UPC operations like upc_memget, etc to
take two extra arguments, which are __FILE__ and __LINE__.  This will
have to be done using some macro tricks inside gcc-upc-lib.h, in
addition to some #define's that are passed to the C preprocessor when
GASP is enabled.

4) During the gimplify pass, determine which flavor of the libupc
functions we should be calling and insert that into the gimplify tree.
As of right now, we need two versions of each function that is in
libupc: 1. the normal version that is currently there, and 2. a version
that takes in source information and call either gasp_event_notify.

In very rough pseudocode, it might logically be structured like this
(dots left out for code bits not important to control flow):

  ...
  libfunc_name = ...;
  libfunc = lookup_name(... (libfunc_name) ...);
  tree gaspargs = NULL_TREE;
  if (gasp_enabled && pragma_pupc_on) {
     libfunc = lookup_profiled_name(... (libfunc_name) ... );
     gaspargs = make tree of __FILE__, __LINE__
  }
  /* insert call to libfunc w/correct args */
  ...

=====

I hope this design sketch for GCC UPC + GASP is helpful, even if it is a
little lengthy for an email.

-Adam