Add param parloops-schedule
2015-09-10 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/67476
* doc/invoke.texi (@item parloops-schedule): New item.
* omp-low.c (expand_omp_for_generic): Handle simple latch. Add missing
phis. Handle original loop.
* params.def (PARAM_PARLOOPS_SCHEDULE): New DEFPARAMENUM.
* tree-parloops.c (create_parallel_loop): Handle
PARAM_PARLOOPS_SCHEDULE.
* testsuite/libgomp.c/autopar-3.c: New test.
* testsuite/libgomp.c/autopar-4.c: New test.
* testsuite/libgomp.c/autopar-5.c: New test.
* testsuite/libgomp.c/autopar-6.c: New test.
* testsuite/libgomp.c/autopar-7.c: New test.
* testsuite/libgomp.c/autopar-8.c: New test.
---
gcc/doc/invoke.texi | 4 +++
gcc/omp-low.c | 57 +++++++++++++++++++++++++++++++--
gcc/params.def | 6 ++++
gcc/tree-parloops.c | 24 +++++++++++++-
libgomp/testsuite/libgomp.c/autopar-3.c | 4 +++
libgomp/testsuite/libgomp.c/autopar-4.c | 4 +++
libgomp/testsuite/libgomp.c/autopar-5.c | 4 +++
libgomp/testsuite/libgomp.c/autopar-6.c | 4 +++
libgomp/testsuite/libgomp.c/autopar-7.c | 4 +++
libgomp/testsuite/libgomp.c/autopar-8.c | 4 +++
10 files changed, 111 insertions(+), 4 deletions(-)
create mode 100644 libgomp/testsuite/libgomp.c/autopar-3.c
create mode 100644 libgomp/testsuite/libgomp.c/autopar-4.c
create mode 100644 libgomp/testsuite/libgomp.c/autopar-5.c
create mode 100644 libgomp/testsuite/libgomp.c/autopar-6.c
create mode 100644 libgomp/testsuite/libgomp.c/autopar-7.c
create mode 100644 libgomp/testsuite/libgomp.c/autopar-8.c
@@ -11005,6 +11005,10 @@ automaton. The default is 50.
Chunk size of omp schedule for loops parallelized by parloops. The default
is 0.
+@item parloops-schedule
+Schedule type of omp schedule for loops parallelized by parloops (static,
+dynamic, guided, auto, runtime). The default is static.
+
@end table
@end table
@@ -239,6 +239,7 @@ static vec<omp_context *> taskreg_contexts;
static void scan_omp (gimple_seq *, omp_context *);
static tree scan_omp_1_op (tree *, int *, void *);
+static gphi *find_phi_with_arg_on_edge (tree, edge);
#define WALK_SUBSTMTS \
case GIMPLE_BIND: \
@@ -6155,7 +6156,9 @@ expand_omp_for_generic (struct omp_region *region,
if (!broken_loop)
{
l2_bb = create_empty_bb (cont_bb);
- gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
+ gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb
+ || (single_succ_edge (BRANCH_EDGE (cont_bb)->dest)->dest
+ == l1_bb));
gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
}
else
@@ -6429,8 +6432,12 @@ expand_omp_for_generic (struct omp_region *region,
remove_edge (e);
make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
- add_bb_to_loop (l2_bb, cont_bb->loop_father);
e = find_edge (cont_bb, l1_bb);
+ if (e == NULL)
+ {
+ e = BRANCH_EDGE (cont_bb);
+ gcc_assert (single_succ (e->dest) == l1_bb);
+ }
if (gimple_omp_for_combined_p (fd->for_stmt))
{
remove_edge (e);
@@ -6454,7 +6461,45 @@ expand_omp_for_generic (struct omp_region *region,
e->flags = EDGE_FALLTHRU;
}
make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
+ }
+
+
+ if (gimple_in_ssa_p (cfun))
+ {
+ gphi_iterator psi;
+
+ for (psi = gsi_start_phis (l3_bb); !gsi_end_p (psi); gsi_next (&psi))
+ {
+ source_location locus;
+ gphi *nphi;
+ gphi *exit_phi = psi.phi ();
+
+ edge l2_to_l3 = find_edge (l2_bb, l3_bb);
+ tree exit_res = PHI_ARG_DEF_FROM_EDGE (exit_phi, l2_to_l3);
+ basic_block latch = BRANCH_EDGE (cont_bb)->dest;
+ edge latch_to_l1 = find_edge (latch, l1_bb);
+ gphi *inner_phi = find_phi_with_arg_on_edge (exit_res, latch_to_l1);
+
+ tree t = gimple_phi_result (exit_phi);
+ tree new_res = copy_ssa_name (t, NULL);
+ nphi = create_phi_node (new_res, l0_bb);
+
+ edge l0_to_l1 = find_edge (l0_bb, l1_bb);
+ t = PHI_ARG_DEF_FROM_EDGE (inner_phi, l0_to_l1);
+ locus = gimple_phi_arg_location_from_edge (inner_phi, l0_to_l1);
+ edge entry_to_l0 = find_edge (entry_bb, l0_bb);
+ add_phi_arg (nphi, t, entry_to_l0, locus);
+
+ edge l2_to_l0 = find_edge (l2_bb, l0_bb);
+ add_phi_arg (nphi, exit_res, l2_to_l0, UNKNOWN_LOCATION);
+
+ add_phi_arg (inner_phi, new_res, l0_to_l1, UNKNOWN_LOCATION);
+ };
+ }
+
+ if (!broken_loop)
+ {
set_immediate_dominator (CDI_DOMINATORS, l2_bb,
recompute_dominator (CDI_DOMINATORS, l2_bb));
set_immediate_dominator (CDI_DOMINATORS, l3_bb,
@@ -6464,14 +6509,20 @@ expand_omp_for_generic (struct omp_region *region,
set_immediate_dominator (CDI_DOMINATORS, l1_bb,
recompute_dominator (CDI_DOMINATORS, l1_bb));
+ struct loop *loop = l1_bb->loop_father;
+ add_bb_to_loop (l2_bb, entry_bb->loop_father);
+
struct loop *outer_loop = alloc_loop ();
outer_loop->header = l0_bb;
outer_loop->latch = l2_bb;
add_loop (outer_loop, l0_bb->loop_father);
+ if (loop != entry_bb->loop_father)
+ return;
+
if (!gimple_omp_for_combined_p (fd->for_stmt))
{
- struct loop *loop = alloc_loop ();
+ loop = alloc_loop ();
loop->header = l1_bb;
/* The loop may have multiple latches. */
add_loop (loop, outer_loop);
@@ -1145,6 +1145,12 @@ DEFPARAM (PARAM_PARLOOPS_CHUNK_SIZE,
"parloops-chunk-size",
"Chunk size of omp schedule for loops parallelized by parloops",
0, 0, 0)
+
+DEFPARAMENUM (PARAM_PARLOOPS_SCHEDULE,
+ "parloops-schedule",
+ "Schedule type of omp schedule for loops parallelized by "
+ "parloops (static, dynamic, guided, auto, runtime)",
+ 0, 0, 4, "static", "dynamic", "guided", "auto", "runtime")
/*
Local variables:
@@ -2092,8 +2092,30 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
gimple_cond_set_lhs (cond_stmt, cvar_base);
type = TREE_TYPE (cvar);
t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
- OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
int chunk_size = PARAM_VALUE (PARAM_PARLOOPS_CHUNK_SIZE);
+ int schedule_type = PARAM_VALUE (PARAM_PARLOOPS_SCHEDULE);
+ switch (schedule_type)
+ {
+ case 0:
+ OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
+ break;
+ case 1:
+ OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
+ break;
+ case 2:
+ OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_GUIDED;
+ break;
+ case 3:
+ OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_AUTO;
+ chunk_size = 0;
+ break;
+ case 4:
+ OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_RUNTIME;
+ chunk_size = 0;
+ break;
+ default:
+ gcc_unreachable ();
+ }
if (chunk_size != 0)
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t)
= build_int_cst (integer_type_node, chunk_size);
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=dynamic" } */
+
+#include "autopar-1.c"
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=dynamic --param parloops-chunk-size=100" } */
+
+#include "autopar-1.c"
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=guided" } */
+
+#include "autopar-1.c"
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=guided --param parloops-chunk-size=100" } */
+
+#include "autopar-1.c"
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=auto" } */
+
+#include "autopar-1.c"
new file mode 100644
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-schedule=runtime" } */
+
+#include "autopar-1.c"
--
1.9.1