aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-22 08:04:41 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-22 08:04:41 +0000
commit44f5e867ee71240a6976210a16053cbb0f1c4445 (patch)
treebc147e1c9012ff0f57644c717fec7e432a8b446f
parentf51093772d48bb0a9166bd9400cc178b67844dc0 (diff)
Backported from mainline
2015-05-13 Jakub Jelinek <jakub@redhat.com> PR middle-end/66133 * omp-low.c (expand_omp_taskreg): For GIMPLE_OMP_TASK expansion, make sure it is never noreturn, even when the task body does not return. (lower_omp_taskreg): For GIMPLE_OMP_TASK, emit GIMPLE_OMP_CONTINUE right before GIMPLE_OMP_RETURN. (make_gimple_omp_edges): Accept GIMPLE_OMP_CONTINUE as ->cont for GIMPLE_OMP_TASK. For GIMPLE_OMP_RETURN corresponding to GIMPLE_OMP_TASK add an EDGE_ABNORMAL edge from entry to exit. * testsuite/libgomp.c/pr66133.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-5-branch@223520 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/omp-low.c49
-rw-r--r--libgomp/ChangeLog8
-rw-r--r--libgomp/testsuite/libgomp.c/pr66133.c35
4 files changed, 102 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 679238b0ac5..9f2910eecef 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2015-05-22 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2015-05-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/66133
+ * omp-low.c (expand_omp_taskreg): For GIMPLE_OMP_TASK expansion,
+ make sure it is never noreturn, even when the task body does not
+ return.
+ (lower_omp_taskreg): For GIMPLE_OMP_TASK, emit GIMPLE_OMP_CONTINUE
+ right before GIMPLE_OMP_RETURN.
+ (make_gimple_omp_edges): Accept GIMPLE_OMP_CONTINUE as ->cont
+ for GIMPLE_OMP_TASK. For GIMPLE_OMP_RETURN corresponding to
+ GIMPLE_OMP_TASK add an EDGE_ABNORMAL edge from entry to exit.
+
2015-05-21 Sandra Loosemore <sandra@codesourcery.com>
Backport from mainline r223418:
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 835ff71391f..afce8079ee7 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5377,7 +5377,10 @@ expand_omp_taskreg (struct omp_region *region)
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
entry_bb = region->entry;
- exit_bb = region->exit;
+ if (gimple_code (entry_stmt) == GIMPLE_OMP_TASK)
+ exit_bb = region->cont;
+ else
+ exit_bb = region->exit;
bool is_cilk_for
= (flag_cilkplus
@@ -5436,7 +5439,9 @@ expand_omp_taskreg (struct omp_region *region)
variable. In which case, we need to keep the assignment. */
if (gimple_omp_taskreg_data_arg (entry_stmt))
{
- basic_block entry_succ_bb = single_succ (entry_bb);
+ basic_block entry_succ_bb
+ = single_succ_p (entry_bb) ? single_succ (entry_bb)
+ : FALLTHRU_EDGE (entry_bb)->dest;
tree arg, narg;
gimple parcopy_stmt = NULL;
@@ -5524,14 +5529,28 @@ expand_omp_taskreg (struct omp_region *region)
e = split_block (entry_bb, stmt);
gsi_remove (&gsi, true);
entry_bb = e->dest;
- single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+ edge e2 = NULL;
+ if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
+ single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+ else
+ {
+ e2 = make_edge (e->src, BRANCH_EDGE (entry_bb)->dest, EDGE_ABNORMAL);
+ gcc_assert (e2->dest == region->exit);
+ remove_edge (BRANCH_EDGE (entry_bb));
+ set_immediate_dominator (CDI_DOMINATORS, e2->dest, e->src);
+ gsi = gsi_last_bb (region->exit);
+ gcc_assert (!gsi_end_p (gsi)
+ && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+ gsi_remove (&gsi, true);
+ }
- /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
+ /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR. */
if (exit_bb)
{
gsi = gsi_last_bb (exit_bb);
gcc_assert (!gsi_end_p (gsi)
- && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+ && (gimple_code (gsi_stmt (gsi))
+ == (e2 ? GIMPLE_OMP_CONTINUE : GIMPLE_OMP_RETURN)));
stmt = gimple_build_return (NULL);
gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
gsi_remove (&gsi, true);
@@ -5552,6 +5571,14 @@ expand_omp_taskreg (struct omp_region *region)
new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
if (exit_bb)
single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
+ if (e2)
+ {
+ basic_block dest_bb = e2->dest;
+ if (!exit_bb)
+ make_edge (new_bb, dest_bb, EDGE_FALLTHRU);
+ remove_edge (e2);
+ set_immediate_dominator (CDI_DOMINATORS, dest_bb, new_bb);
+ }
/* When the OMP expansion process cannot guarantee an up-to-date
loop tree arrange for the child function to fixup loops. */
if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
@@ -11158,6 +11185,10 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
gimple_seq_add_seq (&new_body, par_olist);
new_body = maybe_catch_exception (new_body);
+ if (gimple_code (stmt) == GIMPLE_OMP_TASK)
+ gimple_seq_add_stmt (&new_body,
+ gimple_build_omp_continue (integer_zero_node,
+ integer_zero_node));
gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
gimple_omp_set_body (stmt, new_body);
@@ -12272,6 +12303,10 @@ make_gimple_omp_edges (basic_block bb, struct omp_region **region,
somewhere other than the next block. This will be
created later. */
cur_region->exit = bb;
+ if (cur_region->type == GIMPLE_OMP_TASK)
+ /* Add an edge corresponding to not scheduling the task
+ immediately. */
+ make_edge (cur_region->entry, bb, EDGE_ABNORMAL);
fallthru = cur_region->type != GIMPLE_OMP_SECTION;
cur_region = cur_region->outer;
break;
@@ -12320,6 +12355,10 @@ make_gimple_omp_edges (basic_block bb, struct omp_region **region,
}
break;
+ case GIMPLE_OMP_TASK:
+ fallthru = true;
+ break;
+
default:
gcc_unreachable ();
}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 88ca4ded0e5..f498aabc972 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,11 @@
+2015-05-22 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2015-05-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/66133
+ * testsuite/libgomp.c/pr66133.c: New test.
+
2015-04-22 Release Manager
* GCC 5.1.0 released.
diff --git a/libgomp/testsuite/libgomp.c/pr66133.c b/libgomp/testsuite/libgomp.c/pr66133.c
new file mode 100644
index 00000000000..e98e5aac412
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr66133.c
@@ -0,0 +1,35 @@
+/* PR middle-end/66133 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+volatile int x;
+
+__attribute__((noinline)) void
+foo (void)
+{
+ if (x == 0)
+ {
+ #pragma omp task
+ {
+ usleep (2000);
+ exit (0);
+ }
+ }
+ else
+ abort ();
+}
+
+int
+main ()
+{
+ #pragma omp parallel num_threads (2)
+ {
+ #pragma omp barrier
+ #pragma omp single
+ foo ();
+ }
+ exit (0);
+}