This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [UPC 05/22] language hooks changes


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
> --------
>
> Two new UPC-specific 'decl' language hooks are defined and then called from
> layout_decl() in stor-layout.c.  The layout_decl_p() function tests if
> this is a UPC shared array declaration that requires special handling.
> If it does, then layout_decl() is called.
>
> A few new UPC-specific language hooks are defined in a 'upc' sub-structure
> of the language hooks structure.  They are defined as
> hooks because they are called from code in the 'c-family/' directory,
> but are implemented in the 'c/' directory.

Please post these together with the langhook uses, otherwise it's really hard
to review.

I'll note that whatever "special" layout you want for your pointer
representation
should be better ensured via attributes if possible.

Richard.

> 2015-11-30  Gary Funck  <gary@intrepid.com>
>
>         gcc/
>         * langhooks-def.h (lhd_do_nothing_b, lhd_do_nothing_t_t):
>         New do nothing hook prototypes.
>         (LANG_HOOKS_UPC_TOGGLE_KEYWORDS,
>         LANG_HOOKS_UPC_PTS_INIT_TYPE, LANG_HOOKS_UPC_BUILD_INIT_FUNC,
>         LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS): New default UPC hooks.
>         * langhooks-def.h (LANG_HOOKS_LAYOUT_DECL_P, LANG_HOOKS_LAYOUT_DECL):
>         New language hook defaults.
>         (LANG_HOOKS_UPC): New.  Define UPC hooks structure.
>         * langhooks.c (lhd_do_nothing_b, lhd_do_nothing_t_t):
>         New do nothing hooks.
>         * langhooks.h (layout_decl_p, layout_decl): New language hooks.
>         (lang_hooks_for_upc): New UPC language hooks structure.
>         * stor-layout.c (layout_decl): Call the layout_decl_p() and
>         and layout_decl() hooks.
>         gcc/c/
>         * c-lang.c: #include "c-upc-lang.h".
>         #include "c-upc-low.h".
>         (LANG_HOOKS_UPC_TOGGLE_KEYWORDS, LANG_HOOKS_UPC_PTS_INIT_TYPE,
>         LANG_HOOKS_UPC_BUILD_INIT_FUNC, LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS,
>         LANG_HOOKS_LAYOUT_DECL_P, LANG_HOOKS_LAYOUT_DECL):
>         Override defaults.  Define UPC-specific hook routines.
>         * c-upc-lang.c: New.  Implement UPC-specific hook routines.
>         * c-upc-lang.h: New.  Define UPC-specific hook prototypes.
>
> Index: gcc/langhooks-def.h
> ===================================================================
> --- gcc/langhooks-def.h (.../trunk)     (revision 231059)
> +++ gcc/langhooks-def.h (.../branches/gupc)     (revision 231080)
> @@ -35,7 +35,9 @@ struct diagnostic_info;
>  /* See langhooks.h for the definition and documentation of each hook.  */
>
>  extern void lhd_do_nothing (void);
> +extern void lhd_do_nothing_b (bool);
>  extern void lhd_do_nothing_t (tree);
> +extern void lhd_do_nothing_t_t (tree, tree);
>  extern void lhd_do_nothing_f (struct function *);
>  extern tree lhd_pass_through_t (tree);
>  extern bool lhd_post_options (const char **);
> @@ -175,6 +177,10 @@ extern tree lhd_make_node (enum tree_cod
>  #define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
>  #define LANG_HOOKS_DESCRIPTIVE_TYPE    NULL
>  #define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
> +#define LANG_HOOKS_UPC_TOGGLE_KEYWORDS  lhd_do_nothing_b
> +#define LANG_HOOKS_UPC_PTS_INIT_TYPE  lhd_do_nothing
> +#define LANG_HOOKS_UPC_BUILD_INIT_FUNC lhd_do_nothing_t
> +#define LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS lhd_do_nothing
>  #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE lhd_enum_underlying_base_type
>
>  #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
> @@ -219,6 +225,8 @@ extern tree lhd_make_node (enum tree_cod
>  #define LANG_HOOKS_OMP_CLAUSE_LINEAR_CTOR NULL
>  #define LANG_HOOKS_OMP_CLAUSE_DTOR hook_tree_tree_tree_null
>  #define LANG_HOOKS_OMP_FINISH_CLAUSE lhd_omp_finish_clause
> +#define LANG_HOOKS_LAYOUT_DECL_P hook_bool_tree_tree_false
> +#define LANG_HOOKS_LAYOUT_DECL lhd_do_nothing_t_t
>
>  #define LANG_HOOKS_DECLS { \
>    LANG_HOOKS_GLOBAL_BINDINGS_P, \
> @@ -243,7 +251,9 @@ extern tree lhd_make_node (enum tree_cod
>    LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP, \
>    LANG_HOOKS_OMP_CLAUSE_LINEAR_CTOR, \
>    LANG_HOOKS_OMP_CLAUSE_DTOR, \
> -  LANG_HOOKS_OMP_FINISH_CLAUSE \
> +  LANG_HOOKS_OMP_FINISH_CLAUSE, \
> +  LANG_HOOKS_LAYOUT_DECL_P, \
> +  LANG_HOOKS_LAYOUT_DECL \
>  }
>
>  /* LTO hooks.  */
> @@ -261,6 +271,13 @@ extern void lhd_end_section (void);
>    LANG_HOOKS_END_SECTION \
>  }
>
> +#define LANG_HOOKS_UPC { \
> +  LANG_HOOKS_UPC_TOGGLE_KEYWORDS, \
> +  LANG_HOOKS_UPC_PTS_INIT_TYPE, \
> +  LANG_HOOKS_UPC_BUILD_INIT_FUNC, \
> +  LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS \
> +}
> +
>  /* The whole thing.  The structure is defined in langhooks.h.  */
>  #define LANG_HOOKS_INITIALIZER { \
>    LANG_HOOKS_NAME, \
> @@ -300,6 +317,7 @@ extern void lhd_end_section (void);
>    LANG_HOOKS_DECLS, \
>    LANG_HOOKS_FOR_TYPES_INITIALIZER, \
>    LANG_HOOKS_LTO, \
> +  LANG_HOOKS_UPC, \
>    LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
>    LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
>    LANG_HOOKS_FUNCTION_PARAMETER_PACK_P, \
> Index: gcc/langhooks.c
> ===================================================================
> --- gcc/langhooks.c     (.../trunk)     (revision 231059)
> +++ gcc/langhooks.c     (.../branches/gupc)     (revision 231080)
> @@ -43,6 +43,13 @@ lhd_do_nothing (void)
>  {
>  }
>
> +/* Do nothing (bool).  */
> +
> +void
> +lhd_do_nothing_b (bool ARG_UNUSED (b))
> +{
> +}
> +
>  /* Do nothing (tree).  */
>
>  void
> @@ -50,6 +57,14 @@ lhd_do_nothing_t (tree ARG_UNUSED (t))
>  {
>  }
>
> +/* Do nothing (tree, tree).  */
> +
> +void
> +lhd_do_nothing_t_t (tree ARG_UNUSED (a),
> +                    tree ARG_UNUSED (b))
> +{
> +}
> +
>  /* Pass through (tree).  */
>  tree
>  lhd_pass_through_t (tree t)
> Index: gcc/langhooks.h
> ===================================================================
> --- gcc/langhooks.h     (.../trunk)     (revision 231059)
> +++ gcc/langhooks.h     (.../branches/gupc)     (revision 231080)
> @@ -240,6 +240,13 @@ struct lang_hooks_for_decls
>
>    /* Do language specific checking on an implicitly determined clause.  */
>    void (*omp_finish_clause) (tree clause, gimple_seq *pre_p);
> +
> +  /* Return true if language-specific layout is needed.  */
> +  bool (*layout_decl_p) (tree decl, tree type);
> +
> +  /* Perform language-specific layout.
> +     (Should be called only if the layout_decl_p hook is ture.)  */
> +  void (*layout_decl) (tree decl, tree type);
>  };
>
>  /* Language hooks related to LTO serialization.  */
> @@ -259,6 +266,25 @@ struct lang_hooks_for_lto
>    void (*end_section) (void);
>  };
>
> +/* Language hooks related to UPC.  */
> +
> +struct lang_hooks_for_upc
> +{
> +
> +  /* Enable/Disable UPC keywords.  */
> +  void (*toggle_keywords) (bool);
> +
> +  /* Define the UPC pointer-to-shared representation type.  */
> +  void (*pts_init_type) (void);
> +
> +  /* Build a function that will be called by the UPC runtime
> +     to initialize UPC shared variables.  */
> +  void (*build_init_func) (tree);
> +
> +  /* For the current compilation unit, write */
> +  void (*write_global_declarations) (void);
> +};
> +
>  /* Language-specific hooks.  See langhooks-def.h for defaults.  */
>
>  struct lang_hooks
> @@ -426,6 +452,8 @@ struct lang_hooks
>
>    struct lang_hooks_for_lto lto;
>
> +  struct lang_hooks_for_upc upc;
> +
>    /* Returns a TREE_VEC of the generic parameters of an instantiation of
>       a generic type or decl, e.g. C++ template instantiation.  If
>       TREE_CHAIN of the return value is set, it is an INTEGER_CST
> Index: gcc/stor-layout.c
> ===================================================================
> --- gcc/stor-layout.c   (.../trunk)     (revision 231059)
> +++ gcc/stor-layout.c   (.../branches/gupc)     (revision 231080)
> @@ -626,7 +626,11 @@ layout_decl (tree decl, unsigned int kno
>    if (DECL_MODE (decl) == VOIDmode)
>      DECL_MODE (decl) = TYPE_MODE (type);
>
> -  if (DECL_SIZE (decl) == 0)
> +  if (lang_hooks.decls.layout_decl_p (decl, type))
> +    {
> +      lang_hooks.decls.layout_decl (decl, type);
> +    }
> +  else if (DECL_SIZE (decl) == 0)
>      {
>        DECL_SIZE (decl) = TYPE_SIZE (type);
>        DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
> Index: gcc/c/c-lang.c
> ===================================================================
> --- gcc/c/c-lang.c      (.../trunk)     (revision 231059)
> +++ gcc/c/c-lang.c      (.../branches/gupc)     (revision 231080)
> @@ -25,6 +25,8 @@ along with GCC; see the file COPYING3.
>  #include "langhooks.h"
>  #include "langhooks-def.h"
>  #include "c-objc-common.h"
> +#include "c-upc-lang.h"
> +#include "c-upc-low.h"
>
>  enum c_language_kind c_language = clk_c;
>
> @@ -37,6 +39,18 @@ enum c_language_kind c_language = clk_c;
>  #define LANG_HOOKS_INIT c_objc_common_init
>  #undef LANG_HOOKS_INIT_TS
>  #define LANG_HOOKS_INIT_TS c_common_init_ts
> +#undef LANG_HOOKS_UPC_TOGGLE_KEYWORDS
> +#define LANG_HOOKS_UPC_TOGGLE_KEYWORDS upc_toggle_keywords
> +#undef LANG_HOOKS_UPC_PTS_INIT_TYPE
> +#define LANG_HOOKS_UPC_PTS_INIT_TYPE upc_pts_init_type
> +#undef LANG_HOOKS_UPC_BUILD_INIT_FUNC
> +#define LANG_HOOKS_UPC_BUILD_INIT_FUNC upc_build_init_func
> +#undef LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS
> +#define LANG_HOOKS_UPC_WRITE_GLOBAL_DECLS upc_write_global_declarations
> +#undef LANG_HOOKS_LAYOUT_DECL_P
> +#define LANG_HOOKS_LAYOUT_DECL_P upc_lang_layout_decl_p
> +#undef LANG_HOOKS_LAYOUT_DECL
> +#define LANG_HOOKS_LAYOUT_DECL upc_lang_layout_decl
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> Index: gcc/c/c-upc-lang.c
> ===================================================================
> --- gcc/c/c-upc-lang.c  (.../trunk)     (revision 0)
> +++ gcc/c/c-upc-lang.c  (.../branches/gupc)     (revision 231080)
> @@ -0,0 +1,347 @@
> +/* c-upc-lang.c: UPC language-specific functions.
> +   Copyright (C) 2003-2015 Free Software Foundation, Inc.
> +   Contributed by Gary Funck <gary@intrepid.com>
> +     and Nenad Vukicevic <nenad@intrepid.com>.
> +
> +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
> +<http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tm.h"
> +#include "tree.h"
> +#include "alias.h"
> +#include "stringpool.h"
> +#include "tree-iterator.h"
> +#include "c-tree.h"
> +#include "stor-layout.h"
> +#include "c-upc.h"
> +#include "c-upc-low.h"
> +#include "c-upc-pts-ops.h"
> +#include "c-upc-rts-names.h"
> +#include "c-family/c-upc-pts.h"
> +#include "common/common-target.h"
> +#include "varasm.h"
> +#include "target.h"
> +
> +static GTY (()) section *upc_init_array_section;
> +
> +/* Create a static variable of type 'type'.
> +   This routine mimics the behavior of 'objc_create_temporary_var'
> +   with the change that it creates a static (file scoped) variable.  */
> +static tree
> +upc_create_static_var (tree type, const char *name)
> +{
> +  tree id = get_identifier (name);
> +  tree decl = build_decl (input_location, VAR_DECL, id, type);
> +  TREE_USED (decl) = 1;
> +  TREE_STATIC (decl) = 1;
> +  TREE_READONLY (decl) = 1;
> +  TREE_THIS_VOLATILE (decl) = 0;
> +  TREE_ADDRESSABLE (decl) = 0;
> +  DECL_PRESERVE_P (decl) = 1;
> +  DECL_ARTIFICIAL (decl) = 1;
> +  DECL_EXTERNAL (decl) = 0;
> +  DECL_IGNORED_P (decl) = 1;
> +  DECL_CONTEXT (decl) = NULL;
> +  pushdecl_top_level (decl);
> +  return decl;
> +}
> +
> +/* Return TRUE if DECL's size is zero,
> +   and DECL is a UPC shared array.  */
> +bool
> +upc_lang_layout_decl_p (tree decl, tree type)
> +{
> +  int need_to_size_shared_array_decl = 0;
> +  tree t = type;
> +
> +  if (decl && DECL_SIZE (decl) == 0)
> +    {
> +      while (t != NULL && TREE_CODE (t) == ARRAY_TYPE
> +            && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
> +       t = TREE_TYPE (t);
> +
> +      if (t && TREE_CODE (t) == ARRAY_TYPE)
> +        {
> +         tree tt = TREE_TYPE (t);
> +         tree tt_size = TYPE_SIZE (tt);
> +          need_to_size_shared_array_decl =
> +           SHARED_TYPE_P (tt)
> +           && tt_size != NULL_TREE
> +            && !integer_zerop (tt_size);
> +        }
> +    }
> +  return need_to_size_shared_array_decl;
> +}
> +
> +/* Given that TYPE describes a UPC shared array, and that DECL's size hasn't
> +   been calculated, calculate the size of the type and adjust the size
> +   attributes in DECL.  */
> +
> +void
> +upc_lang_layout_decl (tree decl, tree type)
> +{
> +  tree t = type;
> +  gcc_checking_assert (upc_lang_layout_decl_p (decl, type));
> +  while (TREE_CODE (t) == ARRAY_TYPE
> +        && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
> +    t = TREE_TYPE (t);
> +
> +  {
> +    const tree elt_type = TREE_TYPE (t);
> +    const tree elt_size = TYPE_SIZE (elt_type);
> +    const tree block_factor = TYPE_HAS_BLOCK_FACTOR (elt_type)
> +      ? convert (bitsizetype, TYPE_BLOCK_FACTOR (elt_type)) : NULL;
> +    if (block_factor && integer_zerop (block_factor))
> +      {
> +       /* Allocate the entire UPC shared array on thread 0.  */
> +       if (TYPE_HAS_THREADS_FACTOR (type))
> +         {
> +           const tree n_threads =
> +             convert (bitsizetype, upc_num_threads ());
> +           DECL_SIZE (decl) = size_binop (MULT_EXPR, elt_size, n_threads);
> +         }
> +       else
> +         DECL_SIZE (decl) = TYPE_SIZE (type);
> +      }
> +    else
> +      {
> +       const tree t_size = TYPE_SIZE (type);
> +       const tree n_elem = size_binop (FLOOR_DIV_EXPR, t_size, elt_size);
> +       const tree n_threads = convert (bitsizetype, upc_num_threads ());
> +       if (TYPE_HAS_THREADS_FACTOR (type))
> +         {
> +           if (block_factor)
> +             {
> +               const tree blk_size = convert (bitsizetype, block_factor);
> +               tree t1, t2;
> +               t1 = size_binop (CEIL_DIV_EXPR, n_elem, blk_size);
> +               t2 = size_binop (MULT_EXPR, t1, blk_size);
> +               DECL_SIZE (decl) = size_binop (MULT_EXPR, t2, elt_size);
> +             }
> +           else
> +             DECL_SIZE (decl) = t_size;
> +         }
> +       else
> +         {
> +           /* We want to allocate ceiling (N_ELEM / N_THREADS)
> +              elements per thread, where N_ELEM is the total number of
> +              elements in the array.  If the array is blocked,
> +              then we allocate (ceiling (ceiling
> +                (N_ELEM / BLOCK_FACTOR) / N_THREADS)
> +                * block_factor) * N_ELEM_PER_THREAD.  */
> +           tree n_elem_per_thread;
> +           if (block_factor)
> +             {
> +               tree block_count, blocks_per_thread;
> +               block_count = size_binop (CEIL_DIV_EXPR,
> +                                         n_elem, block_factor);
> +               blocks_per_thread = size_binop (CEIL_DIV_EXPR,
> +                                               block_count, n_threads);
> +               n_elem_per_thread = size_binop (MULT_EXPR,
> +                                               blocks_per_thread,
> +                                               block_factor);
> +             }
> +           else
> +             n_elem_per_thread = size_binop (CEIL_DIV_EXPR,
> +                                             n_elem, n_threads);
> +
> +           /* In the special case of an array of size 1, we know that
> +              we want a constant size no matter what N_THREADS is.  Make
> +              the size a constant so that declarations of the form:
> +                shared int x[1];
> +              will work in a dynamic THREADS compilation environment.  */
> +           if (integer_onep (n_elem))
> +             DECL_SIZE (decl) = elt_size;
> +           else
> +             DECL_SIZE (decl) = size_binop (MULT_EXPR, n_elem_per_thread,
> +                                            elt_size);
> +         }
> +      }
> +    if (DECL_SIZE_UNIT (decl) == 0)
> +      DECL_SIZE_UNIT (decl)
> +       = fold_convert (sizetype,
> +                       size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
> +                                   bitsize_unit_node));
> +  }
> +}
> +
> +/* Initialize the UPC-specific parts of the compiler.  */
> +
> +static void
> +upc_parse_init (void)
> +{
> +  upc_pts_init ();
> +  upc_genericize_init ();
> +}
> +
> +/* Build the internal representation of UPC's pointer-to-shared type.  */
> +
> +void
> +upc_pts_init_type (void)
> +{
> +  tree fields = NULL_TREE;
> +  tree name = NULL_TREE;
> +  tree ref;
> +  machine_mode pts_mode;
> +  const location_t loc = UNKNOWN_LOCATION;
> +  struct c_struct_parse_info *null_struct_parse_info = NULL;
> +  int save_pedantic = pedantic;
> +  ref = start_struct (loc, RECORD_TYPE, name, &null_struct_parse_info);
> +  /* Ensure that shared pointers have twice the alignment of a pointer.  */
> +  TYPE_ALIGN (ref) = 2 * TYPE_ALIGN (ptr_type_node);
> +  TYPE_USER_ALIGN (ref) = 1;
> +  name = get_identifier ("vaddr");
> +  upc_vaddr_field_node = build_decl (loc, FIELD_DECL, name,
> +                                    build_pointer_type (char_type_node));
> +  fields = chainon (fields, upc_vaddr_field_node);
> +  DECL_NONADDRESSABLE_P (upc_vaddr_field_node) = 0;
> +  DECL_INITIAL (upc_vaddr_field_node) = NULL_TREE;
> +  upc_thread_field_node =
> +    build_decl (loc, FIELD_DECL, get_identifier ("thread"),
> +               c_common_type_for_size (UPC_PTS_THREAD_SIZE, 1));
> +  fields = chainon (fields, upc_thread_field_node);
> +  if (!(UPC_PTS_THREAD_SIZE % 8))
> +    {
> +      DECL_NONADDRESSABLE_P (upc_thread_field_node) = 0;
> +      DECL_INITIAL (upc_thread_field_node) = NULL_TREE;
> +    }
> +  else
> +    {
> +      DECL_NONADDRESSABLE_P (upc_thread_field_node) = 1;
> +      DECL_INITIAL (upc_thread_field_node) = size_int (UPC_PTS_THREAD_SIZE);
> +    }
> +  upc_phase_field_node =
> +    build_decl (loc, FIELD_DECL, get_identifier ("phase"),
> +               c_common_type_for_size (UPC_PTS_PHASE_SIZE, 1));
> +  fields = chainon (fields, upc_phase_field_node);
> +  if (!(UPC_PTS_PHASE_SIZE % 8))
> +    {
> +      DECL_NONADDRESSABLE_P (upc_phase_field_node) = 0;
> +      DECL_INITIAL (upc_phase_field_node) = NULL_TREE;
> +    }
> +  else
> +    {
> +      DECL_NONADDRESSABLE_P (upc_phase_field_node) = 1;
> +      DECL_INITIAL (upc_phase_field_node) = size_int (UPC_PTS_PHASE_SIZE);
> +    }
> +  /* Avoid spurious complaints regarding the definition of
> +     `phase' and `thread'.  */
> +  pedantic = 0;
> +  upc_pts_rep_type_node = finish_struct (loc, ref, fields, NULL_TREE,
> +                                        null_struct_parse_info);
> +  pedantic = save_pedantic;
> +  gcc_assert (TYPE_SIZE (upc_pts_rep_type_node));
> +  gcc_assert (tree_fits_uhwi_p (TYPE_SIZE (upc_pts_rep_type_node)));
> +  gcc_assert (tree_to_uhwi (TYPE_SIZE (upc_pts_rep_type_node))
> +             == 2 * POINTER_SIZE);
> +  pts_mode = mode_for_size_tree (TYPE_SIZE (upc_pts_rep_type_node),
> +                                 MODE_INT, 0);
> +  gcc_assert (pts_mode != BLKmode);
> +  SET_TYPE_MODE(upc_pts_rep_type_node, pts_mode);
> +  record_builtin_type (RID_SHARED, "upc_shared_ptr_t",
> +                      upc_pts_rep_type_node);
> +}
> +
> +/* Build a function that will be called by the UPC runtime
> +   to initialize UPC shared variables.  STMT_LIST is a
> +   list of initialization statements.  */
> +
> +void
> +upc_build_init_func (tree stmt_list)
> +{
> +  tree init_func_id = get_identifier (UPC_INIT_DECLS_FUNC);
> +  struct c_declspecs *specs;
> +  struct c_typespec void_spec;
> +  struct c_declarator *init_func_decl;
> +  struct c_arg_info args;
> +  tree init_func, fn_body;
> +  tree init_func_ptr_type, init_func_addr;
> +  location_t loc = input_location;
> +  int decl_ok;
> +  memset (&void_spec, '\0', sizeof (struct c_typespec));
> +  void_spec.kind = ctsk_typedef;
> +  void_spec.spec = lookup_name (get_identifier ("void"));
> +  specs = declspecs_add_type (loc, build_null_declspecs (), void_spec);
> +  init_func_decl = build_id_declarator (init_func_id);
> +  init_func_decl->id_loc = loc;
> +  memset (&args, '\0', sizeof (struct c_arg_info));
> +  args.types = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
> +  init_func_decl = build_function_declarator (&args, init_func_decl);
> +  decl_ok = start_function (specs, init_func_decl, NULL_TREE);
> +  gcc_assert (decl_ok);
> +  store_parm_decls ();
> +  init_func = current_function_decl;
> +  DECL_SOURCE_LOCATION (current_function_decl) = loc;
> +  TREE_PUBLIC (current_function_decl) = 0;
> +  TREE_USED (current_function_decl) = 1;
> +  fn_body = c_begin_compound_stmt (true);
> +  append_to_statement_list_force (stmt_list, &fn_body);
> +  fn_body = c_end_compound_stmt (loc, fn_body, true);
> +  add_stmt (fn_body);
> +  finish_function ();
> +  gcc_assert (DECL_RTL (init_func));
> +  mark_decl_referenced (init_func);
> +  DECL_PRESERVE_P (init_func) = 1;
> +  init_func_ptr_type = build_pointer_type (TREE_TYPE (init_func));
> +  init_func_addr = upc_create_static_var (init_func_ptr_type,
> +                                          "__upc_init_func_addr");
> +  DECL_INITIAL (init_func_addr) = build_unary_op (loc, ADDR_EXPR,
> +                                                  init_func, 0);
> +  set_decl_section_name (init_func_addr,
> +                         targetm.upc.init_array_section_name ());
> +}
> +
> +/* Enable/Disable UPC keywords.
> +   If ENABLE is true, UPC keywords are enabled.
> +   If ENABLE is false, UPC keywords are removed from consideration.
> +   This routine is used by the implementation of
> +   "#pragma upc upc_code" and "#pragma upc c_code" respectively.  */
> +
> +void
> +upc_toggle_keywords (bool enable)
> +{
> +  unsigned int i;
> +  tree id;
> +  for (i = 0; i < num_c_common_reswords; i++)
> +    {
> +      if (UPC_IS_KEYWORD (c_common_reswords[i].rid))
> +        {
> +         id = get_identifier (c_common_reswords[i].word);
> +         C_IS_RESERVED_WORD (id) = enable;
> +        }
> +    }
> +}
> +
> +/* UPC language-specific initialization.  */
> +
> +void
> +upc_lang_init (void)
> +{
> +  gcc_assert (flag_upc);
> +  if (!targetm_common.have_named_sections)
> +    {
> +      fatal_error (input_location,
> +                   "UPC is not implemented on this target; "
> +                  "the target linker does not support separately "
> +                  "linked sections");
> +    }
> +  upc_parse_init ();
> +}
> +
> +#include "gt-c-c-upc-lang.h"
> Index: gcc/c/c-upc-lang.h
> ===================================================================
> --- gcc/c/c-upc-lang.h  (.../trunk)     (revision 0)
> +++ gcc/c/c-upc-lang.h  (.../branches/gupc)     (revision 231080)
> @@ -0,0 +1,30 @@
> +/* c-upc-lang.h: UPC language-specific functions.
> +   Copyright (C) 2012-2015 Free Software Foundation, Inc.
> +   Contributed by Gary Funck <gary@intrepid.com>
> +     and Nenad Vukicevic <nenad@intrepid.com>.
> +
> +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
> +<http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GCC_C_UPC_LANG_H
> +#define GCC_C_UPC_LANG_H 1
> +extern void upc_pts_init_type (void);
> +extern void upc_build_init_func (tree);
> +extern void upc_toggle_keywords (bool);
> +extern bool upc_lang_layout_decl_p (tree, tree);
> +extern void upc_lang_layout_decl (tree, tree);
> +extern void upc_lang_init (void);
> +#endif /* !GCC_C_UPC_LANG_H */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]