This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [gomp4.1] fold ordered depend(sink) clauses
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Aldy Hernandez <aldyh at redhat dot com>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 31 Jul 2015 18:38:22 +0200
- Subject: Re: [gomp4.1] fold ordered depend(sink) clauses
- Authentication-results: sourceware.org; auth=none
- References: <55B96647 dot 20805 at redhat dot com> <20150730100114 dot GO1780 at tucnak dot redhat dot com> <55BADD27 dot 1080402 at redhat dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Jul 30, 2015 at 07:27:51PM -0700, Aldy Hernandez wrote:
> +static gimple
> +gimplify_omp_ordered (tree expr, gimple_seq body)
> +{
> + tree c, decls;
> + int failures = 0;
> + unsigned int i;
> +
> + if (gimplify_omp_ctxp)
> + for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
> + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
> + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
> + {
> + bool fail = false;
> + for (decls = OMP_CLAUSE_DECL (c), i = 0;
> + decls && TREE_CODE (decls) == TREE_LIST;
> + decls = TREE_CHAIN (decls), ++i)
> + if (i < gimplify_omp_ctxp->loop_iter_var.length ()
> + && TREE_VALUE (decls) != gimplify_omp_ctxp->loop_iter_var[i])
> + {
> + error_at (OMP_CLAUSE_LOCATION (c),
> + "variable %qE is not an iteration "
> + "of outermost loop %d, expected %qE",
> + TREE_VALUE (decls), i + 1,
> + gimplify_omp_ctxp->loop_iter_var[i]);
> + fail = true;
> + failures++;
> + }
> + /* Avoid being too redundant. */
> + if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length ())
> + {
> + error_at (OMP_CLAUSE_LOCATION (c),
> + "number of variables in depend(sink) "
> + "clause does not match number of "
> + "iteration variables");
> + failures++;
> + }
failures seems to be a write only variable.
Perhaps if fail is true (set it to true after this error too),
don't create the ordered at all? Or drop the bogus clauses.
> +
> + /* ?? This is stupid. We need to call extract_omp_for_data just
> + to get the number of ordered loops... */
> + extract_omp_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, NULL);
> + if (!fd.ordered)
> + return;
> + struct omp_for_data_loop *loops
> + = (struct omp_for_data_loop *)
> + alloca (fd.ordered * sizeof (struct omp_for_data_loop));
You can do just what expand_omp_for does:
struct omp_for_data fd;
struct omp_for_data_loop *loops;
loops
= (struct omp_for_data_loop *)
alloca (gimple_omp_for_collapse (ctx->outer->stmt)
* sizeof (struct omp_for_data_loop));
extract_omp_for_data (as_a <gomp_for *> (ctx->outer_stmt), &fd, loops);
> + For example:
> +
> + for (i=0; i < N; ++i)
> + depend(sink:i-8,j-1)
> + depend(sink:i,j-2) // Completely ignored because i+0.
> + depend(sink:i-4,j+3)
> + depend(sink:i-6,j+2)
Even when writing comments, it is better to make it valid:
#pragma omp for ordered(2)
for (i=0; i < N; ++i)
for (j=0; j < M; ++j)
{
#pragma omp ordered \
depend(sink:i-8,j-1) \
depend(sink:i,j-2) \ // Completely ignored because i+0.
depend(sink:i-4,j+3) \
depend(sink:i-6,j+2)
#pragma omp ordered depend(source)
}
> +
> + Folded clause is:
> +
> + depend(sink:-gcd(8,4,6),min(-1,3,2))
Spaces here instead of desirable tab.
> + -or-
> + depend(sink:-2,-1)
> + */
> +
> + /* FIXME: Computing GCD's where the first element is zero is
> + non-trivial in the presence of collapsed loops. Do this later. */
> + if (fd.collapse > 1)
> + return;
Better ad an gcc_assert for now.
> + enum {
> + DIR_UNKNOWN,
> + DIR_FORWARD,
> + DIR_BACKWARD
> + } loop_dir;
> + switch (fd.loops[i].cond_code)
> + {
> + case LT_EXPR:
> + case LE_EXPR:
> + loop_dir = DIR_FORWARD;
> + break;
> + case GT_EXPR:
> + case GE_EXPR:
> + loop_dir = DIR_BACKWARD;
> + break;
> + default:
> + loop_dir = DIR_UNKNOWN;
> + gcc_unreachable ();
> + }
I think there is no point in doing this, extract_omp_for_data
canonicalizes cond_code already, so it is always
LT_EXPR or GT_EXPR. So just gcc_assert it is these two and
compare it directly, or add bool forward = fd.loops[i].cond_code == LT_EXPR;
?
> +
> + /* While the committee makes up its mind, bail if we have any
> + non-constant steps. */
> + if (TREE_CODE (fd.loops[i].step) != INTEGER_CST)
> + goto gimplify_omp_ordered_ret;
Misnamed label. lower instead?
> + wide_int offset = TREE_PURPOSE (decls);
> + if (!iter_vars[i])
> + iter_vars[i] = TREE_VALUE (decls);
> +
> + /* Ignore invalid offsets that are not multiples of the step. */
> + if (!wi::multiple_of_p
> + (wi::abs (offset), wi::abs ((wide_int) fd.loops[i].step),
> + UNSIGNED))
What does wi::abs do with very large unsigned integers?
#pragma omp ordered(2)
for (unsigned int i = 64; i > 32; i += -1)
for (unsigned int j = 0; j < 32; j++)
?
step of i is 0xffffffff and cond_code is GT_EXPR. I suppose for unsigned
steps you don't want to use wi::abs, but just negate the step if
iterating downward?
Jakub