public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Aldy Hernandez <aldyh@redhat.com>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [gomp4.1] depend(sink) and depend(source) parsing for C
Date: Mon, 13 Jul 2015 13:56:00 -0000	[thread overview]
Message-ID: <20150713135618.GQ1788@tucnak.redhat.com> (raw)
In-Reply-To: <55A161F8.8010800@redhat.com>

On Sat, Jul 11, 2015 at 11:35:36AM -0700, Aldy Hernandez wrote:
> It looks like the C++ bits are quite similar to the C ones.  AFAICT, only
> numbers are allowed for the sink offsets, so no C++ iterators, which would
> likely complicate matters.  If they are eventually allowed, we can implement
> them as a follow up.
> 
> The attached patch addresses all your concerns plus includes the C++
> implementation.  The included test passes for both languages.
> 
> I can work on Fortran next if you'd like.

Please leave Fortran unresolved for now, we'll see in Autumn if we have time
for Fortran OpenMP 4.1 support, or not, there is also the possibility to
handle it like in 4.9 - 4.9.0 came with just C/C++ OpenMP 4.0 support
(and Fortran only OpenMP 3.1 support) and 4.9.1 added Fortran OpenMP 4.0 support.

Please write ChangeLog entries and commit them into */ChangeLog.gomp files.

> +	  if (c_parser_next_token_is_not (parser, CPP_NUMBER))
> +	    {
> +	      c_parser_error (parser, "expected %<integer%>");

I think %< and %> here

> +	      return list;
> +	    }
> +
> +	  addend = c_parser_peek_token (parser)->value;
> +	  if (TREE_CODE (addend) != INTEGER_CST)
> +	    {
> +	      c_parser_error (parser, "expected %<integer%>");

and here aren't appropriate here, you don't expect integer as a keyword,
but some integer...

On the C++ FE side, please also try a testcase in g++.dg/gomp/ where
the ordered(n) loop with #pragma omp ordered depend({source,sink}) will be
in a template, to make sure pt.c does the right thing with it.

> +	  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER))
> +	    {
> +	      cp_parser_error (parser, "expected %<integer%>");
> +	      return list;
> +	    }
> +
> +	  addend = cp_lexer_peek_token (parser->lexer)->u.value;
> +	  if (TREE_CODE (addend) != INTEGER_CST)
> +	    {
> +	      cp_parser_error (parser, "expected %<integer%>");

See above.

> @@ -365,6 +367,8 @@ new_omp_context (enum omp_region_type region_type)
>  
>    c = XCNEW (struct gimplify_omp_ctx);
>    c->outer_context = gimplify_omp_ctxp;
> +  c->iter_vars.safe_push(0);
> +  c->iter_vars.pop();

As mentioned, please leave this out.

> @@ -8982,7 +8997,36 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
>  		}
>  		break;
>  	      case OMP_ORDERED:
> -		g = gimple_build_omp_ordered (body);
> +		if (gimplify_omp_ctxp)
> +		  for (tree c = OMP_ORDERED_CLAUSES (*expr_p);
> +		       c; c = OMP_CLAUSE_CHAIN (c))
> +		    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
> +			&& OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
> +		      {
> +			unsigned int n = 0;
> +			bool fail = false;
> +			for (tree decls = OMP_CLAUSE_DECL (c);
> +			     decls && TREE_CODE (decls) == TREE_LIST;
> +			     decls = TREE_CHAIN (decls), ++n)
> +			  if (n < gimplify_omp_ctxp->iter_vars.length ()
> +			      && TREE_VALUE (decls)
> +			      != gimplify_omp_ctxp->iter_vars[n])
> +			    {
> +			      error_at (OMP_CLAUSE_LOCATION (c),
> +					"variable %qE is not an iteration "
> +					"variable", TREE_VALUE (decls));

I think this error message will be confusing to users, if they write
#pragma omp for ordered(3)
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
for (int k = 0; k < 10; k++)
{
#pragma omp ordered depend(sink:k-1, j+2, i-3)
#pragma omp ordered depend(source)
}
because then it will complain that k and i are not iteration
variables, when they in fact are, just in wrong order.

I believe our diagnostics doesn't have support for ngettext style
of diagnostic messages (1st vs. 2nd, 3rd, 4th ...); I wonder if
saying variable %qE is not an iteration variable of outermost loop %d, expected %qE",
TREE_VALUE (decls), n + 1, gimplify_omp_ctxp->iter_vars[n]
wouldn't be better or something similar.

> +			      fail = true;
> +			    }
> +			/* Avoid being too redundant.  */
> +			if (!fail
> +			    && n != gimplify_omp_ctxp->iter_vars.length ())
> +			  error_at (OMP_CLAUSE_LOCATION (c),
> +			     "number of variables in depend(sink) clause "
> +			     "does not match number of iteration variables");
> +		      }
> +
> +		g = gimple_build_omp_ordered (body,
> +					      OMP_ORDERED_CLAUSES (*expr_p));
>  		break;
>  	      case OMP_CRITICAL:
>  		gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> index 83677ea..3dec095 100644
> --- a/gcc/omp-low.c
> +++ b/gcc/omp-low.c
> @@ -2996,6 +2996,8 @@ scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
>  static bool
>  check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
>  {
> +  tree c;
> +
>    /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
>       inside an OpenACC CTX.  */
>    if (!(is_gimple_omp (stmt)
> @@ -3216,7 +3218,54 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
>  	    break;
>  	  }
>        break;
> +    case GIMPLE_OMP_TASK:
> +      for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
> +	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
> +	    && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
> +		|| OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
> +	  {
> +	    enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
> +	    gcc_assert (kind == OMP_CLAUSE_DEPEND_SOURCE
> +			|| kind == OMP_CLAUSE_DEPEND_SINK);
> +	    error_at (OMP_CLAUSE_LOCATION (c),
> +		      "depend(%s) is only available in %<omp ordered%>",

%<depend(%s)%> ?  Also, I'd perhaps replace available with allowed.

> +	      /* Look for containing ordered(N) loop.  */
> +	      for (omp_context *octx = ctx; octx; octx = octx->outer)
> +		if (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
> +		    && find_omp_clause (gimple_omp_for_clauses (octx->stmt),
> +					OMP_CLAUSE_ORDERED))

I think you want to save the result of find_omp_clause in a temporary
and also test if OMP_CLAUSE_ORDERED_EXPR (c) != NULL_TREE.


> +		  {
> +		    have_ordered = true;
> +		    break;
> +		  }
> +	      if (!have_ordered)
> +		{
> +		  error_at (OMP_CLAUSE_LOCATION (c),
> +			    "depend clause must be closely nested inside an "

%<depend%> ?

If you want to spend time on something still in the FE, it would be nice to
resolve the C++ iteration var issue (i.e. increase OMP_FOR number of
arguments, so that it could have yet another (optional) vector, say
OMP_FOR_ORIG_DECLS.  If that vector would be NULL, the gimplifier would
assume that all the decls in OMP_FOR_INIT are the ones present in the
source, if it would be present, you'd use them for the variable checking
instead of the ones from OMP_FOR_INIT (but, replace them with the
decls from OMP_FOR_INIT after the checking).

There is another issue - if some iterator var has pointer type, supposedly
we want somewhere in the FEs already multiply it by the size of what they
point to (and convert to sizetype).  For C FE, it can be done already during
parsing, we should know the type of the iterator var already at that point,
for C++ FE it needs to be done only in finish_omp_clauses if
!processing_template_decl, because in templates we might not know the type.

	Jakub

  parent reply	other threads:[~2015-07-13 13:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-09 19:22 Aldy Hernandez
2015-07-09 18:53 ` Jakub Jelinek
2015-07-10 18:03   ` Aldy Hernandez
2015-07-11 18:35     ` Aldy Hernandez
2015-07-11 18:55       ` Aldy Hernandez
2015-07-13 13:56       ` Jakub Jelinek [this message]
2015-07-13 17:11         ` Aldy Hernandez
2015-07-13 17:32           ` Jakub Jelinek
2015-07-14 14:07         ` Aldy Hernandez
2015-07-14 14:15           ` Jakub Jelinek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150713135618.GQ1788@tucnak.redhat.com \
    --to=jakub@redhat.com \
    --cc=aldyh@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).