openmp: Fix up loop-21.c
I've missed +FAIL: libgomp.c/loop-21.c execution test during testing of the recent patch. The problem is that while for the number of iterations computation it doesn't matter if we compute min_inner_iterations as (m2 * first + n2 + (adjusted step) + m1 * first + n1) / step or (m2 * last + n2 + (adjusted step) + m1 * last + n1) / step provided that in the second case we use as factor (m1 - m2) * ostep / step rather than (m2 - m1) * ostep / step, for the logical to actual iterator values computation it does matter and in my hand written C implementations of all the cases (outer vs. inner loop with increasing vs. decreasing iterator) I'm using the same computation and it worked well for all the pseudo-random iterators testing it was doing. It also means min_inner_iterations is misnamed, because it is not really minimum number of inner iterations, whether the first or last outer iteration results in the smaller or larger value of this can be (sometimes) only determined at runtime. So this patch also renames it to first_inner_iterations. 2020-07-15 Jakub Jelinek <jakub@redhat.com> PR libgomp/96198 * omp-general.h (struct omp_for_data): Rename min_inner_iterations member to first_inner_iterations, adjust comment. * omp-general.c (omp_extract_for_data): Adjust for the above change. Always use n1first and n2first to compute it, rather than depending on single_nonrect_cond_code. Similarly, always compute factor as (m2 - m1) * outer_step / inner_step rather than sometimes m1 - m2 depending on single_nonrect_cond_code. * omp-expand.c (expand_omp_for_init_vars): Rename min_inner_iterations to first_inner_iterations and min_inner_iterationsd to first_inner_iterationsd.
This commit is contained in:
parent
765fbbf9bb
commit
79c12969ec
3 changed files with 23 additions and 38 deletions
|
@ -2264,7 +2264,7 @@ expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
|
|||
{
|
||||
tree outer_n1 = fd->adjn1 ? fd->adjn1 : fd->loops[i - 1].n1;
|
||||
tree itype = TREE_TYPE (fd->loops[i].v);
|
||||
tree min_inner_iterations = fd->min_inner_iterations;
|
||||
tree first_inner_iterations = fd->first_inner_iterations;
|
||||
tree factor = fd->factor;
|
||||
gcond *cond_stmt
|
||||
= gimple_build_cond (NE_EXPR, factor,
|
||||
|
@ -2282,21 +2282,21 @@ expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
|
|||
stopvalull
|
||||
= force_gimple_operand_gsi (gsi, stopvalull, true, NULL_TREE,
|
||||
false, GSI_CONTINUE_LINKING);
|
||||
min_inner_iterations
|
||||
= fold_convert (slltype, min_inner_iterations);
|
||||
min_inner_iterations
|
||||
= force_gimple_operand_gsi (gsi, min_inner_iterations, true,
|
||||
first_inner_iterations
|
||||
= fold_convert (slltype, first_inner_iterations);
|
||||
first_inner_iterations
|
||||
= force_gimple_operand_gsi (gsi, first_inner_iterations, true,
|
||||
NULL_TREE, false,
|
||||
GSI_CONTINUE_LINKING);
|
||||
factor = fold_convert (slltype, factor);
|
||||
factor
|
||||
= force_gimple_operand_gsi (gsi, factor, true, NULL_TREE,
|
||||
false, GSI_CONTINUE_LINKING);
|
||||
tree min_inner_iterationsd
|
||||
tree first_inner_iterationsd
|
||||
= fold_build1 (FLOAT_EXPR, double_type_node,
|
||||
min_inner_iterations);
|
||||
min_inner_iterationsd
|
||||
= force_gimple_operand_gsi (gsi, min_inner_iterationsd, true,
|
||||
first_inner_iterations);
|
||||
first_inner_iterationsd
|
||||
= force_gimple_operand_gsi (gsi, first_inner_iterationsd, true,
|
||||
NULL_TREE, false,
|
||||
GSI_CONTINUE_LINKING);
|
||||
tree factord = fold_build1 (FLOAT_EXPR, double_type_node,
|
||||
|
@ -2318,7 +2318,7 @@ expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
|
|||
t = fold_build2 (RDIV_EXPR, double_type_node, factord,
|
||||
build_real (double_type_node, dconst2));
|
||||
tree t3 = fold_build2 (MINUS_EXPR, double_type_node,
|
||||
min_inner_iterationsd, t);
|
||||
first_inner_iterationsd, t);
|
||||
t3 = force_gimple_operand_gsi (gsi, t3, true, NULL_TREE, false,
|
||||
GSI_CONTINUE_LINKING);
|
||||
t = fold_build2 (MULT_EXPR, double_type_node, factord,
|
||||
|
@ -2356,12 +2356,12 @@ expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
|
|||
t = fold_build2 (RSHIFT_EXPR, ulltype, t, integer_one_node);
|
||||
t = fold_build2 (MULT_EXPR, ulltype, fd->factor, t);
|
||||
tree t2 = fold_build2 (MULT_EXPR, ulltype, c,
|
||||
fd->min_inner_iterations);
|
||||
fd->first_inner_iterations);
|
||||
t = fold_build2 (PLUS_EXPR, ulltype, t, t2);
|
||||
expand_omp_build_assign (gsi, d, t, true);
|
||||
t = fold_build2 (MULT_EXPR, ulltype, fd->factor, c);
|
||||
t = fold_build2 (PLUS_EXPR, ulltype,
|
||||
t, fd->min_inner_iterations);
|
||||
t, fd->first_inner_iterations);
|
||||
t2 = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, false,
|
||||
GSI_CONTINUE_LINKING);
|
||||
cond_stmt = gimple_build_cond (GE_EXPR, stopvalull, d,
|
||||
|
|
|
@ -212,7 +212,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
fd->sched_modifiers = 0;
|
||||
fd->chunk_size = NULL_TREE;
|
||||
fd->simd_schedule = false;
|
||||
fd->min_inner_iterations = NULL_TREE;
|
||||
fd->first_inner_iterations = NULL_TREE;
|
||||
fd->factor = NULL_TREE;
|
||||
fd->adjn1 = NULL_TREE;
|
||||
collapse_iter = NULL;
|
||||
|
@ -726,16 +726,8 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
if (loop->m1 || loop->m2)
|
||||
{
|
||||
gcc_assert (single_nonrect != -1);
|
||||
if (single_nonrect_cond_code == LT_EXPR)
|
||||
{
|
||||
n1 = n1first;
|
||||
n2 = n2first;
|
||||
}
|
||||
else
|
||||
{
|
||||
n1 = n1last;
|
||||
n2 = n2last;
|
||||
}
|
||||
n1 = n1first;
|
||||
n2 = n2first;
|
||||
}
|
||||
t = fold_build2 (PLUS_EXPR, itype, t, fold_convert (itype, n2));
|
||||
t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
|
||||
|
@ -754,8 +746,6 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
or last value of the outer iterator (the one with fewer
|
||||
iterations).
|
||||
Compute t2 = ((m2 - m1) * ostep) / step
|
||||
(for single_nonrect_cond_code GT_EXPR
|
||||
t2 = ((m1 - m2) * ostep) / step instead)
|
||||
and niters = outer_count * t
|
||||
+ t2 * ((outer_count - 1) * outer_count / 2)
|
||||
*/
|
||||
|
@ -763,11 +753,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
tree m2 = loop->m2 ? loop->m2 : integer_zero_node;
|
||||
m1 = fold_convert (itype, m1);
|
||||
m2 = fold_convert (itype, m2);
|
||||
tree t2;
|
||||
if (single_nonrect_cond_code == LT_EXPR)
|
||||
t2 = fold_build2 (MINUS_EXPR, itype, m2, m1);
|
||||
else
|
||||
t2 = fold_build2 (MINUS_EXPR, itype, m1, m2);
|
||||
tree t2 = fold_build2 (MINUS_EXPR, itype, m2, m1);
|
||||
t2 = fold_build2 (MULT_EXPR, itype, t2, ostep);
|
||||
if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
|
||||
t2 = fold_build2 (TRUNC_DIV_EXPR, itype,
|
||||
|
@ -776,7 +762,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
else
|
||||
t2 = fold_build2 (TRUNC_DIV_EXPR, itype, t2, step);
|
||||
t2 = fold_convert (llutype, t2);
|
||||
fd->min_inner_iterations = t;
|
||||
fd->first_inner_iterations = t;
|
||||
fd->factor = t2;
|
||||
t = fold_build2 (MULT_EXPR, llutype, t,
|
||||
single_nonrect_count);
|
||||
|
@ -834,11 +820,11 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
if (count)
|
||||
{
|
||||
*collapse_count = fold_convert_loc (loc, iter_type, count);
|
||||
if (fd->min_inner_iterations && fd->factor)
|
||||
if (fd->first_inner_iterations && fd->factor)
|
||||
{
|
||||
t = make_tree_vec (4);
|
||||
TREE_VEC_ELT (t, 0) = *collapse_count;
|
||||
TREE_VEC_ELT (t, 1) = fd->min_inner_iterations;
|
||||
TREE_VEC_ELT (t, 1) = fd->first_inner_iterations;
|
||||
TREE_VEC_ELT (t, 2) = fd->factor;
|
||||
TREE_VEC_ELT (t, 3) = fd->adjn1;
|
||||
*collapse_count = t;
|
||||
|
@ -856,7 +842,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
if (TREE_CODE (fd->loop.n2) == TREE_VEC)
|
||||
{
|
||||
gcc_assert (fd->non_rect);
|
||||
fd->min_inner_iterations = TREE_VEC_ELT (fd->loop.n2, 1);
|
||||
fd->first_inner_iterations = TREE_VEC_ELT (fd->loop.n2, 1);
|
||||
fd->factor = TREE_VEC_ELT (fd->loop.n2, 2);
|
||||
fd->adjn1 = TREE_VEC_ELT (fd->loop.n2, 3);
|
||||
fd->loop.n2 = TREE_VEC_ELT (fd->loop.n2, 0);
|
||||
|
|
|
@ -80,10 +80,9 @@ struct omp_for_data
|
|||
struct omp_for_data_loop *loops;
|
||||
/* The following are relevant only for non-rectangular loops
|
||||
where only a single loop depends on an outer loop iterator. */
|
||||
tree min_inner_iterations; /* Number of iterations of the inner
|
||||
loop with either the first or last
|
||||
outer iterator, depending on which
|
||||
results in fewer iterations. */
|
||||
tree first_inner_iterations; /* Number of iterations of the inner
|
||||
loop with the first outer iterator
|
||||
(or adjn1, if that is non-NULL). */
|
||||
tree factor; /* (m2 - m1) * outer_step / inner_step. */
|
||||
/* Adjusted n1 of the outer loop in such loop nests (if needed). */
|
||||
tree adjn1;
|
||||
|
|
Loading…
Add table
Reference in a new issue