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 introduces a new qualifier, "shared", that indicates that the
qualified object is located in a global shared address space that is
accessible by all UPC threads.  Additional qualifiers ("strict" and
"relaxed") further specify the semantics of accesses to
UPC shared objects.

In UPC, a shared qualified array can further specify a "layout
qualifier" (blocking factor) that indicates how the shared data
is blocked and distributed.

The following example illustrates the use of the UPC "shared" qualifier
combined with a layout qualifier.

    #define BLKSIZE 5
    #define N_PER_THREAD (4 * BLKSIZE)
    shared [BLKSIZE] double A[N_PER_THREAD*THREADS];

Above the "[BLKSIZE]" construct is the UPC layout qualifier; this
specifies that the shared array, A, distributes its elements across
each thread in blocks of 5 elements.  If the program is run with two
threads, then A is distributed as shown below:

    Thread 0    Thread 1
    --------    ---------
    A[ 0.. 4]   A[ 5.. 9]
    A[10..14]   A[15..19]
    A[20..24]   A[25..29]
    A[30..34]   A[35..39]

Above, the elements shown for thread 0 are defined as having "affinity"
to thread 0.  Similarly, those elements shown for thread 1 have
affinity to thread 1.  In UPC, a pointer to a shared object can be
cast to a thread local pointer (a "C" pointer), when the designated
shared object has affinity to the referencing thread.

A UPC "pointer-to-shared" (PTS) is a pointer that references a UPC
shared object.  A UPC pointer-to-shared is a "fat" pointer with the
following logical fields:
   (virt_addr, thread, phase)

The virtual address (virt_addr) field is combined with the thread
number (thread) to derive the location of the referenced object
within the UPC shared address space.  The phase field is used
keep track of the current block offset for PTS's that have
blocking factor that is greater than one.

GUPC implements pointer-to-shared objects using a "struct" internal
representation.  Until recently, GUPC also supported a "packed"
representation, which is more space efficient, but limits the range of
various fields in the UPC pointer-to-shared representation.  We have
decided to support only the "struct" representation so that the
compiler uses a single ABI that supports the full range of addresses,
threads, and blocking factors.

GCC's internal tree representation is extended to record the UPC
"shared", "strict", "relaxed" qualifiers, and the layout qualifier.

--- gcc/tree-core.h     (.../trunk)     (revision 228959)
+++ gcc/tree-core.h     (.../branches/gupc)     (revision 229159)
@@ -470,7 +470,11 @@ enum cv_qualifier {
   TYPE_QUAL_CONST    = 0x1,
   TYPE_QUAL_VOLATILE = 0x2,
   TYPE_QUAL_RESTRICT = 0x4,
-  TYPE_QUAL_ATOMIC   = 0x8
+  TYPE_QUAL_ATOMIC   = 0x8,
+  /* UPC qualifiers */
+  TYPE_QUAL_SHARED   = 0x10,
+  TYPE_QUAL_RELAXED  = 0x20,
+  TYPE_QUAL_STRICT   = 0x40
 };
[...]
@@ -857,9 +875,14 @@ struct GTY(()) tree_base {
       unsigned user_align : 1;
       unsigned nameless_flag : 1;
       unsigned atomic_flag : 1;
-      unsigned spare0 : 3;
-
-      unsigned spare1 : 8;
+      unsigned shared_flag : 1;
+      unsigned strict_flag : 1;
+      unsigned relaxed_flag : 1;
+
+      unsigned threads_factor_flag : 1;
+      unsigned block_factor_0 : 1;
+      unsigned block_factor_x : 1;
+      unsigned spare1 : 5;

A given type is a UPC shared type if its 'shared_flag' is set.
However, for array types, the shared_flag of the *element type*
must be checked.  Thus,

    /* Return TRUE if TYPE is a shared type.  For arrays,
       the element type must be queried, because array types
       are never qualified.  */
    #define SHARED_TYPE_P(TYPE) \
      ((TYPE) && TYPE_P (TYPE) \
       && TYPE_SHARED ((TREE_CODE (TYPE) != ARRAY_TYPE \
                        ? (TYPE) : strip_array_types (TYPE))))

By default, a type has a blocking factor of 1.  If the blocking factor is 0
(known as "indefinite") then 'block_factor_0' is set. If the blocking
factor is neither 0 nor 1, then 'block_factor_x' is set and the
actual blocking factor is found in a 'tree map' hash table called
'block_factor_htab' which is managed in tree.c.

This use of a garbage collected hash table which maps tree nodes to
a UPC blocking factor leads to a need to implement custom garbage
collection logic for all tree nodes.  This custom garbage collection
logic is implemented in gt_ggc_mx().  PCH support is implemented
in gt_pch_nx().  This custom garbage collector is defined in tree-core.h
as follows:

-struct GTY(()) tree_type_common {
+struct GTY((user)) tree_type_common {
   struct tree_common common;
   tree size;
   tree size_unit;
[...]
   tree pointer_to;
   tree reference_to;
   union tree_type_symtab {
-    int GTY ((tag ("TYPE_SYMTAB_IS_ADDRESS"))) address;
-    const char * GTY ((tag ("TYPE_SYMTAB_IS_POINTER"))) pointer;
-    struct die_struct * GTY ((tag ("TYPE_SYMTAB_IS_DIE"))) die;
-  } GTY ((desc ("debug_hooks->tree_type_symtab_field"))) symtab;
+    int address;
+    const char *pointer;
+    struct die_struct *die;
+  } symtab;
   tree canonical;
   tree next_variant;

Above, 'tree_type_symtab' has to be explicitly traversed by
the garbage collection routine.

2015-11-30  Gary Funck  <g...@intrepid.com>

        gcc/
        * expr.c (tree_expr_size): Move to tree.c and make it an
        extern function.
        * print-tree.c (print_node): Print UPC "shared" qualifier
        and blocking factor (if present).  Indicate THREADS scaling,
        if present.
        * tree-core.h (cv_qualifier): Add UPC type qualifiers:
        TYPE_QUAL_SHARED, TYPE_QUAL_RELAXED, and TYPE_QUAL_STRICT.
        (tree_index): Add UPC tree indexes:
        TI_UPC_PTS_TYPE, TI_UPC_PTS_REP_TYPE, TI_UPC_CHAR_PTS_TYPE,
        TI_UPC_PHASE_FIELD, TI_UPC_THREAD_FIELD, TI_UPC_VADDR_FIELD,
        TI_UPC_NULL_PTS.
        (tree_base): Add UPC-specific flags:
        shared_flag, strict_flag, relaxed_flag, threads_factor_flag,
        block_factor_0, block_factor_x.
        (tree_type_common): Remove ggc tag type descriptions in
        tree_type_symtab fields to accommodate UPC-related garbage collection
        changes.
        (gt_ggc_mx, gt_pch_nx, gt_pch_nx): New prototypes.
        Add custom garbage collection and PCH support for tree_type_common.
        * tree-dump.c (dequeue_and_dump): Add qualifier tags for
        UPC language qualifier (shared, strict, relaxed).
        * tree-pretty-print.c (dump_upc_type_quals): Print UPC language
        qualifiers and blocking factor.
        (dump_generic_node): Call dump_upc_type_quals()
        if the type asserts the "shared" qualifier.
        Print UPC qualifiers if applied to a tree node.
        Print type name for the UPC pointer-to-shared representation type.
        * tree-sra.c (find_param_candidates):
        Exclude UPC pointer-to-shared types.
        * tree.c: #include "debug.h".  Needed for access to symtab
        definition in the tree node garbage collection logic.
        (tm_block_factor_hasher, block_factor_htab): New.
        Define a garbage-collected mapping from tree node to
        UPC blocking factor.
        (init_ttree): Call block_factor_lookup_init().
        (copy_node_stat): Call SET_TYPE_BLOCK_FACTOR if
        type has a UPC blocking factor.
        (tree_expr_size): Move from expr.c and make it an
        'extern' function.
        (stabilize_reference_1): Copy UPC qualifiers to result.
        (build1_stat): Copy shared qualifier from type node.
        (build1_stat, build2_stat): For unary and binary operations,
        remove UPC "shared" qualifiers from the result type.
        (build3_stat): For reference expressions, ensure that
        the result node preserves the UPC qualifiers applied to the
        first argument.
        (set_type_quals): Add a 'tree' argument for the
        UPC layout qualifier (blocking factor).  Set the blocking factor
        if the type asserts the "shared" qualifier.
        (check_qualified_type): Add a 'tree' argument for the
        UPC layout qualifier (blocking factor).  Include the blocking factor
        into the type check.
        (check_aligned_type): Include the blocking factor
        into the type check.
        (get_qualified_type_1): Rename get_qualified_type()
        to get_qualified_type_1() and add a blocking factor argument.
        A #define of get_qualified_type is added to tree.h;
        it will call get_qualified_type_1() with a null layout qualifier.
        (build_qualified_type): Adjust calls to
        get_qualified_type_1() and set_type_quals().
        (build_pointer_type): For UPC pointer-to-shared types
        ensure that the resulting pointer type is compatible with the
        UPC pointer-to-shared representation type.
        (build_atomic_base): Adjust call to set_type_quals().
        (build_opaque_vector_type):
        Adjust call to check_qualified_type().
        (tree_nop_conversion): Handle conversions involving
        UPC pointer-to-shared types.
        (gt_ggc_mx, gt_pch_nx, gt_pch_nx): Implement custom
        garbage collection logic, necessitated by the use of a garbage
        collected hash tree map used to look up UPC blocking factors.
        Contributed by Meador Inge <mead...@codesourcery.com>.
        (get_block_factor, build_unshared_type,
        block_factor_lookup, block_factor_insert,
        block_factor_lookup_init): New.
        * tree.h (SHARED_TYPE_P, PTS_CVT_OP_P, TREE_QUALS,
        TREE_SHARED, TREE_STRICT, TREE_RELAXED,
        TYPE_SHARED, TYPE_STRICT, TYPE_RELAXED, TYPE_HAS_THREADS_FACTOR,
        TREE_FUNC_QUALS, TYPE_HAS_BLOCK_FACTOR_0, TYPE_HAS_BLOCK_FACTOR_X,
        TYPE_HAS_BLOCK_FACTOR, SET_TYPE_BLOCK_FACTOR): New.
        (TYPE_QUALS, TYPE_QUALS_NO_ADDR_SPACE,
        TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC):
        Add UPC type qualifiers (shared, relaxed, strict).
        (block_factor_insert, block_factor_lookup,
        build_unshared_type, block_factor_lookup_init,
        get_block_factor): New.  Declare prototypes.
        (SSA_VAR_P): Exclude UPC shared types.
        (upc_pts_type_node, upc_pts_rep_type_node,
        upc_char_pts_type_node, upc_phase_field_node,
        upc_thread_field_node, upc_vaddr_field_node,
        upc_null_pts_node): New.  Define UPC-related global tree nodes.
        (check_qualified_type, get_qualified_type_1):
        Adjust prototypes.
        (get_qualified_type): Re-implement as a pre-processor macro
        that invokes get_qualified_type_1() with a null blocking factor.
        (tree_expr_size): New. Declare prototype for function
        moved from expr.c into tree.c.

Index: gcc/expr.c
===================================================================
--- gcc/expr.c  (.../trunk)     (revision 231059)
+++ gcc/expr.c  (.../branches/gupc)     (revision 231080)
@@ -137,7 +137,6 @@ static void emit_single_push_insn (machi
 #endif
 static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, int);
 static rtx const_vector_from_tree (tree);
-static tree tree_expr_size (const_tree);
 static HOST_WIDE_INT int_expr_size (tree);
 
 
@@ -11566,18 +11565,6 @@ get_personality_function (tree decl)
   return XEXP (DECL_RTL (personality), 0);
 }
 
-/* Returns a tree for the size of EXP in bytes.  */
-
-static tree
-tree_expr_size (const_tree exp)
-{
-  if (DECL_P (exp)
-      && DECL_SIZE_UNIT (exp) != 0)
-    return DECL_SIZE_UNIT (exp);
-  else
-    return size_in_bytes (TREE_TYPE (exp));
-}
-
 /* Return an rtx for the size in bytes of the value of EXP.  */
 
 rtx
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c    (.../trunk)     (revision 231059)
+++ gcc/print-tree.c    (.../branches/gupc)     (revision 231080)
@@ -299,6 +299,8 @@ print_node (FILE *file, const char *pref
     fputs (" readonly", file);
   if (TYPE_P (node) && TYPE_ATOMIC (node))
     fputs (" atomic", file);
+  if (TREE_SHARED (node))
+    fputs (" shared", file);
   if (!TYPE_P (node) && TREE_CONSTANT (node))
     fputs (" constant", file);
   else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
@@ -607,6 +609,14 @@ print_node (FILE *file, const char *pref
 
       print_node (file, "size", TYPE_SIZE (node), indent + 4);
       print_node (file, "unit size", TYPE_SIZE_UNIT (node), indent + 4);
+      if (TYPE_SHARED (node))
+        {
+          if (TYPE_HAS_THREADS_FACTOR(node))
+           fputs (" THREADS factor", file);
+         if (TYPE_HAS_BLOCK_FACTOR (node))
+           print_node (file, "block factor",
+                       TYPE_BLOCK_FACTOR (node), indent + 4);
+        }
       indent_to (file, indent + 3);
 
       if (TYPE_USER_ALIGN (node))
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h     (.../trunk)     (revision 231059)
+++ gcc/tree-core.h     (.../branches/gupc)     (revision 231080)
@@ -501,7 +501,11 @@ enum cv_qualifier {
   TYPE_QUAL_CONST    = 0x1,
   TYPE_QUAL_VOLATILE = 0x2,
   TYPE_QUAL_RESTRICT = 0x4,
-  TYPE_QUAL_ATOMIC   = 0x8
+  TYPE_QUAL_ATOMIC   = 0x8,
+  /* UPC qualifiers */
+  TYPE_QUAL_SHARED   = 0x10,
+  TYPE_QUAL_RELAXED  = 0x20,
+  TYPE_QUAL_STRICT   = 0x40
 };
 
 /* Standard named or nameless data types of the C compiler.  */
@@ -578,6 +582,14 @@ enum tree_index {
   TI_FILEPTR_TYPE,
   TI_POINTER_SIZED_TYPE,
 
+  TI_UPC_PTS_TYPE,
+  TI_UPC_PTS_REP_TYPE,
+  TI_UPC_CHAR_PTS_TYPE,
+  TI_UPC_PHASE_FIELD,
+  TI_UPC_THREAD_FIELD,
+  TI_UPC_VADDR_FIELD,
+  TI_UPC_NULL_PTS,
+
   TI_POINTER_BOUNDS_TYPE,
 
   TI_DFLOAT32_TYPE,
@@ -880,9 +892,14 @@ struct GTY(()) tree_base {
       unsigned user_align : 1;
       unsigned nameless_flag : 1;
       unsigned atomic_flag : 1;
-      unsigned spare0 : 3;
-
-      unsigned spare1 : 8;
+      unsigned shared_flag : 1;
+      unsigned strict_flag : 1;
+      unsigned relaxed_flag : 1;
+
+      unsigned threads_factor_flag : 1;
+      unsigned block_factor_0 : 1;
+      unsigned block_factor_x : 1;
+      unsigned spare1 : 5;
 
       /* This field is only used with TREE_TYPE nodes; the only reason it is
         present in tree_base instead of tree_type is to save space.  The size
@@ -1411,7 +1428,7 @@ struct GTY(()) tree_block {
   struct die_struct *die;
 };
 
-struct GTY(()) tree_type_common {
+struct GTY((user)) tree_type_common {
   struct tree_common common;
   tree size;
   tree size_unit;
@@ -1441,10 +1458,10 @@ struct GTY(()) tree_type_common {
   tree pointer_to;
   tree reference_to;
   union tree_type_symtab {
-    int GTY ((tag ("TYPE_SYMTAB_IS_ADDRESS"))) address;
-    const char * GTY ((tag ("TYPE_SYMTAB_IS_POINTER"))) pointer;
-    struct die_struct * GTY ((tag ("TYPE_SYMTAB_IS_DIE"))) die;
-  } GTY ((desc ("debug_hooks->tree_type_symtab_field"))) symtab;
+    int address;
+    const char *pointer;
+    struct die_struct *die;
+  } symtab;
   tree canonical;
   tree next_variant;
   tree main_variant;
@@ -1452,6 +1469,11 @@ struct GTY(()) tree_type_common {
   tree name;
 };
 
+/* Garbage collection and PCH support for tree_type_common.  */
+extern void gt_ggc_mx (tree_type_common *t);
+extern void gt_pch_nx (tree_type_common *t);
+extern void gt_pch_nx (tree_type_common *t, gt_pointer_operator, void *);
+
 struct GTY(()) tree_type_with_lang_specific {
   struct tree_type_common common;
   /* Points to a structure whose details depend on the language in use.  */
Index: gcc/tree-dump.c
===================================================================
--- gcc/tree-dump.c     (.../trunk)     (revision 231059)
+++ gcc/tree-dump.c     (.../branches/gupc)     (revision 231080)
@@ -387,10 +387,13 @@ dequeue_and_dump (dump_info_p di)
 
       if (quals != TYPE_UNQUALIFIED)
        {
-         fprintf (di->stream, "qual: %c%c%c     ",
+         fprintf (di->stream, "qual: %c%c%c%c%c%c  ",
                   (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
                   (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
-                  (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
+                  (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ',
+                  (quals & TYPE_QUAL_SHARED) ? 's' : ' ',
+                  (quals & TYPE_QUAL_STRICT) ? 't' : ' ',
+                  (quals & TYPE_QUAL_RELAXED) ? 'x' : ' ');
          di->column += 14;
        }
 
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c     (.../trunk)     (revision 231059)
+++ gcc/tree-pretty-print.c     (.../branches/gupc)     (revision 231080)
@@ -1105,6 +1105,25 @@ dump_block_node (pretty_printer *pp, tre
 }
 
 
+static void
+dump_upc_type_quals (pretty_printer *buffer, tree type, int quals)
+{
+  gcc_assert (type && TYPE_CHECK (type));
+  gcc_assert (quals & TYPE_QUAL_SHARED);
+  if (quals & TYPE_QUAL_STRICT)
+    pp_string (buffer, "strict ");
+  if (quals & TYPE_QUAL_RELAXED)
+    pp_string (buffer, "relaxed ");
+  pp_string (buffer, "shared ");
+  if (TYPE_HAS_BLOCK_FACTOR (type))
+    {
+      tree block_factor = TYPE_BLOCK_FACTOR (type);
+      pp_string (buffer, "[");
+      pp_wide_integer (buffer, TREE_INT_CST_LOW (block_factor));
+      pp_string (buffer, "] ");
+    }
+}
+
 /* Dump the node NODE on the pretty_printer PP, SPC spaces of
    indent.  FLAGS specifies details to show in the dump (see TDF_* in
    dumpfile.h).  If IS_STMT is true, the object printed is considered
@@ -1204,6 +1223,8 @@ dump_generic_node (pretty_printer *pp, t
          pp_string (pp, "volatile ");
        else if (quals & TYPE_QUAL_RESTRICT)
          pp_string (pp, "restrict ");
+       else if (quals & TYPE_QUAL_SHARED)
+          dump_upc_type_quals (pp, node, quals);
 
        if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
          {
@@ -1346,6 +1367,14 @@ dump_generic_node (pretty_printer *pp, t
            pp_string (pp, " volatile");
          if (quals & TYPE_QUAL_RESTRICT)
            pp_string (pp, " restrict");
+          if (quals & TYPE_QUAL_SHARED)
+           {
+             if (quals & TYPE_QUAL_STRICT)
+               pp_string (pp, " strict");
+             if (quals & TYPE_QUAL_RELAXED)
+               pp_string (pp, " relaxed");
+              pp_string (pp, " shared");
+           }
 
          if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
            {
@@ -1515,6 +1544,8 @@ dump_generic_node (pretty_printer *pp, t
          pp_string (pp, "const ");
        if (quals & TYPE_QUAL_VOLATILE)
          pp_string (pp, "volatile ");
+       if (quals & TYPE_QUAL_SHARED)
+          dump_upc_type_quals (pp, node, quals);
 
         /* Print the name of the structure.  */
         if (TREE_CODE (node) == RECORD_TYPE)
@@ -1522,7 +1553,12 @@ dump_generic_node (pretty_printer *pp, t
         else if (TREE_CODE (node) == UNION_TYPE)
          pp_string (pp, "union ");
 
-        if (TYPE_NAME (node))
+       if (upc_pts_rep_type_node && node == upc_pts_rep_type_node)
+         /* Normally, builtin types will not be printed.
+            We short-circuit that check for the UPC "struct PTS"
+            representation type.  */
+         pp_string (pp, "upc_shared_ptr_t");
+        else if (TYPE_NAME (node))
          dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
        else if (!(flags & TDF_SLIM))
          /* FIXME: If we eliminate the 'else' above and attempt
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c      (.../trunk)     (revision 231059)
+++ gcc/tree-sra.c      (.../branches/gupc)     (revision 231080)
@@ -3882,6 +3882,7 @@ find_param_candidates (void)
 
          if (TREE_CODE (type) == FUNCTION_TYPE
              || TYPE_VOLATILE (type)
+             || SHARED_TYPE_P (type)
              || (TREE_CODE (type) == ARRAY_TYPE
                  && TYPE_NONALIASED_COMPONENT (type))
              || !is_gimple_reg (parm)
Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (.../trunk)     (revision 231059)
+++ gcc/tree.c  (.../branches/gupc)     (revision 231080)
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.
 #include "langhooks-def.h"
 #include "tree-diagnostic.h"
 #include "except.h"
+#include "debug.h"
 #include "builtins.h"
 #include "print-tree.h"
 #include "ipa-utils.h"
@@ -243,7 +244,23 @@ struct tree_vec_map_cache_hasher : ggc_c
 static GTY ((cache))
      hash_table<tree_vec_map_cache_hasher> *debug_args_for_decl;
 
-static void set_type_quals (tree, int);
+struct tm_block_factor_hasher : ggc_cache_ptr_hash<tree_map>
+{
+  static hashval_t hash (tree_map *m) { return tree_map_hash (m); }
+  static bool equal (tree_map *a, tree_map *b) { return tree_map_eq (a, b); }
+
+  static int
+  keep_cache_entry (tree_map *&e)
+  {
+    return ggc_marked_p (e->base.from);
+  }
+};
+
+/* Hash table for block factor lookups when the block factor
+   is not 0 (the indefinite block factor) or 1 (the default).  */
+static GTY((cache)) hash_table<tm_block_factor_hasher> *block_factor_htab;
+
+static void set_type_quals (tree, int, tree);
 static void print_type_hash_statistics (void);
 static void print_debug_expr_statistics (void);
 static void print_value_expr_statistics (void);
@@ -639,6 +656,9 @@ init_ttree (void)
   type_hash_table
     = hash_table<type_cache_hasher>::create_ggc (TYPE_HASH_INITIAL_SIZE);
 
+  /* Initialize hash table used to manage blocking factors.  */
+  block_factor_lookup_init ();
+
   debug_expr_for_decl
     = hash_table<tree_decl_map_cache_hasher>::create_ggc (512);
 
@@ -1197,6 +1217,9 @@ copy_node_stat (tree node MEM_STAT_DECL)
          TYPE_CACHED_VALUES_P (t) = 0;
          TYPE_CACHED_VALUES (t) = NULL_TREE;
        }
+
+      if (TYPE_HAS_BLOCK_FACTOR (node))
+        SET_TYPE_BLOCK_FACTOR (t, TYPE_BLOCK_FACTOR (node));
     }
     else if (code == TARGET_OPTION_NODE)
       {
@@ -2932,6 +2955,18 @@ size_in_bytes (const_tree type)
   return t;
 }
 
+/* Returns a tree for the size of EXP in bytes.  */
+
+tree
+tree_expr_size (const_tree exp)
+{
+  if (DECL_P (exp)
+      && DECL_SIZE_UNIT (exp) != 0)
+    return DECL_SIZE_UNIT (exp);
+  else
+    return size_in_bytes (TREE_TYPE (exp));
+}
+
 /* Return the size of TYPE (in bytes) as a wide integer
    or return -1 if the size can vary or is larger than an integer.  */
 
@@ -4155,6 +4190,9 @@ stabilize_reference_1 (tree e)
   TREE_READONLY (result) = TREE_READONLY (e);
   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
+  TREE_SHARED (result)  = TREE_SHARED (e);
+  TREE_STRICT (result)  = TREE_STRICT (e);
+  TREE_RELAXED (result) = TREE_RELAXED (e);
 
   return result;
 }
@@ -4238,6 +4276,9 @@ stabilize_reference (tree ref)
   TREE_READONLY (result) = TREE_READONLY (ref);
   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
+  TREE_SHARED (result)  = TREE_SHARED (ref);
+  TREE_STRICT (result)  = TREE_STRICT (ref);
+  TREE_RELAXED (result) = TREE_RELAXED (ref);
 
   return result;
 }
@@ -4381,6 +4422,7 @@ build1_stat (enum tree_code code, tree t
       /* Whether a dereference is readonly has nothing to do with whether
         its operand is readonly.  */
       TREE_READONLY (t) = 0;
+      TREE_SHARED (t) = SHARED_TYPE_P (type);
       break;
 
     case ADDR_EXPR:
@@ -4396,6 +4438,12 @@ build1_stat (enum tree_code code, tree t
       if (TREE_CODE_CLASS (code) == tcc_reference
          && node && TREE_THIS_VOLATILE (node))
        TREE_THIS_VOLATILE (t) = 1;
+      /* Drop the "shared" type qualifier for
+         expressions involving shared objects.  */ 
+      if (TREE_CODE_CLASS (code) == tcc_unary
+         && node && !TYPE_P (node)
+         && SHARED_TYPE_P (type))
+       TREE_TYPE (t) = build_unshared_type (type);
       break;
     }
 
@@ -4439,6 +4487,10 @@ build2_stat (enum tree_code code, tree t
                && ptrofftype_p (TREE_TYPE (arg1)));
 
   t = make_node_stat (code PASS_MEM_STAT);
+
+  /* Remove shared type qualifiers from the result type.  */
+  if (SHARED_TYPE_P (tt))
+    tt = build_unshared_type (tt);
   TREE_TYPE (t) = tt;
 
   /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
@@ -4516,6 +4568,14 @@ build3_stat (enum tree_code code, tree t
   TREE_THIS_VOLATILE (t)
     = (TREE_CODE_CLASS (code) == tcc_reference
        && arg0 && TREE_THIS_VOLATILE (arg0));
+  TREE_SHARED (t)
+    = (TREE_CODE_CLASS (code) == tcc_reference
+       && arg0 && TREE_SHARED (arg0));
+  if (TREE_SHARED (t))
+    {
+      TREE_STRICT (t)  = TREE_STRICT (arg0);
+      TREE_RELAXED (t) = TREE_RELAXED (arg0);
+    }
 
   return t;
 }
@@ -6464,16 +6524,22 @@ handle_dll_attribute (tree * pnode, tree
 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
 
 /* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
-   of the various TYPE_QUAL values.  */
+   of the various TYPE_QUAL values.  Also, set the blocking factor,
+   which is either null or a reference to an integral constant.  */
 
 static void
-set_type_quals (tree type, int type_quals)
+set_type_quals (tree type, int type_quals, tree block_factor)
 {
   TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
   TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
   TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0;
   TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
+  TYPE_SHARED (type) = (type_quals & TYPE_QUAL_SHARED) != 0;
+  TYPE_STRICT (type) = (type_quals & TYPE_QUAL_STRICT) != 0;
+  TYPE_RELAXED (type) = (type_quals & TYPE_QUAL_RELAXED) != 0;
+  if (TYPE_SHARED (type))
+    SET_TYPE_BLOCK_FACTOR (type, block_factor);
 }
 
 /* Returns true iff unqualified CAND and BASE are equivalent.  */
@@ -6490,12 +6556,15 @@ check_base_type (const_tree cand, const_
                                   TYPE_ATTRIBUTES (base)));
 }
 
-/* Returns true iff CAND is equivalent to BASE with TYPE_QUALS.  */
+/* Returns true iff CAND is equivalent to BASE with TYPE_QUALS
+   and BLOCK_FACTOR.  */
 
 bool
-check_qualified_type (const_tree cand, const_tree base, int type_quals)
+check_qualified_type (const_tree cand, const_tree base,
+                      int type_quals, tree block_factor)
 {
   return (TYPE_QUALS (cand) == type_quals
+         && TYPE_BLOCK_FACTOR (cand) == block_factor
          && check_base_type (cand, base));
 }
 
@@ -6505,6 +6574,7 @@ static bool
 check_aligned_type (const_tree cand, const_tree base, unsigned int align)
 {
   return (TYPE_QUALS (cand) == TYPE_QUALS (base)
+         && TYPE_BLOCK_FACTOR (cand) == TYPE_BLOCK_FACTOR (base)
          && TYPE_NAME (cand) == TYPE_NAME (base)
          /* Apparently this is needed for Objective-C.  */
          && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
@@ -6557,11 +6627,11 @@ find_atomic_core_type (tree type)
 }
 
 /* Return a version of the TYPE, qualified as indicated by the
-   TYPE_QUALS, if one exists.  If no qualified version exists yet,
-   return NULL_TREE.  */
+   TYPE_QUALS, and BLOCK_FACTOR if one exists.
+   If no qualified version exists yet, return NULL_TREE.  */
 
 tree
-get_qualified_type (tree type, int type_quals)
+get_qualified_type_1 (tree type, int type_quals, tree block_factor)
 {
   tree t;
 
@@ -6572,28 +6642,28 @@ get_qualified_type (tree type, int type_
      like the one we need to have.  If so, use that existing one.  We must
      preserve the TYPE_NAME, since there is code that depends on this.  */
   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-    if (check_qualified_type (t, type, type_quals))
+    if (check_qualified_type (t, type, type_quals, block_factor))
       return t;
 
   return NULL_TREE;
 }
 
-/* Like get_qualified_type, but creates the type if it does not
+/* Like get_qualified_type_1, but creates the type if it does not
    exist.  This function never returns NULL_TREE.  */
 
 tree
-build_qualified_type (tree type, int type_quals)
+build_qualified_type_1 (tree type, int type_quals, tree block_factor)
 {
   tree t;
 
   /* See if we already have the appropriate qualified variant.  */
-  t = get_qualified_type (type, type_quals);
+  t = get_qualified_type_1 (type, type_quals, block_factor);
 
   /* If not, build it.  */
   if (!t)
     {
       t = build_variant_type_copy (type);
-      set_type_quals (t, type_quals);
+      set_type_quals (t, type_quals, block_factor);
 
       if (((type_quals & TYPE_QUAL_ATOMIC) == TYPE_QUAL_ATOMIC))
        {
@@ -7934,6 +8004,16 @@ build_pointer_type (tree to_type)
   addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
                                              : TYPE_ADDR_SPACE (to_type);
   machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  if (SHARED_TYPE_P (to_type))
+    {
+      tree upc_pts_type;
+      pointer_mode = TYPE_MODE (upc_pts_rep_type_node);
+      upc_pts_type = build_pointer_type_for_mode (to_type, pointer_mode,
+                                                  false);
+      TYPE_USER_ALIGN (upc_pts_type) = TYPE_USER_ALIGN (upc_pts_rep_type_node);
+      TYPE_ALIGN (upc_pts_type) = TYPE_ALIGN (upc_pts_rep_type_node);
+      return upc_pts_type;
+    }
   return build_pointer_type_for_mode (to_type, pointer_mode, false);
 }
 
@@ -9991,7 +10071,7 @@ build_atomic_base (tree type, unsigned i
     return t;
   
   t = build_variant_type_copy (type);
-  set_type_quals (t, TYPE_QUAL_ATOMIC);
+  set_type_quals (t, TYPE_QUAL_ATOMIC, NULL_TREE);
 
   if (align)
     TYPE_ALIGN (t) = align;
@@ -10724,7 +10804,7 @@ build_opaque_vector_type (tree innertype
   cand = TYPE_NEXT_VARIANT (t);
   if (cand
       && TYPE_VECTOR_OPAQUE (cand)
-      && check_qualified_type (cand, t, TYPE_QUALS (t)))
+      && check_qualified_type (cand, t, TYPE_QUALS (t), NULL_TREE))
     return cand;
   /* Othewise build a variant type and make sure to queue it after
      the non-opaque type.  */
@@ -12205,6 +12285,7 @@ static inline bool
 tree_nop_conversion (const_tree exp)
 {
   tree outer_type, inner_type;
+  int outer_is_pts_p, inner_is_pts_p;
 
   if (!CONVERT_EXPR_P (exp)
       && TREE_CODE (exp) != NON_LVALUE_EXPR)
@@ -12218,6 +12299,22 @@ tree_nop_conversion (const_tree exp)
   if (!inner_type)
     return false;
 
+  outer_is_pts_p = (POINTER_TYPE_P (outer_type)
+                    && SHARED_TYPE_P (TREE_TYPE (outer_type)));
+  inner_is_pts_p = (POINTER_TYPE_P (inner_type)
+                    && SHARED_TYPE_P (TREE_TYPE (inner_type)));
+
+  /* Pointer-to-shared types have special
+     equivalence rules that must be checked.  */
+  if (outer_is_pts_p && inner_is_pts_p
+      && lang_hooks.types_compatible_p)
+    return lang_hooks.types_compatible_p (outer_type, inner_type);
+
+  /* Pointer-to-shared types are not interchangeable
+     with integral types.  */
+  if (outer_is_pts_p || inner_is_pts_p)
+    return false;
+
   return tree_nop_conversion_p (outer_type, inner_type);
 }
 
@@ -12731,6 +12828,121 @@ block_may_fallthru (const_tree block)
     }
 }
 
+/* Garbage collection support for tree_type_common.  */
+
+extern void gt_ggc_mx (tree&);
+extern void gt_ggc_mx_die_struct (void *);
+
+void gt_ggc_mx (tree_type_common *tt)
+{
+  tree t = (tree) tt;
+  tree block_factor = TYPE_BLOCK_FACTOR (t);
+
+  gt_ggc_mx (tt->common.typed.type);
+  gt_ggc_mx (tt->common.chain);
+  gt_ggc_mx (tt->size);
+  gt_ggc_mx (tt->size_unit);
+  gt_ggc_mx (tt->attributes);
+  gt_ggc_mx (tt->pointer_to);
+  gt_ggc_mx (tt->reference_to);
+  switch (debug_hooks->tree_type_symtab_field)
+    {
+    case TYPE_SYMTAB_IS_ADDRESS:
+      break;
+    case TYPE_SYMTAB_IS_POINTER:
+      gt_ggc_m_S (tt->symtab.pointer);
+      break;
+    case TYPE_SYMTAB_IS_DIE:
+      gt_ggc_mx_die_struct (tt->symtab.die);
+      break;
+    default:
+      break;
+    }
+  gt_ggc_mx (tt->name);
+  gt_ggc_mx (tt->next_variant);
+  gt_ggc_mx (tt->main_variant);
+  gt_ggc_mx (tt->context);
+  gt_ggc_mx (tt->canonical);
+
+  if (TYPE_HAS_BLOCK_FACTOR_X (t))
+    gt_ggc_mx (block_factor);
+}
+
+/* PCH support for tree_type_common.  */
+
+extern void gt_pch_nx (tree&);
+extern void gt_ggc_nx_die_struct (void *);
+
+void gt_pch_nx (tree_type_common *tt)
+{
+  tree t = (tree) tt;
+  tree block_factor = TYPE_BLOCK_FACTOR (t);
+
+  gt_pch_nx (tt->common.typed.type);
+  gt_pch_nx (tt->common.chain);
+  gt_pch_nx (tt->size);
+  gt_pch_nx (tt->size_unit);
+  gt_pch_nx (tt->attributes);
+  gt_pch_nx (tt->pointer_to);
+  gt_pch_nx (tt->reference_to);
+  switch (debug_hooks->tree_type_symtab_field)
+    {
+    case TYPE_SYMTAB_IS_ADDRESS:
+      break;
+    case TYPE_SYMTAB_IS_POINTER:
+      gt_pch_n_S (tt->symtab.pointer);
+      break;
+    case TYPE_SYMTAB_IS_DIE:
+      gt_pch_nx_die_struct (tt->symtab.die);
+      break;
+    default:
+      break;
+    }
+  gt_pch_nx (tt->name);
+  gt_pch_nx (tt->next_variant);
+  gt_pch_nx (tt->main_variant);
+  gt_pch_nx (tt->context);
+  gt_pch_nx (tt->canonical);
+
+  if (TYPE_HAS_BLOCK_FACTOR_X (t))
+    gt_pch_nx (block_factor);
+}
+
+void gt_pch_nx (tree_type_common *tt, gt_pointer_operator op, void *cookie)
+{
+  tree t = (tree) tt;
+  tree block_factor = TYPE_BLOCK_FACTOR (t);
+
+  op (&(tt->common.typed.type), cookie);
+  op (&(tt->common.chain), cookie);
+  op (&(tt->size), cookie);
+  op (&(tt->size_unit), cookie);
+  op (&(tt->attributes), cookie);
+  op (&(tt->pointer_to), cookie);
+  op (&(tt->reference_to), cookie);
+  switch (debug_hooks->tree_type_symtab_field)
+    {
+    case TYPE_SYMTAB_IS_ADDRESS:
+      break;
+    case TYPE_SYMTAB_IS_POINTER:
+      op (&(tt->symtab.pointer), cookie);
+      break;
+    case TYPE_SYMTAB_IS_DIE:
+      op (&(tt->symtab.die), cookie);
+      break;
+    default:
+      break;
+    }
+  op (&(tt->name), cookie);
+  op (&(tt->next_variant), cookie);
+  op (&(tt->main_variant), cookie);
+  op (&(tt->context), cookie);
+  op (&(tt->canonical), cookie);
+
+  if (TYPE_HAS_BLOCK_FACTOR_X (t))
+    op (&(block_factor), cookie);
+}
+
 /* True if we are using EH to handle cleanups.  */
 static bool using_eh_for_cleanups_flag = false;
 
@@ -13901,6 +14113,103 @@ nonnull_arg_p (const_tree arg)
   return false;
 }
 
+/* Return the blocking factor of the shared type, TYPE.
+   If the blocking factor is NULL, then return the default blocking
+   factor of 1.  */
+
+tree
+get_block_factor (const tree type)
+{
+  tree block_factor = size_one_node;
+  const tree elt_type = strip_array_types (type);
+  if (elt_type && (TREE_CODE (elt_type) != ERROR_MARK)
+      && TYPE_HAS_BLOCK_FACTOR (elt_type))
+    block_factor = TYPE_BLOCK_FACTOR (elt_type);
+  return block_factor;
+}
+
+/* Return a variant of TYPE, where the shared, strict, and relaxed
+   qualifiers have been removed.  */
+
+tree
+build_unshared_type (tree type)
+{
+  tree u_type = type;
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      const tree elem_type = TREE_TYPE(type);
+      const tree u_elem_type = build_unshared_type (elem_type);
+      if (u_elem_type != elem_type)
+        {
+          for (u_type = TYPE_MAIN_VARIANT (type);
+               u_type && TREE_TYPE(u_type) != u_elem_type;
+               u_type = TYPE_NEXT_VARIANT (u_type)) /* loop */;
+          if (!u_type)
+            {
+              u_type = build_variant_type_copy (type);
+              TREE_TYPE (u_type) = u_elem_type;
+            }
+        }
+    }
+  else
+    {
+      const int quals = TYPE_QUALS (type);
+      const int u_quals = quals & ~(TYPE_QUAL_SHARED
+                                    | TYPE_QUAL_RELAXED
+                                    | TYPE_QUAL_STRICT);
+      u_type = build_qualified_type (type, u_quals);
+    }
+  return u_type;
+}
+
+/* Lookup the block size of TYPE, and return it if we find one.  */
+
+tree
+block_factor_lookup (const_tree type)
+{
+  struct tree_map in;
+  union
+    {
+      const_tree ct;
+      tree t;
+    } ct_to_t;
+  ct_to_t.ct = type;
+  /* Drop the const qualifier, avoid the warning.  */
+  in.base.from = ct_to_t.t;
+  in.hash = TYPE_HASH (in.base.from);
+  struct tree_map **loc = block_factor_htab->
+                            find_slot_with_hash (&in, in.hash, NO_INSERT);
+  gcc_assert (loc != NULL);
+  struct tree_map *h = *loc;
+  if (h)
+    return h->to;
+  return NULL_TREE;
+}
+
+/* Insert a mapping TYPE->BLOCK_FACTOR in the block factor hashtable.  */
+
+void
+block_factor_insert (tree type, tree block_factor)
+{
+
+  gcc_assert (type && TYPE_P (type));
+  gcc_assert (block_factor && INTEGRAL_TYPE_P (TREE_TYPE (block_factor)));
+  gcc_assert (!(integer_zerop (block_factor) || integer_onep (block_factor)));
+  tree_map *h = ggc_alloc<tree_map> ();
+  h->base.from = type;
+  h->hash = TYPE_HASH (type);
+  h->to = block_factor;
+  tree_map **loc = block_factor_htab->
+                     find_slot_with_hash (h, h->hash, INSERT);
+  *loc = h;
+}
+
+void
+block_factor_lookup_init (void)
+{
+  block_factor_htab = hash_table<tm_block_factor_hasher>::create_ggc (17);
+}
+
 /* Given location LOC, strip away any packed range information
    or ad-hoc information.  */
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h  (.../trunk)     (revision 231059)
+++ gcc/tree.h  (.../branches/gupc)     (revision 231080)
@@ -636,6 +636,24 @@ extern void omp_clause_range_check_faile
 #define FUNC_OR_METHOD_TYPE_P(NODE) \
   (TREE_CODE (NODE) == FUNCTION_TYPE || TREE_CODE (NODE) == METHOD_TYPE)
 
+/* Return TRUE if TYPE is a shared type.  For arrays,
+   the element type must be queried, because array types
+   are never qualified.  */
+#define SHARED_TYPE_P(TYPE) \
+  ((TYPE) && TYPE_P (TYPE) \
+   && TYPE_SHARED ((TREE_CODE (TYPE) != ARRAY_TYPE \
+                    ? (TYPE) : strip_array_types (TYPE))))
+
+/* Return TRUE if EXP is a conversion operation involving
+   pointers-to-shared.  If either of the types involved
+   in the conversion is a pointer-to-shared type, return TRUE.  */
+#define PTS_CVT_OP_P(EXP) \
+  ((EXP) && ((POINTER_TYPE_P (TREE_TYPE (EXP)) \
+              && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (EXP, 0)))) \
+              && (SHARED_TYPE_P (TREE_TYPE (TREE_TYPE (EXP))) \
+                  || SHARED_TYPE_P (TREE_TYPE ( \
+                       TREE_TYPE (TREE_OPERAND (EXP, 0)))))))
+
 /* Define many boolean fields that all tree nodes have.  */
 
 /* In VAR_DECL, PARM_DECL and RESULT_DECL nodes, nonzero means address
@@ -812,6 +830,14 @@ extern void omp_clause_range_check_faile
 #define DECL_UNSIGNED(NODE) \
   (DECL_COMMON_CHECK (NODE)->base.u.bits.unsigned_flag)
 
+/* Convert tree flags to type qualifiers.  */
+#define TREE_QUALS(NODE)                               \
+  ((TREE_READONLY(NODE) * TYPE_QUAL_CONST) |           \
+   (TREE_THIS_VOLATILE(NODE) * TYPE_QUAL_VOLATILE) |   \
+   (TREE_SHARED(NODE) * TYPE_QUAL_SHARED) |            \
+   (TREE_STRICT(NODE) * TYPE_QUAL_STRICT) |            \
+   (TREE_RELAXED(NODE) * TYPE_QUAL_RELAXED))
+
 /* In integral and pointer types, means an unsigned type.  */
 #define TYPE_UNSIGNED(NODE) (TYPE_CHECK (NODE)->base.u.bits.unsigned_flag)
 
@@ -941,6 +967,11 @@ extern void omp_clause_range_check_faile
 #define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \
   (IDENTIFIER_NODE_CHECK (NODE)->base.deprecated_flag)
 
+/* Shared, strict, and relaxed common tree flags */
+#define TREE_SHARED(NODE) ((NODE)->base.u.bits.shared_flag)
+#define TREE_STRICT(NODE) ((NODE)->base.u.bits.strict_flag)
+#define TREE_RELAXED(NODE) ((NODE)->base.u.bits.relaxed_flag)
+
 /* In an aggregate type, indicates that the scalar fields of the type are
    stored in reverse order from the target order.  This effectively
    toggles BYTES_BIG_ENDIAN and WORDS_BIG_ENDIAN within the type.  */
@@ -1887,6 +1918,21 @@ extern machine_mode element_mode (const_
    the term.  */
 #define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type_common.restrict_flag)
 
+/* If nonzero, this type is `shared'-qualified, in the UPC dialect */
+#define TYPE_SHARED(NODE) (TYPE_CHECK (NODE)->base.u.bits.shared_flag)
+
+/* If nonzero, this type is `strict'-qualified, in the UPC dialect  */
+#define TYPE_STRICT(NODE) (TYPE_CHECK (NODE)->base.u.bits.strict_flag)
+
+/* If nonzero, this type is `relaxed'-qualified, in the UPC dialect  */
+#define TYPE_RELAXED(NODE) \
+  (TYPE_CHECK (NODE)->base.u.bits.relaxed_flag)
+
+/* Record that we are processing a UPC shared array declaration
+   or type definition that refers to THREADS in its array dimension.*/
+#define TYPE_HAS_THREADS_FACTOR(NODE) \
+  (TYPE_CHECK (NODE)->base.u.bits.threads_factor_flag)
+
 /* If nonzero, type's name shouldn't be emitted into debug info.  */
 #define TYPE_NAMELESS(NODE) (TYPE_CHECK (NODE)->base.u.bits.nameless_flag)
 
@@ -1911,13 +1957,24 @@ extern machine_mode element_mode (const_
          | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE)         \
          | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC)             \
          | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)         \
+         | (TYPE_SHARED (NODE) * TYPE_QUAL_SHARED)             \
+         | (TYPE_STRICT (NODE) * TYPE_QUAL_STRICT)             \
+         | (TYPE_RELAXED (NODE) * TYPE_QUAL_RELAXED)           \
          | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE)))))
 
+/* The set of qualifiers pertinent to a FUNCTION_DECL node.  */
+#define TREE_FUNC_QUALS(NODE)                          \
+  ((TREE_READONLY (NODE) * TYPE_QUAL_CONST)            \
+   | (TREE_THIS_VOLATILE (NODE) * TYPE_QUAL_VOLATILE))
+
 /* The same as TYPE_QUALS without the address space qualifications.  */
 #define TYPE_QUALS_NO_ADDR_SPACE(NODE)                         \
   ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST)             \
          | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE)         \
          | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC)             \
+         | (TYPE_SHARED (NODE) * TYPE_QUAL_SHARED)             \
+         | (TYPE_STRICT (NODE) * TYPE_QUAL_STRICT)             \
+         | (TYPE_RELAXED (NODE) * TYPE_QUAL_RELAXED)           \
          | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)))
 
 /* The same as TYPE_QUALS without the address space and atomic 
@@ -1925,8 +1982,72 @@ extern machine_mode element_mode (const_
 #define TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC(NODE)               \
   ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST)             \
          | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE)         \
+          | (TYPE_SHARED (NODE) * TYPE_QUAL_SHARED)            \
+          | (TYPE_STRICT (NODE) * TYPE_QUAL_STRICT)            \
+          | (TYPE_RELAXED (NODE) * TYPE_QUAL_RELAXED)          \
          | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)))
 
+/* Non-zero if the blocking factor is 0.  */
+#define TYPE_HAS_BLOCK_FACTOR_0(NODE)  \
+  TYPE_CHECK (NODE)->base.u.bits.block_factor_0
+
+/* Non-zero if the blocking factor is greater than 1.
+   In this case, the blocking factor value is stored in a hash table.  */
+#define TYPE_HAS_BLOCK_FACTOR_X(NODE) \
+  TYPE_CHECK (NODE)->base.u.bits.block_factor_x
+
+/* Non-zero if the blocking factor is not equal to 1 (the default).  */
+#define TYPE_HAS_BLOCK_FACTOR(NODE) \
+  (TYPE_SHARED(NODE) \
+   && (TYPE_HAS_BLOCK_FACTOR_0 (NODE) \
+       || TYPE_HAS_BLOCK_FACTOR_X (NODE)))
+
+/* Return the blocking factor of the type given by NODE..
+   The default block factor is one.  The additional flag bits
+   over-ride the default.  */
+#define TYPE_BLOCK_FACTOR(NODE) \
+  (TYPE_SHARED (NODE) \
+    ? (TYPE_HAS_BLOCK_FACTOR_0 (NODE) ? size_zero_node \
+      : TYPE_HAS_BLOCK_FACTOR_X (NODE) ? block_factor_lookup (NODE) \
+      : NULL_TREE) \
+    : NULL_TREE)
+
+/* Set the block factor in the type described by NODE.
+   For a zero blocking factor set TYPE_BLOCK_FACTOR_0 (NODE). 
+   For a blocking factor greater than 1, insert the value
+   into a hash table indexed by NODE, and then set the
+   flag TYPE_BLOCK_FACTOR_X (NODE).  */
+#define SET_TYPE_BLOCK_FACTOR(NODE, VAL) \
+  do { \
+    if (TYPE_SHARED (NODE)) \
+      { \
+       TYPE_HAS_BLOCK_FACTOR_0 (NODE) = 0; \
+       TYPE_HAS_BLOCK_FACTOR_X (NODE) = 0; \
+       if (VAL) \
+         { \
+           gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (VAL))); \
+           if (!integer_onep (VAL)) \
+             { \
+               if (integer_zerop (VAL)) \
+                 TYPE_HAS_BLOCK_FACTOR_0 (NODE) = 1; \
+               else \
+                 { \
+                   TYPE_HAS_BLOCK_FACTOR_X (NODE) = 1; \
+                   block_factor_insert (NODE, VAL); \
+                 } \
+             } \
+          } \
+      } \
+    else \
+      gcc_assert (!VAL); \
+  } while (0)
+
+extern void block_factor_insert (tree, tree);
+extern tree block_factor_lookup (const_tree);
+extern tree build_unshared_type (tree);
+extern void block_factor_lookup_init (void);
+extern tree get_block_factor (const tree);
+
 /* These flags are available for each language front end to use internally.  */
 #define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_0)
 #define TYPE_LANG_FLAG_1(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_1)
@@ -2176,7 +2297,7 @@ extern machine_mode element_mode (const_
 /* Nonzero if DECL represents an SSA name or a variable that can possibly
    have an associated SSA name.  */
 #define SSA_VAR_P(DECL)                                                        
\
-       (TREE_CODE (DECL) == VAR_DECL                                   \
+       ((TREE_CODE (DECL) == VAR_DECL && !TREE_SHARED (DECL))          \
         || TREE_CODE (DECL) == PARM_DECL                               \
         || TREE_CODE (DECL) == RESULT_DECL                             \
         || TREE_CODE (DECL) == SSA_NAME)
@@ -3611,6 +3732,17 @@ tree_operand_check_code (const_tree __t,
 #define boolean_false_node             global_trees[TI_BOOLEAN_FALSE]
 #define boolean_true_node              global_trees[TI_BOOLEAN_TRUE]
 
+/* The UPC type `void *'.  */
+#define upc_pts_type_node      global_trees[TI_UPC_PTS_TYPE]
+
+/* UPC pointer to shared qualified object representation */
+#define upc_pts_rep_type_node  global_trees[TI_UPC_PTS_REP_TYPE]
+#define upc_char_pts_type_node global_trees[TI_UPC_CHAR_PTS_TYPE]
+#define upc_phase_field_node   global_trees[TI_UPC_PHASE_FIELD]
+#define upc_thread_field_node  global_trees[TI_UPC_THREAD_FIELD]
+#define upc_vaddr_field_node   global_trees[TI_UPC_VADDR_FIELD]
+#define upc_null_pts_node      global_trees[TI_UPC_NULL_PTS]
+
 /* The decimal floating point types. */
 #define dfloat32_type_node              global_trees[TI_DFLOAT32_TYPE]
 #define dfloat64_type_node              global_trees[TI_DFLOAT64_TYPE]
@@ -4151,20 +4283,25 @@ extern tree handle_dll_attribute (tree *
 extern bool check_base_type (const_tree cand, const_tree base);
 
 /* Check whether CAND is suitable to be returned from get_qualified_type
-   (BASE, TYPE_QUALS).  */
+   (BASE, TYPE_QUALS, BLOCK_FACTOR).  */
 
-extern bool check_qualified_type (const_tree, const_tree, int);
+extern bool check_qualified_type (const_tree cand, const_tree base,
+                                 int type_quals, tree block_factor);
 
 /* Return a version of the TYPE, qualified as indicated by the
-   TYPE_QUALS, if one exists.  If no qualified version exists yet,
-   return NULL_TREE.  */
+   TYPE_QUALS and BLOCK_FACTOR, if one exists.
+   If no qualified version exists yet, return NULL_TREE.  */
 
-extern tree get_qualified_type (tree, int);
+extern tree get_qualified_type_1 (tree type, int type_quals, tree 
block_factor);
+#define get_qualified_type(TYPE, QUALS) \
+          get_qualified_type_1 (TYPE, QUALS, 0)
 
 /* Like get_qualified_type, but creates the type if it does not
    exist.  This function never returns NULL_TREE.  */
 
-extern tree build_qualified_type (tree, int);
+extern tree build_qualified_type_1 (tree type, int type_quals, tree 
block_factor);
+#define build_qualified_type(TYPE, QUALS) \
+   build_qualified_type_1 (TYPE, QUALS, 0)
 
 /* Create a variant of type T with alignment ALIGN.  */
 
@@ -4195,6 +4332,7 @@ extern tree type_hash_canon (unsigned in
 extern tree convert (tree, tree);
 extern unsigned int expr_align (const_tree);
 extern tree size_in_bytes (const_tree);
+extern tree tree_expr_size (const_tree);
 extern HOST_WIDE_INT int_size_in_bytes (const_tree);
 extern HOST_WIDE_INT max_int_size_in_bytes (const_tree);
 extern tree bit_position (const_tree);

Reply via email to