public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/omp/gcc-12] openmp: Add support for streaming metadirectives and resolving them after LTO
@ 2022-06-29 14:43 Kwok Yeung
  0 siblings, 0 replies; only message in thread
From: Kwok Yeung @ 2022-06-29 14:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:568a9a64df46cc04266b6c0b584b9b90cd90d2bb

commit 568a9a64df46cc04266b6c0b584b9b90cd90d2bb
Author: Kwok Cheung Yeung <kcy@codesourcery.com>
Date:   Tue Jan 25 10:49:44 2022 -0800

    openmp: Add support for streaming metadirectives and resolving them after LTO
    
    This patch adds support for streaming metadirective Gimple statements during
    LTO, and adds a metadirective expansion pass that runs after LTO.  This is
    required for metadirectives with selectors that can only be resolved from
    within the accel compiler.
    
    2022-01-25  Kwok Cheung Yeung  <kcy@codesourcery.com>
    
            gcc/
            * Makefile.in (OBJS): Add omp-expand-metadirective.o.
            * gimple-streamer-in.cc (input_gimple_stmt): Add case for
            GIMPLE_OMP_METADIRECTIVE.  Handle metadirective labels.
            * gimple-streamer-out.cc (output_gimple_stmt): Likewise.
            * omp-expand-metadirective.cc: New.
            * passes.def: Add pass_omp_expand_metadirective.
            * tree-pass.h (make_pass_omp_expand_metadirective): New prototype.

Diff:
---
 gcc/ChangeLog.omp               |  10 +++
 gcc/Makefile.in                 |   1 +
 gcc/gimple-streamer-in.cc       |  10 +++
 gcc/gimple-streamer-out.cc      |   6 ++
 gcc/omp-expand-metadirective.cc | 191 ++++++++++++++++++++++++++++++++++++++++
 gcc/passes.def                  |   1 +
 gcc/tree-pass.h                 |   1 +
 7 files changed, 220 insertions(+)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 843aa6d922c..c0c38ff8fb8 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,13 @@
+2022-01-25  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+	* Makefile.in (OBJS): Add omp-expand-metadirective.o.
+	* gimple-streamer-in.cc (input_gimple_stmt): Add case for
+	GIMPLE_OMP_METADIRECTIVE.  Handle metadirective labels.
+	* gimple-streamer-out.cc (output_gimple_stmt): Likewise.
+	* omp-expand-metadirective.cc: New.
+	* passes.def: Add pass_omp_expand_metadirective.
+	* tree-pass.h (make_pass_omp_expand_metadirective): New prototype.
+
 2022-01-25  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
 	* gimplify.cc (expand_omp_metadirective): New.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ab581884ed3..3454e146546 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1521,6 +1521,7 @@ OBJS = \
 	omp-oacc-kernels-decompose.o \
 	omp-oacc-neuter-broadcast.o \
 	omp-simd-clone.o \
+	omp-expand-metadirective.o \
 	omp-data-optimize.o \
 	opt-problem.o \
 	optabs.o \
diff --git a/gcc/gimple-streamer-in.cc b/gcc/gimple-streamer-in.cc
index e7f3256302f..28a39eb0d52 100644
--- a/gcc/gimple-streamer-in.cc
+++ b/gcc/gimple-streamer-in.cc
@@ -151,6 +151,7 @@ input_gimple_stmt (class lto_input_block *ib, class data_in *data_in,
     case GIMPLE_COND:
     case GIMPLE_GOTO:
     case GIMPLE_DEBUG:
+    case GIMPLE_OMP_METADIRECTIVE:
       for (i = 0; i < num_ops; i++)
 	{
 	  tree *opp, op = stream_read_tree (ib, data_in);
@@ -188,6 +189,15 @@ input_gimple_stmt (class lto_input_block *ib, class data_in *data_in,
 	  else
 	    gimple_call_set_fntype (call_stmt, stream_read_tree (ib, data_in));
 	}
+      if (gomp_metadirective *metadirective_stmt
+	    = dyn_cast <gomp_metadirective*> (stmt))
+	{
+	  gimple_alloc_omp_metadirective (metadirective_stmt);
+	  for (i = 0; i < num_ops; i++)
+	    gimple_omp_metadirective_set_label (metadirective_stmt, i,
+						stream_read_tree (ib,
+								  data_in));
+	}
       break;
 
     case GIMPLE_NOP:
diff --git a/gcc/gimple-streamer-out.cc b/gcc/gimple-streamer-out.cc
index 33365251295..30d71e57c91 100644
--- a/gcc/gimple-streamer-out.cc
+++ b/gcc/gimple-streamer-out.cc
@@ -127,6 +127,7 @@ output_gimple_stmt (struct output_block *ob, struct function *fn, gimple *stmt)
     case GIMPLE_COND:
     case GIMPLE_GOTO:
     case GIMPLE_DEBUG:
+    case GIMPLE_OMP_METADIRECTIVE:
       for (i = 0; i < gimple_num_ops (stmt); i++)
 	{
 	  tree op = gimple_op (stmt, i);
@@ -169,6 +170,11 @@ output_gimple_stmt (struct output_block *ob, struct function *fn, gimple *stmt)
 	  else
 	    stream_write_tree (ob, gimple_call_fntype (stmt), true);
 	}
+      if (gimple_code (stmt) == GIMPLE_OMP_METADIRECTIVE)
+	for (i = 0; i < gimple_num_ops (stmt); i++)
+	  stream_write_tree (ob, gimple_omp_metadirective_label (stmt, i),
+			     true);
+
       break;
 
     case GIMPLE_NOP:
diff --git a/gcc/omp-expand-metadirective.cc b/gcc/omp-expand-metadirective.cc
new file mode 100644
index 00000000000..aaf048a699a
--- /dev/null
+++ b/gcc/omp-expand-metadirective.cc
@@ -0,0 +1,191 @@
+/* Expand an OpenMP metadirective.
+
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+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 "backend.h"
+#include "target.h"
+#include "tree.h"
+#include "langhooks.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "gomp-constants.h"
+#include "omp-general.h"
+#include "diagnostic-core.h"
+#include "tree-cfg.h"
+#include "cfganal.h"
+#include "ssa.h"
+#include "tree-into-ssa.h"
+#include "cfghooks.h"
+
+static void
+omp_expand_metadirective (function *fun, basic_block bb)
+{
+  gimple *stmt = last_stmt (bb);
+  vec<struct omp_metadirective_variant> candidates
+    = omp_resolve_metadirective (stmt);
+
+  /* This is the last chance for the metadirective to be resolved.  */
+  if (candidates.is_empty ())
+    gcc_unreachable ();
+
+  auto_vec<tree> labels;
+
+  for (unsigned int i = 0; i < candidates.length (); i++)
+    labels.safe_push (candidates[i].directive);
+
+  /* Delete BBs for all variants not in the candidate list.  */
+  for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
+    {
+      tree label = gimple_omp_metadirective_label (stmt, i);
+      if (!labels.contains (label))
+	{
+	  edge e = find_edge (bb, label_to_block (fun, label));
+	  remove_edge_and_dominated_blocks (e);
+	}
+    }
+
+  /* Remove the metadirective statement.  */
+  gimple_stmt_iterator gsi = gsi_last_bb (bb);
+  gsi_remove (&gsi, true);
+
+  if (candidates.length () == 1)
+    {
+      /* Special case if there is only one selector - there should be one
+	 remaining edge from BB to the selected variant.  */
+      edge e = find_edge (bb, label_to_block (fun,
+					      candidates.last ().directive));
+      e->flags |= EDGE_FALLTHRU;
+
+      return;
+    }
+
+  basic_block cur_bb = bb;
+
+  /* For each candidate, create a conditional that checks the dynamic
+     condition, branching to the candidate directive if true, to the
+     next candidate check if false.  */
+  for (unsigned i = 0; i < candidates.length () - 1; i++)
+    {
+      basic_block next_bb = NULL;
+      gcond *cond_stmt = gimple_build_cond_from_tree (candidates[i].selector,
+						      NULL_TREE, NULL_TREE);
+      gsi = gsi_last_bb (cur_bb);
+      gsi_insert_seq_after (&gsi, cond_stmt, GSI_NEW_STMT);
+
+      if (i < candidates.length () - 2)
+	{
+	  edge e_false = split_block (cur_bb, cond_stmt);
+	  e_false->flags &= ~EDGE_FALLTHRU;
+	  e_false->flags |= EDGE_FALSE_VALUE;
+	  e_false->probability = profile_probability::uninitialized ();
+
+	  next_bb = e_false->dest;
+	}
+
+      /* Redirect the source of the edge from BB to the candidate directive
+	 to the conditional.  Reusing the edge avoids disturbing phi nodes in
+	  the destination BB.  */
+      edge e = find_edge (bb, label_to_block (fun, candidates[i].directive));
+      redirect_edge_pred (e, cur_bb);
+      e->flags |= EDGE_TRUE_VALUE;
+
+      if (next_bb)
+	cur_bb = next_bb;
+    }
+
+  /* The last of the candidates is always static.  */
+  edge e = find_edge (cur_bb, label_to_block (fun,
+					      candidates.last ().directive));
+  e->flags |= EDGE_FALSE_VALUE;
+}
+
+namespace {
+
+const pass_data pass_data_omp_expand_metadirective =
+{
+  GIMPLE_PASS, /* type */
+  "omp_expand_metadirective", /* name */
+  OPTGROUP_OMP, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  PROP_gimple_lcf, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  TODO_update_ssa | TODO_cleanup_cfg, /* todo_flags_finish */
+};
+
+class pass_omp_expand_metadirective : public gimple_opt_pass
+{
+public:
+  pass_omp_expand_metadirective (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_omp_expand_metadirective, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *)
+  {
+    return (flag_openmp);
+  }
+
+  virtual unsigned int execute (function *fun);
+}; // class pass_omp_oacc_kernels_decompose
+
+unsigned int
+pass_omp_expand_metadirective::execute (function *fun)
+{
+  basic_block bb;
+  auto_vec<basic_block> metadirective_bbs;
+
+  FOR_EACH_BB_FN (bb, fun)
+    {
+      gimple *stmt = last_stmt (bb);
+      if (stmt && is_a<gomp_metadirective *> (stmt))
+	metadirective_bbs.safe_push (bb);
+    }
+
+  if (metadirective_bbs.is_empty ())
+    return 0;
+
+  calculate_dominance_info (CDI_DOMINATORS);
+
+  for (unsigned i = 0; i < metadirective_bbs.length (); i++)
+    omp_expand_metadirective (fun, metadirective_bbs[i]);
+
+  free_dominance_info (fun, CDI_DOMINATORS);
+  mark_virtual_operands_for_renaming (fun);
+
+  return 0;
+}
+
+} // anon namespace
+
+
+gimple_opt_pass *
+make_pass_omp_expand_metadirective (gcc::context *ctxt)
+{
+  return new pass_omp_expand_metadirective (ctxt);
+}
diff --git a/gcc/passes.def b/gcc/passes.def
index 3ab73cf2c73..66badeef652 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -188,6 +188,7 @@ along with GCC; see the file COPYING3.  If not see
   NEXT_PASS (pass_lower_eh_dispatch);
   NEXT_PASS (pass_omp_device_lower);
   NEXT_PASS (pass_omp_target_link);
+  NEXT_PASS (pass_omp_expand_metadirective);
   NEXT_PASS (pass_adjust_alignment);
   NEXT_PASS (pass_all_optimizations);
   PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations)
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 432d405e690..f0c0a122db5 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -422,6 +422,7 @@ extern gimple_opt_pass *make_pass_lower_switch_O0 (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_lower_vector (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_lower_vector_ssa (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_omp_oacc_kernels_decompose (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_omp_expand_metadirective (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_lower_omp (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_omp_data_optimize (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_diagnose_omp_blocks (gcc::context *ctxt);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-29 14:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-29 14:43 [gcc/devel/omp/gcc-12] openmp: Add support for streaming metadirectives and resolving them after LTO Kwok Yeung

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).