This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4.1] Small doacross fixes and improvements
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Aldy Hernandez <aldyh at redhat dot com>
- Date: Mon, 14 Sep 2015 16:20:26 +0200
- Subject: [gomp4.1] Small doacross fixes and improvements
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This patch makes sure that when we remove all depend clauses from a
construct (e.g. because all of them refer to invalid iterations), we don't
leave ordered construct without clauses in (because that means omp ordered
threads). Furthermore, it attempts to optimize adjacent #pragma omp ordered
depend(sink:...) directives. And makes sure we don't lower them to any
code, the goal is to do something about them only during expansion.
The patch also treats them as stand-alone directives for the construction
of omp regions and edges in the cfg (so we don't emit GIMPLE_OMP_RETURN
for those).
2015-09-14 Jakub Jelinek <jakub@redhat.com>
* omp-low.c (lower_omp_ordered_clauses): Add GSI_P argument.
Use XALLOCAVEC, don't check for gimple_omp_for_collapse 0.
Merge adjacent ordered depend(sink:) statements. If removing
all depend clauses, replace also the ordered stmt with GIMPLE_NOP.
(lower_omp_ordered): Call lower_omp_ordered_clauses only if depend
clause is present. Don't do anything else after that call.
(build_omp_regions_1): Treat GIMPLE_OMP_ORDERED with depend clause
as stand-alone directive.
(make_gimple_omp_edges): Likewise.
--- gcc/omp-low.c.jj 2015-09-10 14:46:48.000000000 +0200
+++ gcc/omp-low.c 2015-09-14 15:00:15.713086562 +0200
@@ -11185,6 +11185,13 @@ build_omp_regions_1 (basic_block bb, str
gcc_unreachable ();
}
}
+ else if (code == GIMPLE_OMP_ORDERED
+ && find_omp_clause (gimple_omp_ordered_clauses
+ (as_a <gomp_ordered *> (stmt)),
+ OMP_CLAUSE_DEPEND))
+ /* #pragma omp ordered depend is also just a stand-alone
+ directive. */
+ region = NULL;
/* ..., this directive becomes the parent for a new region. */
if (region)
parent = region;
@@ -12110,22 +12117,54 @@ lower_omp_taskgroup (gimple_stmt_iterato
/* Fold the OMP_ORDERED_CLAUSES for the OMP_ORDERED in STMT if possible. */
static void
-lower_omp_ordered_clauses (gomp_ordered *ord_stmt, omp_context *ctx)
+lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
+ omp_context *ctx)
{
struct omp_for_data fd;
if (!ctx->outer || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR)
return;
unsigned int len = gimple_omp_for_collapse (ctx->outer->stmt);
- if (!len)
- return;
- struct omp_for_data_loop *loops
- = (struct omp_for_data_loop *)
- alloca (len * sizeof (struct omp_for_data_loop));
+ struct omp_for_data_loop *loops = XALLOCAVEC (struct omp_for_data_loop, len);
extract_omp_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, loops);
if (!fd.ordered)
return;
+ tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
+ tree c = gimple_omp_ordered_clauses (ord_stmt);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
+ && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+ {
+ /* Merge depend clauses from multiple adjacent
+ #pragma omp ordered depend(sink:...) constructs
+ into one #pragma omp ordered depend(sink:...), so that
+ we can optimize them together. */
+ gimple_stmt_iterator gsi = *gsi_p;
+ gsi_next (&gsi);
+ while (!gsi_end_p (gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (is_gimple_debug (stmt)
+ || gimple_code (stmt) == GIMPLE_NOP)
+ {
+ gsi_next (&gsi);
+ continue;
+ }
+ if (gimple_code (stmt) != GIMPLE_OMP_ORDERED)
+ break;
+ gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
+ c = gimple_omp_ordered_clauses (ord_stmt2);
+ if (c == NULL_TREE
+ || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
+ || OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
+ break;
+ while (*list_p)
+ list_p = &OMP_CLAUSE_CHAIN (*list_p);
+ *list_p = c;
+ gsi_remove (&gsi, true);
+ }
+ }
+
/* Canonicalize sink dependence clauses into one folded clause if
possible.
@@ -12183,8 +12222,7 @@ lower_omp_ordered_clauses (gomp_ordered
tree *iter_vars = (tree *) alloca (sizeof (tree) * len);
memset (iter_vars, 0, sizeof (tree) * len);
- tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
- tree c;
+ list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
unsigned int i;
while ((c = *list_p) != NULL)
{
@@ -12317,6 +12355,11 @@ lower_omp_ordered_clauses (gomp_ordered
lower_omp_ordered_ret:
sbitmap_free (folded_deps_used);
folded_deps.release ();
+
+ /* Ordered without clauses is #pragma omp threads, while we want
+ a nop instead if we remove all clauses. */
+ if (gimple_omp_ordered_clauses (ord_stmt) == NULL_TREE)
+ gsi_replace (gsi_p, gimple_build_nop (), true);
}
@@ -12333,7 +12376,12 @@ lower_omp_ordered (gimple_stmt_iterator
bool simd
= find_omp_clause (gimple_omp_ordered_clauses (ord_stmt), OMP_CLAUSE_SIMD);
- lower_omp_ordered_clauses (ord_stmt, ctx);
+ if (find_omp_clause (gimple_omp_ordered_clauses (ord_stmt),
+ OMP_CLAUSE_DEPEND))
+ {
+ lower_omp_ordered_clauses (gsi_p, ord_stmt, ctx);
+ return;
+ }
push_gimplify_context ();
@@ -14979,13 +15027,21 @@ make_gimple_omp_edges (basic_block bb, s
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
- case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_SECTION:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
break;
+ case GIMPLE_OMP_ORDERED:
+ cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ if (find_omp_clause (gimple_omp_ordered_clauses
+ (as_a <gomp_ordered *> (last)),
+ OMP_CLAUSE_DEPEND))
+ cur_region = cur_region->outer;
+ break;
+
case GIMPLE_OMP_TARGET:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
Jakub