aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-low.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-06-22 20:39:25 +0000
committerJakub Jelinek <jakub@redhat.com>2011-06-22 20:39:25 +0000
commit265793d69dcc0ccd68b4778f501e4a227164f3de (patch)
treec2cc34ab7a462c76b41fcd457b365ba285e84685 /gcc/omp-low.c
parent158e95f908e85506259732363c26d3c4dbac4f12 (diff)
PR libgomp/49490
* omp-low.c (expand_omp_for_static_nochunk): Only use n ceil/ nthreads size for the first n % nthreads threads in the team instead of all threads except for the last few ones which get less work or none at all. * iter.c (gomp_iter_static_next): For chunk size 0 only use n ceil/ nthreads size for the first n % nthreads threads in the team instead of all threads except for the last few ones which get less work or none at all. * iter_ull.c (gomp_iter_ull_static_next): Likewise. * env.c (parse_schedule): If OMP_SCHEDULE doesn't have chunk argument, set run_sched_modifier to 0 for static resp. 1 for other kinds. If chunk argument is 0 and not static, set value to 1. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@175315 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r--gcc/omp-low.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 944a40bce97..05646bf8833 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3,7 +3,7 @@
marshalling to implement data sharing and copying clauses.
Contributed by Diego Novillo <dnovillo@redhat.com>
- Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
@@ -4108,9 +4108,14 @@ expand_omp_for_generic (struct omp_region *region,
else
n = (adj + N2 - N1) / STEP;
q = n / nthreads;
- q += (q * nthreads != n);
- s0 = q * threadid;
- e0 = min(s0 + q, n);
+ tt = n % nthreads;
+ if (threadid < tt) goto L3; else goto L4;
+ L3:
+ tt = 0;
+ q = q + 1;
+ L4:
+ s0 = q * threadid + tt;
+ e0 = s0 + q;
V = s0 * STEP + N1;
if (s0 >= e0) goto L2; else goto L0;
L0:
@@ -4126,12 +4131,14 @@ static void
expand_omp_for_static_nochunk (struct omp_region *region,
struct omp_for_data *fd)
{
- tree n, q, s0, e0, e, t, nthreads, threadid;
+ tree n, q, s0, e0, e, t, tt, nthreads, threadid;
tree type, itype, vmain, vback;
- basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
+ basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
+ basic_block body_bb, cont_bb;
basic_block fin_bb;
gimple_stmt_iterator gsi;
gimple stmt;
+ edge ep;
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
@@ -4185,19 +4192,39 @@ expand_omp_for_static_nochunk (struct omp_region *region,
t = fold_convert (itype, t);
n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
+ q = create_tmp_var (itype, "q");
t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
- q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
+
+ tt = create_tmp_var (itype, "tt");
+ t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
- t = fold_build2 (MULT_EXPR, itype, q, nthreads);
- t = fold_build2 (NE_EXPR, itype, t, n);
- t = fold_build2 (PLUS_EXPR, itype, q, t);
- q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
+ t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ second_bb = split_block (entry_bb, stmt)->dest;
+ gsi = gsi_last_bb (second_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
+
+ gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
+ GSI_SAME_STMT);
+ stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
+ build_int_cst (itype, 1));
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ third_bb = split_block (second_bb, stmt)->dest;
+ gsi = gsi_last_bb (third_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
t = build2 (MULT_EXPR, itype, q, threadid);
+ t = build2 (PLUS_EXPR, itype, t, tt);
s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = fold_build2 (PLUS_EXPR, itype, s0, q);
- t = fold_build2 (MIN_EXPR, itype, t, n);
e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = build2 (GE_EXPR, boolean_type_node, s0, e0);
@@ -4263,13 +4290,20 @@ expand_omp_for_static_nochunk (struct omp_region *region,
gsi_remove (&gsi, true);
/* Connect all the blocks. */
- find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
- find_edge (entry_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
+ ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
+ ep->probability = REG_BR_PROB_BASE / 4 * 3;
+ ep = find_edge (entry_bb, second_bb);
+ ep->flags = EDGE_TRUE_VALUE;
+ ep->probability = REG_BR_PROB_BASE / 4;
+ find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
+ find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
- set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
set_immediate_dominator (CDI_DOMINATORS, body_bb,
recompute_dominator (CDI_DOMINATORS, body_bb));
set_immediate_dominator (CDI_DOMINATORS, fin_bb,