[PATCH 2/7] OpenMP 4.0 offloading infrastructure: LTO streaming.
authorIlya Verbin <ilya.verbin@intel.com>
Thu, 13 Nov 2014 13:37:38 +0000 (13:37 +0000)
committerKirill Yukhin <kyukhin@gcc.gnu.org>
Thu, 13 Nov 2014 13:37:38 +0000 (13:37 +0000)
gcc/
* cgraph.c: Include context.h.
(cgraph_node::create): Set node->offloadable and g->have_offload if
decl have "omp declare target" attribute.
* cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags.
* cgraphunit.c: Include lto-section-names.h.
(ipa_passes): Call ipa_write_summaries if there is something to write to
OFFLOAD_SECTION_NAME_PREFIX sections.
(symbol_table::compile): Set flag_generate_lto if there is something to
offload.
Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init.
* context.c (gcc::context::context): Initialize have_offload with false.
* context.h (class context): Add have_offload flag.
* ipa-inline-analysis.c (inline_generate_summary): Do not exit under
flag_generate_lto.
(inline_free_summary): Always remove hooks.
* lto-cgraph.c (referenced_from_other_partition_p): Ignore references
from non-offloadable nodes while streaming a node into offload section.
(reachable_from_other_partition_p): Likewise.
(select_what_to_stream): New function.
(compute_ltrans_boundary): Do not call
lto_set_symtab_encoder_in_partition if the node should not be streamed.
* lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define.
(section_name_prefix): Declare.
* lto-streamer.c (section_name_prefix): New variable.
(lto_get_section_name): Use section_name_prefix instead of
LTO_SECTION_NAME_PREFIX.
* lto-streamer.h (select_what_to_stream): Declare.
* omp-low.c: Include context.h.
(is_targetreg_ctx): New function.
(scan_sharing_clauses): Use offloadable flag, instead of an attribute.
(create_omp_child_function, check_omp_nesting_restrictions): Use new
is_targetreg_ctx function.  Replace usage of "omp declare target"
attribute with a cgraph_node flag offloadable.
(expand_omp_target): Set mark_force_output for offloadable functions.
(lower_omp_critical): Set offloadable flag for omp critical symbol.
* passes.c (ipa_write_summaries): New argument offload_lto_mode.  Call
select_what_to_stream.  Do not call lto_set_symtab_encoder_in_partition
if the node should not be streamed out.
* tree-pass.h (ipa_write_summaries): New bool argument.
* varpool.c: Include context.h.
(varpool_node::get_create): Set node->offloadable and g->have_offload if
decl have "omp declare target" attribute.

gcc/lto/
* lto-object.c (lto_obj_add_section): Use section_name_prefix instead of
LTO_SECTION_NAME_PREFIX.
* lto-partition.c (lto_promote_cross_file_statics): Call
select_what_to_stream.
* lto.c (lto_section_with_id): Use section_name_prefix instead of
LTO_SECTION_NAME_PREFIX.
(read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if
being built as an offload compiler.

Co-Authored-By: Andrey Turetskiy <andrey.turetskiy@intel.com>
Co-Authored-By: Bernd Schmidt <bernds@codesourcery.com>
Co-Authored-By: Michael Zolotukhin <michael.v.zolotukhin@intel.com>
From-SVN: r217486

19 files changed:
gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/context.c
gcc/context.h
gcc/ipa-inline-analysis.c
gcc/lto-cgraph.c
gcc/lto-section-names.h
gcc/lto-streamer.c
gcc/lto-streamer.h
gcc/lto/ChangeLog
gcc/lto/lto-object.c
gcc/lto/lto-partition.c
gcc/lto/lto.c
gcc/omp-low.c
gcc/passes.c
gcc/tree-pass.h
gcc/varpool.c

index 80df1888a3b7717a8bcb00884dbeca31fd83f1ea..316a00a74b3f63f95517e0282e871bd44899905a 100644 (file)
@@ -1,3 +1,51 @@
+2014-11-13  Ilya Verbin  <ilya.verbin@intel.com>
+           Bernd Schmidt  <bernds@codesourcery.com>
+           Andrey Turetskiy  <andrey.turetskiy@intel.com>
+           Michael Zolotukhin  <michael.v.zolotukhin@intel.com>
+
+       * cgraph.c: Include context.h.
+       (cgraph_node::create): Set node->offloadable and g->have_offload if
+       decl have "omp declare target" attribute.
+       * cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags.
+       * cgraphunit.c: Include lto-section-names.h.
+       (ipa_passes): Call ipa_write_summaries if there is something to write to
+       OFFLOAD_SECTION_NAME_PREFIX sections.
+       (symbol_table::compile): Set flag_generate_lto if there is something to
+       offload.
+       Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init.
+       * context.c (gcc::context::context): Initialize have_offload with false.
+       * context.h (class context): Add have_offload flag.
+       * ipa-inline-analysis.c (inline_generate_summary): Do not exit under
+       flag_generate_lto.
+       (inline_free_summary): Always remove hooks.
+       * lto-cgraph.c (referenced_from_other_partition_p): Ignore references
+       from non-offloadable nodes while streaming a node into offload section.
+       (reachable_from_other_partition_p): Likewise.
+       (select_what_to_stream): New function.
+       (compute_ltrans_boundary): Do not call
+       lto_set_symtab_encoder_in_partition if the node should not be streamed.
+       * lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define.
+       (section_name_prefix): Declare.
+       * lto-streamer.c (section_name_prefix): New variable.
+       (lto_get_section_name): Use section_name_prefix instead of
+       LTO_SECTION_NAME_PREFIX.
+       * lto-streamer.h (select_what_to_stream): Declare.
+       * omp-low.c: Include context.h.
+       (is_targetreg_ctx): New function.
+       (scan_sharing_clauses): Use offloadable flag, instead of an attribute.
+       (create_omp_child_function, check_omp_nesting_restrictions): Use new
+       is_targetreg_ctx function.  Replace usage of "omp declare target"
+       attribute with a cgraph_node flag offloadable.
+       (expand_omp_target): Set mark_force_output for offloadable functions.
+       (lower_omp_critical): Set offloadable flag for omp critical symbol.
+       * passes.c (ipa_write_summaries): New argument offload_lto_mode.  Call
+       select_what_to_stream.  Do not call lto_set_symtab_encoder_in_partition
+       if the node should not be streamed out.
+       * tree-pass.h (ipa_write_summaries): New bool argument.
+       * varpool.c: Include context.h.
+       (varpool_node::get_create): Set node->offloadable and g->have_offload if
+       decl have "omp declare target" attribute.
+
 2014-11-13  Bernd Schmidt  <bernds@codesourcery.com>
            Thomas Schwinge  <thomas@codesourcery.com>
            Ilya Verbin  <ilya.verbin@intel.com>
index 7216b89718436157bfab5339129192328daabbcf..8dcccbf19c6e2f13ae28b9375da767a495908a7b 100644 (file)
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "profile.h"
 #include "params.h"
 #include "tree-chkp.h"
+#include "context.h"
 
 /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  */
 #include "tree-pass.h"
@@ -494,6 +495,14 @@ cgraph_node::create (tree decl)
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
 
   node->decl = decl;
+
+  if (flag_openmp
+      && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
+    {
+      node->offloadable = 1;
+      g->have_offload = true;
+    }
+
   node->register_symbol ();
 
   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
index e2becb96d5656557aae2d8ae179741ea6dc8820e..1395bc1b4d9d2d373f02b4d117042e1c04d09d3d 100644 (file)
@@ -450,6 +450,13 @@ public:
   /* Set when init priority is set.  */
   unsigned in_init_priority_hash : 1;
 
+  /* Set when symbol needs to be streamed into LTO bytecode for LTO, or in case
+     of offloading, for separate compilation for a different target.  */
+  unsigned need_lto_streaming : 1;
+
+  /* Set when symbol can be streamed into bytecode for offloading.  */
+  unsigned offloadable : 1;
+
 
   /* Ordering of all symtab entries.  */
   int order;
index 25af2347f42844a27d7f48dc8009ce78d8ad33cc..9f49ed05f6ec2a23fe157b781e342b1f82015fbb 100644 (file)
@@ -224,6 +224,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 #include "dbgcnt.h"
 #include "tree-chkp.h"
+#include "lto-section-names.h"
 
 /* Queue of cgraph nodes scheduled to be added into cgraph.  This is a
    secondary queue used during optimization to accommodate passes that
@@ -2079,7 +2080,18 @@ ipa_passes (void)
     targetm.asm_out.lto_start ();
 
   if (!in_lto_p)
-    ipa_write_summaries ();
+    {
+      if (g->have_offload)
+       {
+         section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
+         ipa_write_summaries (true);
+       }
+      if (flag_lto)
+       {
+         section_name_prefix = LTO_SECTION_NAME_PREFIX;
+         ipa_write_summaries (false);
+       }
+    }
 
   if (flag_generate_lto)
     targetm.asm_out.lto_end ();
@@ -2163,8 +2175,12 @@ symbol_table::compile (void)
     fprintf (stderr, "Performing interprocedural optimizations\n");
   state = IPA;
 
+  /* Offloading requires LTO infrastructure.  */
+  if (!in_lto_p && g->have_offload)
+    flag_generate_lto = 1;
+
   /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
-  if (flag_lto)
+  if (flag_generate_lto)
     lto_streamer_hooks_init ();
 
   /* Don't run the IPA passes if there was any error or sorry messages.  */
index 5339e28a98b0c89e340175b3b211ec1dec812f72..9279be40dd74a25e4eeb144d83aacda3b13b4519 100644 (file)
@@ -30,6 +30,8 @@ gcc::context *g;
 
 gcc::context::context ()
 {
+  have_offload = false;
+
   /* The pass manager's constructor uses the dump manager (to set up
      dumps for the various passes), so the dump manager must be set up
      before the pass manager.  */
index b8fb439f1af9d1d40ebc0f3165f416448297d10f..689ae5ad1874b4e9d13e7b7b5f5451cbac979993 100644 (file)
@@ -33,6 +33,9 @@ class context
 public:
   context ();
 
+  /* The flag shows if there are symbols to be streamed for offloading.  */
+  bool have_offload;
+
   /* Pass-management.  */
 
   pass_manager *get_passes () { gcc_assert (m_passes); return m_passes; }
index eb1c6ec2d0def83313c10a989b5b812bcf57b5ac..0373b108699a2dd376d055e409b16651b53c94b6 100644 (file)
@@ -4024,7 +4024,7 @@ inline_generate_summary (void)
 
   /* When not optimizing, do not bother to analyze.  Inlining is still done
      because edge redirection needs to happen there.  */
-  if (!optimize && !flag_lto && !flag_wpa)
+  if (!optimize && !flag_generate_lto && !flag_wpa)
     return;
 
   function_insertion_hook_holder =
@@ -4339,11 +4339,6 @@ void
 inline_free_summary (void)
 {
   struct cgraph_node *node;
-  if (!inline_edge_summary_vec.exists ())
-    return;
-  FOR_EACH_DEFINED_FUNCTION (node)
-    if (!node->alias)
-      reset_inline_summary (node);
   if (function_insertion_hook_holder)
     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
@@ -4359,6 +4354,11 @@ inline_free_summary (void)
   if (edge_duplication_hook_holder)
     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
+  if (!inline_edge_summary_vec.exists ())
+    return;
+  FOR_EACH_DEFINED_FUNCTION (node)
+    if (!node->alias)
+      reset_inline_summary (node);
   vec_free (inline_summary_vec);
   inline_edge_summary_vec.release ();
   if (edge_predicate_pool)
index da1f0e446822f33d6e9b39b7148b2f7df37d80aa..fc8410c1c3ebfdc56752a809e5308d9e0c0a3898 100644 (file)
@@ -330,6 +330,11 @@ referenced_from_other_partition_p (symtab_node *node, lto_symtab_encoder_t encod
 
   for (i = 0; node->iterate_referring (i, ref); i++)
     {
+      /* Ignore references from non-offloadable nodes while streaming NODE into
+        offload LTO section.  */
+      if (!ref->referring->need_lto_streaming)
+       continue;
+
       if (ref->referring->in_other_partition
           || !lto_symtab_encoder_in_partition_p (encoder, ref->referring))
        return true;
@@ -348,9 +353,16 @@ reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t
   if (node->global.inlined_to)
     return false;
   for (e = node->callers; e; e = e->next_caller)
-    if (e->caller->in_other_partition
-       || !lto_symtab_encoder_in_partition_p (encoder, e->caller))
-      return true;
+    {
+      /* Ignore references from non-offloadable nodes while streaming NODE into
+        offload LTO section.  */
+      if (!e->caller->need_lto_streaming)
+       continue;
+
+      if (e->caller->in_other_partition
+         || !lto_symtab_encoder_in_partition_p (encoder, e->caller))
+       return true;
+    }
   return false;
 }
 
@@ -818,6 +830,16 @@ create_references (lto_symtab_encoder_t encoder, symtab_node *node)
       lto_symtab_encoder_encode (encoder, ref->referred);
 }
 
+/* Select what needs to be streamed out.  In regular lto mode stream everything.
+   In offload lto mode stream only nodes marked as offloadable.  */
+void
+select_what_to_stream (bool offload_lto_mode)
+{
+  struct symtab_node *snode;
+  FOR_EACH_SYMBOL (snode)
+    snode->need_lto_streaming = !offload_lto_mode || snode->offloadable;
+}
+
 /* Find all symbols we want to stream into given partition and insert them
    to encoders.
 
@@ -844,6 +866,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
        !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei))
     {
       struct cgraph_node *node = lsei_cgraph_node (lsei);
+      if (!node->need_lto_streaming)
+       continue;
       add_node_to (encoder, node, true);
       lto_set_symtab_encoder_in_partition (encoder, node);
       create_references (encoder, node);
@@ -860,6 +884,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
     {
       varpool_node *vnode = lsei_varpool_node (lsei);
 
+      if (!vnode->need_lto_streaming)
+       continue;
       lto_set_symtab_encoder_in_partition (encoder, vnode);
       lto_set_symtab_encoder_encode_initializer (encoder, vnode);
       create_references (encoder, vnode);
index cb7523098729ed6b8697e6fbcb58694f7ec44c45..f5dbed26bad5d52471b4e41ae87204478ffbdcd1 100644 (file)
@@ -25,6 +25,11 @@ along with GCC; see the file COPYING3.  If not see
    name for the functions and static_initializers.  For other types of
    sections a '.' and the section type are appended.  */
 #define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
+#define OFFLOAD_SECTION_NAME_PREFIX ".gnu.offload_lto_"
+
+/* Can be either OFFLOAD_SECTION_NAME_PREFIX when we stream IR for offload
+   compiler, or LTO_SECTION_NAME_PREFIX for LTO case.  */
+extern const char *section_name_prefix;
 
 /* Segment name for LTO sections.  This is only used for Mach-O.  */
 
index b6cac0b5e9976acb74489d54190912566538f6b6..e8347dccd654de020c0a135a3ea5c94997519d92 100644 (file)
@@ -60,6 +60,7 @@ struct lto_stats_d lto_stats;
 static bitmap_obstack lto_obstack;
 static bool lto_obstack_initialized;
 
+const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
 
 /* Return a string representing LTO tag TAG.  */
 
@@ -189,7 +190,7 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d
     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
   else
     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false)); 
-  return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
+  return concat (section_name_prefix, sep, add, post, NULL);
 }
 
 
index 4b875a2b8ba0faf385d84b4ffe9ce1ac628cd96b..cdbe507d7189e8a8a2fb4969d86a5134d5bb09a0 100644 (file)
@@ -831,6 +831,7 @@ bool referenced_from_this_partition_p (symtab_node *,
 bool reachable_from_this_partition_p (struct cgraph_node *,
                                      lto_symtab_encoder_t);
 lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
+void select_what_to_stream (bool);
 
 
 /* In lto-symtab.c.  */
index cbd1af51f14255482370c808e1ac59e7e7ab9f87..1b2f1fe1514ac78c8f8f438a6170ad2f0424225d 100644 (file)
@@ -1,3 +1,17 @@
+2014-11-13  Ilya Verbin  <ilya.verbin@intel.com>
+           Bernd Schmidt  <bernds@codesourcery.com>
+           Andrey Turetskiy  <andrey.turetskiy@intel.com>
+           Michael Zolotukhin  <michael.v.zolotukhin@intel.com>
+
+       * lto-object.c (lto_obj_add_section): Use section_name_prefix instead of
+       LTO_SECTION_NAME_PREFIX.
+       * lto-partition.c (lto_promote_cross_file_statics): Call
+       select_what_to_stream.
+       * lto.c (lto_section_with_id): Use section_name_prefix instead of
+       LTO_SECTION_NAME_PREFIX.
+       (read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if
+       being built as an offload compiler.
+
 2014-10-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * lto-lang.c: Remove redundant enum from machine_mode.
index 1178326b99199f4588ed2e1e3de82b4c5e75d8bb..b4124f65b97c49ee3b3d12aef695ae4944c12ed7 100644 (file)
@@ -242,8 +242,7 @@ lto_obj_add_section (void *data, const char *name, off_t offset,
   void **slot;
   struct lto_section_list *list = loasd->list;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-              strlen (LTO_SECTION_NAME_PREFIX)) != 0)
+  if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
     return 1;
 
   new_name = xstrdup (name);
index 0e1a95bf9188592a4ec2323c7d7fee90173c3e30..65f0582cf6b2df04bf0de204ff1b7cdc5700d0ab 100644 (file)
@@ -952,6 +952,8 @@ lto_promote_cross_file_statics (void)
 
   gcc_assert (flag_wpa);
 
+  select_what_to_stream (false);
+
   /* First compute boundaries.  */
   n_sets = ltrans_partitions.length ();
   for (i = 0; i < n_sets; i++)
index d8519d9426b1a4418eeeadae83e960c043332fdb..fbf4913875d103f3a81c0d996a933197fb0b7f69 100644 (file)
@@ -2137,7 +2137,7 @@ lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id)
 {
   const char *s;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX, strlen (LTO_SECTION_NAME_PREFIX)))
+  if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
     return 0;
   s = strrchr (name, '.');
   return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
@@ -2912,6 +2912,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
 
   timevar_push (TV_IPA_LTO_DECL_IN);
 
+#ifdef ACCEL_COMPILER
+    section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
+#endif
+
   real_file_decl_data
     = decl_data = ggc_cleared_vec_alloc<lto_file_decl_data_ptr> (nfiles + 1);
   real_file_count = nfiles;
index e7d8a7e916e6e408a237097a019269b98b4061ab..8ac5d94bcd1810dce35661b5faa64b8d9b7f1871 100644 (file)
@@ -86,6 +86,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-nested.h"
 #include "tree-eh.h"
 #include "cilk.h"
+#include "context.h"
 
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -273,6 +274,16 @@ is_parallel_ctx (omp_context *ctx)
 }
 
 
+/* Return true if CTX is for an omp target region.  */
+
+static inline bool
+is_targetreg_ctx (omp_context *ctx)
+{
+  return gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
+        && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION;
+}
+
+
 /* Return true if CTX is for an omp task.  */
 
 static inline bool
@@ -1642,8 +1653,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
          if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
              && DECL_P (decl)
              && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
-             && lookup_attribute ("omp declare target",
-                                  DECL_ATTRIBUTES (decl)))
+             && varpool_node::get_create (decl)->offloadable)
            break;
          if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
              && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
@@ -1783,8 +1793,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
          decl = OMP_CLAUSE_DECL (c);
          if (DECL_P (decl)
              && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
-             && lookup_attribute ("omp declare target",
-                                  DECL_ATTRIBUTES (decl)))
+             && varpool_node::get_create (decl)->offloadable)
            break;
          if (DECL_P (decl))
            {
@@ -1938,26 +1947,19 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
   DECL_EXTERNAL (decl) = 0;
   DECL_CONTEXT (decl) = NULL_TREE;
   DECL_INITIAL (decl) = make_node (BLOCK);
-  bool target_p = false;
-  if (lookup_attribute ("omp declare target",
-                       DECL_ATTRIBUTES (current_function_decl)))
-    target_p = true;
+  if (cgraph_node::get (current_function_decl)->offloadable)
+    cgraph_node::get_create (decl)->offloadable = 1;
   else
     {
       omp_context *octx;
       for (octx = ctx; octx; octx = octx->outer)
-       if (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
-           && gimple_omp_target_kind (octx->stmt)
-              == GF_OMP_TARGET_KIND_REGION)
+       if (is_targetreg_ctx (octx))
          {
-           target_p = true;
+           cgraph_node::get_create (decl)->offloadable = 1;
+           g->have_offload = true;
            break;
          }
     }
-  if (target_p)
-    DECL_ATTRIBUTES (decl)
-      = tree_cons (get_identifier ("omp declare target"),
-                  NULL_TREE, DECL_ATTRIBUTES (decl));
 
   t = build_decl (DECL_SOURCE_LOCATION (decl),
                  RESULT_DECL, NULL_TREE, void_type_node);
@@ -2663,8 +2665,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
       break;
     case GIMPLE_OMP_TARGET:
       for (; ctx != NULL; ctx = ctx->outer)
-       if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
-           && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
+       if (is_targetreg_ctx (ctx))
          {
            const char *name;
            switch (gimple_omp_target_kind (stmt))
@@ -8281,6 +8282,7 @@ expand_omp_target (struct omp_region *region)
   if (kind == GF_OMP_TARGET_KIND_REGION)
     {
       unsigned srcidx, dstidx, num;
+      struct cgraph_node *node;
 
       /* If the target region needs data sent from the parent
         function, then the very first statement (except possible
@@ -8412,6 +8414,11 @@ expand_omp_target (struct omp_region *region)
       push_cfun (child_cfun);
       cgraph_edge::rebuild_edges ();
 
+      /* Prevent IPA from removing child_fn as unreachable, since there are no
+        refs from the parent function to child_fn in offload LTO mode.  */
+      node = cgraph_node::get (child_fn);
+      node->mark_force_output ();
+
       /* Some EH regions might become dead, see PR34608.  If
         pass_cleanup_cfg isn't the first pass to happen with the
         new child, these dead EH edges might cause problems.
@@ -9326,6 +9333,17 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
          DECL_COMMON (decl) = 1;
          DECL_ARTIFICIAL (decl) = 1;
          DECL_IGNORED_P (decl) = 1;
+
+         /* If '#pragma omp critical' is inside target region, the symbol must
+            be marked for offloading.  */
+         omp_context *octx;
+         for (octx = ctx->outer; octx; octx = octx->outer)
+           if (is_targetreg_ctx (octx))
+             {
+               varpool_node::get_create (decl)->offloadable = 1;
+               break;
+             }
+
          varpool_node::finalize_decl (decl);
 
          splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
index 5e91a79414ab73010dab4eeac7ee36f6bced84b4..aa40fe5fa30caa18c25ab7d6c199aa8be327b9ee 100644 (file)
@@ -2416,7 +2416,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
 /* Write out summaries for all the nodes in the callgraph.  */
 
 void
-ipa_write_summaries (void)
+ipa_write_summaries (bool offload_lto_mode)
 {
   lto_symtab_encoder_t encoder;
   int i, order_pos;
@@ -2427,6 +2427,8 @@ ipa_write_summaries (void)
   if (!flag_generate_lto || seen_error ())
     return;
 
+  select_what_to_stream (offload_lto_mode);
+
   encoder = lto_symtab_encoder_new (false);
 
   /* Create the callgraph set in the same order used in
@@ -2453,15 +2455,16 @@ ipa_write_summaries (void)
          renumber_gimple_stmt_uids ();
          pop_cfun ();
        }
-      if (node->definition)
+      if (node->definition && node->need_lto_streaming)
         lto_set_symtab_encoder_in_partition (encoder, node);
     }
 
   FOR_EACH_DEFINED_FUNCTION (node)
-    if (node->alias)
+    if (node->alias && node->need_lto_streaming)
       lto_set_symtab_encoder_in_partition (encoder, node);
   FOR_EACH_DEFINED_VARIABLE (vnode)
-    lto_set_symtab_encoder_in_partition (encoder, vnode);
+    if (vnode->need_lto_streaming)
+      lto_set_symtab_encoder_in_partition (encoder, vnode);
 
   ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
 
index 25ff364a1ad159523c136a755c1759654af62c60..b8f2801e198e0c9538f62269e38f89708dc1be79 100644 (file)
@@ -602,7 +602,7 @@ extern void pass_fini_dump_file (opt_pass *);
 extern const char *get_current_pass_name (void);
 extern void print_current_pass (FILE *);
 extern void debug_pass (void);
-extern void ipa_write_summaries (void);
+extern void ipa_write_summaries (bool);
 extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *);
 extern void ipa_read_summaries (void);
 extern void ipa_read_optimization_summaries (void);
index ac7abc1be86b10491844a6b4cfa4cb23ed8738eb..ee889f2db53f13e4edc6d57f101b2998a801091a 100644 (file)
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-alias.h"
 #include "gimple.h"
 #include "lto-streamer.h"
+#include "context.h"
 
 const char * const tls_model_names[]={"none", "tls-emulated", "tls-real",
                                      "tls-global-dynamic", "tls-local-dynamic",
@@ -164,6 +165,14 @@ varpool_node::get_create (tree decl)
 
   node = varpool_node::create_empty ();
   node->decl = decl;
+
+  if (flag_openmp
+      && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
+    {
+      node->offloadable = 1;
+      g->have_offload = true;
+    }
+
   node->register_symbol ();
   return node;
 }