Re: [gomp4, fortran] Patch to fix continuation checks of OpenACC and OpenMP directives
Ping On 07.07.2015 14:27, Ilmir Usmanov wrote: Ping 30.06.2015, 03:43, Ilmir Usmanov m...@ilmir.us: Hi Cesar! Thanks for your review! 08.06.2015, 17:59, Cesar Philippidis ce...@codesourcery.com: On 06/07/2015 02:05 PM, Ilmir Usmanov wrote: Fixed fortran mail-list address. Sorry for inconvenience. 08.06.2015, 00:01, Ilmir Usmanov m...@ilmir.us: Hi Cesar! This patch fixes checks of OpenMP and OpenACC continuations in case if someone mixes them (i.e. continues OpenMP directive with !$ACC sentinel or vice versa). OK for gomp branch? Thanks for working on this. Does this fix PR63858 by any chance? No problem. I had a feeling that something is wrong in the scanner since I've committed an initial support of OpenACC ver. 1.0 to gomp branch (more than a year ago). Now it does fix the PR, because I've added support of fixed form to the patch. BTW, your test in the PR has a wrong continuation. Fixed test added to the patch. two minor nits... 0001-Fix-mix-of-OpenACC-and-OpenMP-sentinels-in-continuat.patch From 5492bf5bc991b6924f5e3b35c11eeaed745df073 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Sun, 7 Jun 2015 23:55:22 +0300 Subject: [PATCH] Fix mix of OpenACC and OpenMP sentinels in continuation --- gcc/fortran/ChangeLog | 5 + Use ChangeLog.gomp for gomp-4_0-branch. Done. + /* In case we have an OpenMP directive continued by OpenACC + sentinel, or vice versa, we get both openmp_flag and + openacc_flag on. */ + + if (openacc_flag openmp_flag) + { + int is_openmp = 0; + for (i = 0; i 5; i++, c = next_char ()) + { + if (gfc_wide_tolower (c) != (unsigned char) !$acc[i]) + is_openmp = 1; + if (i == 4) + old_loc = gfc_current_locus; + } + gfc_error (Wrong %s continuation at %C: expected %s, got %s, + is_openmp ? OpenACC : OpenMP, + is_openmp ? !$ACC : !$OMP, + is_openmp ? !$OMP : !$ACC); I think it's better for the translation project if you made this a complete string. So maybe change this line into gfc_error (is_openmp ? Wrong continuation at %C: expected !$ACC, got !$OMP, : Wrong continuation at %C: expected !$OMP, got !$ACC); Done Other than that, it looks fine. Thanks, Cesar OK for gomp branch? -- Ilmir. -- Ilmir. -- Ilmir.
Re: [gomp4, fortran] Patch to fix continuation checks of OpenACC and OpenMP directives
Hi Cesar! Thanks for your review! 08.06.2015, 17:59, Cesar Philippidis ce...@codesourcery.com: On 06/07/2015 02:05 PM, Ilmir Usmanov wrote: Fixed fortran mail-list address. Sorry for inconvenience. 08.06.2015, 00:01, Ilmir Usmanov m...@ilmir.us: Hi Cesar! This patch fixes checks of OpenMP and OpenACC continuations in case if someone mixes them (i.e. continues OpenMP directive with !$ACC sentinel or vice versa). OK for gomp branch? Thanks for working on this. Does this fix PR63858 by any chance? No problem. I had a feeling that something is wrong in the scanner since I've committed an initial support of OpenACC ver. 1.0 to gomp branch (more than a year ago). Now it does fix the PR, because I've added support of fixed form to the patch. BTW, your test in the PR has a wrong continuation. Fixed test added to the patch. two minor nits... 0001-Fix-mix-of-OpenACC-and-OpenMP-sentinels-in-continuat.patch From 5492bf5bc991b6924f5e3b35c11eeaed745df073 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Sun, 7 Jun 2015 23:55:22 +0300 Subject: [PATCH] Fix mix of OpenACC and OpenMP sentinels in continuation --- gcc/fortran/ChangeLog | 5 + Use ChangeLog.gomp for gomp-4_0-branch. Done. + /* In case we have an OpenMP directive continued by OpenACC + sentinel, or vice versa, we get both openmp_flag and + openacc_flag on. */ + + if (openacc_flag openmp_flag) + { + int is_openmp = 0; + for (i = 0; i 5; i++, c = next_char ()) + { + if (gfc_wide_tolower (c) != (unsigned char) !$acc[i]) + is_openmp = 1; + if (i == 4) + old_loc = gfc_current_locus; + } + gfc_error (Wrong %s continuation at %C: expected %s, got %s, + is_openmp ? OpenACC : OpenMP, + is_openmp ? !$ACC : !$OMP, + is_openmp ? !$OMP : !$ACC); I think it's better for the translation project if you made this a complete string. So maybe change this line into gfc_error (is_openmp ? Wrong continuation at %C: expected !$ACC, got !$OMP, : Wrong continuation at %C: expected !$OMP, got !$ACC); Done Other than that, it looks fine. Thanks, Cesar OK for gomp branch? -- Ilmir. From dc98062b499838ca4391c0ed497f40205267a44e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov m...@ilmir.us Date: Tue, 30 Jun 2015 03:05:23 +0300 Subject: [PATCH] PR/63858 --- gcc/fortran/ChangeLog.gomp | 10 ++ gcc/fortran/scanner.c | 259 +--- gcc/testsuite/ChangeLog.gomp| 7 + gcc/testsuite/gfortran.dg/goacc/omp-fixed.f | 32 gcc/testsuite/gfortran.dg/goacc/omp.f95 | 8 + 5 files changed, 216 insertions(+), 100 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/goacc/omp-fixed.f diff --git a/gcc/fortran/ChangeLog.gomp b/gcc/fortran/ChangeLog.gomp index aa02ffe..0a5bf47 100644 --- a/gcc/fortran/ChangeLog.gomp +++ b/gcc/fortran/ChangeLog.gomp @@ -1,3 +1,13 @@ +2015-06-30 Ilmir Usmanov m...@ilmir.us + + PR/63858 + Fix mix of OpenACC and OpenMP sentinels in continuation. + * scanner.c (skip_omp_attribute_fixed, skip_oacc_attribute_fixed): New + functions. + (skip_fixed_comments): Fix mix of OpenACC and OpenMP sentinels in + continuation. + (gfc_next_char_literal): Likewise. + 2015-06-18 James Norris jnor...@codesourcery.com * trans-decl.c (find_module_oacc_declare_clauses): Fix setting of diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index f0e6404..d66cf65 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -935,6 +935,63 @@ skip_free_comments (void) return false; } +/* Return true if MP was matched in fixed form. */ +static bool +skip_omp_attribute_fixed (locus *start) +{ + gfc_char_t c; + if (((c = next_char ()) == 'm' || c == 'M') + ((c = next_char ()) == 'p' || c == 'P')) +{ + c = next_char (); + if (c != '\n' + (continue_flag + || c == ' ' || c == '\t' || c == '0')) + { + do + c = next_char (); + while (gfc_is_whitespace (c)); + if (c != '\n' c != '!') + { + /* Canonicalize to *$omp. */ + *start-nextc = '*'; + openmp_flag = 1; + gfc_current_locus = *start; + return true; + } + } +} + return false; +} + +/* Return true if CC was matched in fixed form. */ +static bool +skip_oacc_attribute_fixed (locus *start) +{ + gfc_char_t c; + if (((c = next_char ()) == 'c' || c == 'C') + ((c = next_char ()) == 'c' || c == 'C')) +{ + c = next_char (); + if (c != '\n' + (continue_flag + || c == ' ' || c == '\t' || c == '0')) + { + do + c = next_char (); + while (gfc_is_whitespace (c)); + if (c != '\n' c != '!') + { + /* Canonicalize to *$omp. */ + *start-nextc = '*'; + openacc_flag = 1; + gfc_current_locus = *start; + return true; + } + } +} + return false; +} /* Skip comment lines in fixed source mode. We have the same rules as in skip_free_comment(), except that we can
[gomp4, fortran] Patch to fix continuation checks of OpenACC and OpenMP directives
Hi Cesar! This patch fixes checks of OpenMP and OpenACC continuations in case if someone mixes them (i.e. continues OpenMP directive with !$ACC sentinel or vice versa). OK for gomp branch? -- Ilmir. From 5492bf5bc991b6924f5e3b35c11eeaed745df073 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Sun, 7 Jun 2015 23:55:22 +0300 Subject: [PATCH] Fix mix of OpenACC and OpenMP sentinels in continuation --- gcc/fortran/ChangeLog | 5 + gcc/fortran/scanner.c | 28 gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gfortran.dg/goacc/omp.f95 | 8 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 67f9e09..f61e0e9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2015-06-07 Ilmir Usmanov m...@ilmir.us + + * scanner.c (gfc_next_char_literal): Fix mix of OpenACC and OpenMP + sentinels in continuation. + 2015-05-05 David Malcolm dmalc...@redhat.com * expr.c (check_inquiry): Fix indentation so that it reflects the diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index f0e6404..5af4eea 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -1331,7 +1331,7 @@ restart: continue_line = gfc_linebuf_linenum (gfc_current_locus.lb); if (flag_openmp) - if (prev_openmp_flag != openmp_flag) + if (prev_openmp_flag != openmp_flag !openacc_flag) { gfc_current_locus = old_loc; openmp_flag = prev_openmp_flag; @@ -1340,7 +1340,7 @@ restart: } if (flag_openacc) - if (prev_openacc_flag != openacc_flag) + if (prev_openacc_flag != openacc_flag !openmp_flag) { gfc_current_locus = old_loc; openacc_flag = prev_openacc_flag; @@ -1359,7 +1359,7 @@ restart: while (gfc_is_whitespace (c)) c = next_char (); - if (openmp_flag) + if (openmp_flag !openacc_flag) { for (i = 0; i 5; i++, c = next_char ()) { @@ -1370,7 +1370,7 @@ restart: while (gfc_is_whitespace (c)) c = next_char (); } - if (openacc_flag) + if (openacc_flag !openmp_flag) { for (i = 0; i 5; i++, c = next_char ()) { @@ -1382,6 +1382,26 @@ restart: c = next_char (); } + /* In case we have an OpenMP directive continued by OpenACC + sentinel, or vice versa, we get both openmp_flag and + openacc_flag on. */ + + if (openacc_flag openmp_flag) + { + int is_openmp = 0; + for (i = 0; i 5; i++, c = next_char ()) + { + if (gfc_wide_tolower (c) != (unsigned char) !$acc[i]) + is_openmp = 1; + if (i == 4) + old_loc = gfc_current_locus; + } + gfc_error (Wrong %s continuation at %C: expected %s, got %s, + is_openmp ? OpenACC : OpenMP, + is_openmp ? !$ACC : !$OMP, + is_openmp ? !$OMP : !$ACC); + } + if (c != '') { if (in_string) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c4781c..05a9a52 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-07 Ilmir Usmanov m...@ilmir.us + + * gfortran.dg/goacc/omp.f95: Add mix of OpenACC and OpenMP + sentinels in continuation to test. + 2015-05-06 Yvan Roux yvan.r...@linaro.org PR target/64208 diff --git a/gcc/testsuite/gfortran.dg/goacc/omp.f95 b/gcc/testsuite/gfortran.dg/goacc/omp.f95 index 24f639f..a7333eb 100644 --- a/gcc/testsuite/gfortran.dg/goacc/omp.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/omp.f95 @@ -63,4 +63,12 @@ contains !$omp end parallel !$acc end data end subroutine roku + + subroutine nana + !$acc parallel + !$omp do ! { dg-error Wrong OpenACC continuation } + + !$omp parallel + !$acc loop ! { dg-error Wrong OpenMP continuation } + end subroutine nana end module test \ No newline at end of file -- 1.9.1
Re: [gomp4, fortran] Patch to fix continuation checks of OpenACC and OpenMP directives
Fixed fortran mail-list address. Sorry for inconvenience. 08.06.2015, 00:01, Ilmir Usmanov m...@ilmir.us: Hi Cesar! This patch fixes checks of OpenMP and OpenACC continuations in case if someone mixes them (i.e. continues OpenMP directive with !$ACC sentinel or vice versa). OK for gomp branch? -- Ilmir. -- Ilmir. From 5492bf5bc991b6924f5e3b35c11eeaed745df073 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Sun, 7 Jun 2015 23:55:22 +0300 Subject: [PATCH] Fix mix of OpenACC and OpenMP sentinels in continuation --- gcc/fortran/ChangeLog | 5 + gcc/fortran/scanner.c | 28 gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gfortran.dg/goacc/omp.f95 | 8 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 67f9e09..f61e0e9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2015-06-07 Ilmir Usmanov m...@ilmir.us + + * scanner.c (gfc_next_char_literal): Fix mix of OpenACC and OpenMP + sentinels in continuation. + 2015-05-05 David Malcolm dmalc...@redhat.com * expr.c (check_inquiry): Fix indentation so that it reflects the diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index f0e6404..5af4eea 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -1331,7 +1331,7 @@ restart: continue_line = gfc_linebuf_linenum (gfc_current_locus.lb); if (flag_openmp) - if (prev_openmp_flag != openmp_flag) + if (prev_openmp_flag != openmp_flag !openacc_flag) { gfc_current_locus = old_loc; openmp_flag = prev_openmp_flag; @@ -1340,7 +1340,7 @@ restart: } if (flag_openacc) - if (prev_openacc_flag != openacc_flag) + if (prev_openacc_flag != openacc_flag !openmp_flag) { gfc_current_locus = old_loc; openacc_flag = prev_openacc_flag; @@ -1359,7 +1359,7 @@ restart: while (gfc_is_whitespace (c)) c = next_char (); - if (openmp_flag) + if (openmp_flag !openacc_flag) { for (i = 0; i 5; i++, c = next_char ()) { @@ -1370,7 +1370,7 @@ restart: while (gfc_is_whitespace (c)) c = next_char (); } - if (openacc_flag) + if (openacc_flag !openmp_flag) { for (i = 0; i 5; i++, c = next_char ()) { @@ -1382,6 +1382,26 @@ restart: c = next_char (); } + /* In case we have an OpenMP directive continued by OpenACC + sentinel, or vice versa, we get both openmp_flag and + openacc_flag on. */ + + if (openacc_flag openmp_flag) + { + int is_openmp = 0; + for (i = 0; i 5; i++, c = next_char ()) + { + if (gfc_wide_tolower (c) != (unsigned char) !$acc[i]) + is_openmp = 1; + if (i == 4) + old_loc = gfc_current_locus; + } + gfc_error (Wrong %s continuation at %C: expected %s, got %s, + is_openmp ? OpenACC : OpenMP, + is_openmp ? !$ACC : !$OMP, + is_openmp ? !$OMP : !$ACC); + } + if (c != '') { if (in_string) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c4781c..05a9a52 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-07 Ilmir Usmanov m...@ilmir.us + + * gfortran.dg/goacc/omp.f95: Add mix of OpenACC and OpenMP + sentinels in continuation to test. + 2015-05-06 Yvan Roux yvan.r...@linaro.org PR target/64208 diff --git a/gcc/testsuite/gfortran.dg/goacc/omp.f95 b/gcc/testsuite/gfortran.dg/goacc/omp.f95 index 24f639f..a7333eb 100644 --- a/gcc/testsuite/gfortran.dg/goacc/omp.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/omp.f95 @@ -63,4 +63,12 @@ contains !$omp end parallel !$acc end data end subroutine roku + + subroutine nana + !$acc parallel + !$omp do ! { dg-error Wrong OpenACC continuation } + + !$omp parallel + !$acc loop ! { dg-error Wrong OpenMP continuation } + end subroutine nana end module test \ No newline at end of file -- 1.9.1
Re: Fix logic error in Fortran OpenACC parsing
Hi! On 06.05.2015 14:38, Thomas Schwinge wrote: Hi! On Tue, 5 May 2015 15:38:03 -0400, David Malcolm dmalc...@redhat.com wrote: On Wed, 2015-04-29 at 14:10 +0200, Mikael Morin wrote: Le 29/04/2015 02:02, David Malcolm a écrit : diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 2c7c554..30e4eab 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -4283,7 +4283,7 @@ parse_oacc_structured_block (gfc_statement acc_st) unexpected_eof (); else if (st != acc_end_st) gfc_error (Expecting %s at %C, gfc_ascii_statement (acc_end_st)); - reject_statement (); + reject_statement (); } while (st != acc_end_st); I think this one is a bug; there should be braces around 'gfc_error' and 'reject_statement'. If 'st' is 'acc_end_st', as it shall be, the statement is rejected. So, this is a bug. At least that's the pattern in 'parse_oacc_loop', and how the 'unexpected_statement' function is used. FWIW, Jeff had approved that patch, so I've committed the patch to trunk (as r222823), making the indentation reflect the block structure. Thomas: should the reject_statement (); call in the above be guarded by the else if (st != acc_end_st) clause? Indeed, this seems to be a bug that has been introduced very early in the OpenACC Fortran front end development -- see how the parse_oacc_structured_block function evolved in the patches posted in http://news.gmane.org/find-root.php?message_id=%3C52E1595D.907%40samsung.com%3E and following (Ilmir, CCed just in case). I also see that the corresponding OpenMP code, parse_omp_structured_block, just calls unexpected_statement, which Ilmir's initial patch also did, but at some point, he then changed this to the current code: gfc_error followed by reject_statement, as cited above -- I would guess for the reason to get a better error message? (Tobias, should this thus also be done for OpenMP, and/or extend unexpected_statement accordingly?) That's true. I've checked abandoned openacc-1_0-branch and I used unexpected_statement there (there still odd *_acc_* naming presents instead of new-and-shiny *_oacc_* one), but, as you mentioned, I've changed this for better error reporting... and introduced the bug. And then, I'm a bit confused: is it OK that despite this presumed logic error, which affects all (?) valid executions of this parsing code, we're not running into any issues with the OpenACC Fortran front end test cases? I think, this is OK, since this is an !$ACC END _smth_ statement and it shall not present in the AST. So, it is abandoned later anyway ;) (if I remember correctly, during gfc_clear_new_st call). Although the bug does not affect the logic, it is still a bug. OK for trunk? From my point of view, OK. commit 068eebfa63b2b4c8849ed5fd2c9d0a130586dfb0 Author: Thomas Schwinge tho...@codesourcery.com Date: Wed May 6 13:18:18 2015 +0200 Fix logic error in Fortran OpenACC parsing gcc/fortran/ * parse.c (parse_oacc_structured_block): Fix logic error. Reported by Mikael Morin mikael.mo...@sfr.fr. --- gcc/fortran/parse.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git gcc/fortran/parse.c gcc/fortran/parse.c index 30e4eab..e977498 100644 --- gcc/fortran/parse.c +++ gcc/fortran/parse.c @@ -4282,8 +4282,10 @@ parse_oacc_structured_block (gfc_statement acc_st) if (st == ST_NONE) unexpected_eof (); else if (st != acc_end_st) - gfc_error (Expecting %s at %C, gfc_ascii_statement (acc_end_st)); - reject_statement (); + { + gfc_error (Expecting %s at %C, gfc_ascii_statement (acc_end_st)); + reject_statement (); + } } while (st != acc_end_st); Grüße, Thomas -- Ilmir.
Re: [gomp4] OpenACC wait directive
Hi Cesar! Thank you for the update! On 05.10.2014 02:32, Cesar Philippidis wrote: On 10/03/2014 07:34 AM, Cesar Philippidis wrote: On 09/24/2014 12:18 AM, Ilmir Usmanov wrote: Hi Cesar! Thank you for the patch! On 24.09.2014 02:29, Cesar Philippidis wrote: This patch adds support for the async clause in the wait directive in fortran. It should be pretty straight forward. The fortran FE already supports the wait directive, but the async clause was introduced to the wait directive in OpenACC 2.0 and that was missing in gomp-4_0-branch. Sorry for the delay. I encountered some problems with the runtime in our internal branch, and that slowed things down a bit. Anyway, you are correct, I broke the optional argument to wait in the previous patch. This new patch addresses that and it also make the wait construct conform with OpenACC 2.0. Specifically, !$acc wait (1, 2) async (3) should behave as ex[ected. If you look at gfc_trans_oacc_wait_directive, you'll note that a call to GOACC_wait is emitted for the wait directive. Since I had to add a runtime library stub for that builtin function, I decided to go ahead an include the c front end bits. Is this patch OK for gomp-4_0-branch? Julian is working on working on a more complete implementation of the runtime. The runtime stub that I included is only temporary. I noticed that I forgot to include the changes to gimplify.c in that patch. This new patch includes those changes. Cesar As usual, I'll mostly focus on fortran part, since I don't know CFE and ME well enough. Nevertheless, is there a reason to differ C from Fortran in behavior of matching int-expr-list? I mean, in C you support only integer literals as parameter of wait, but in Fortran you also cover parameters. Anyway, Fortran part. gfc_match_oacc_wait (void) +if (!gfc_resolve_expr (el-expr) +|| el-expr-ts.type != BT_INTEGER || el-expr-rank != 0 +|| el-expr-expr_type != EXPR_CONSTANT) + { +gfc_error (WAIT clause at %L requires a scalar INTEGER expression, + el-expr-where); As you probably know, in Fortran one can define a function after whole program. So, since you are resolving wait-list during match, you don't cover this case. But async clause works fine. By the way, the same difference between wait and async presents in CFE. Otherwise, Fortran part looks good for me. -- Ilmir.
Re: [gomp4] OpenACC wait directive
Hi Cesar! Thank you for the patch! On 24.09.2014 02:29, Cesar Philippidis wrote: This patch adds support for the async clause in the wait directive in fortran. It should be pretty straight forward. The fortran FE already supports the wait directive, but the async clause was introduced to the wait directive in OpenACC 2.0 and that was missing in gomp-4_0-branch. Yes, I've mostly focused on spec. ver. 1.0. Is this OK for gomp-4_0-branch? No, it isn't. According to the spec and this presentation: http://www.pgroup.com/lit/presentations/cea-3.pdf (See slide 1-35) it is possible to write construction like: !$acc wait(1) async(2) However, your patch doesn't support this. Also, don't forget to check whether a queue waits itself (for example, wait(1) async(1)). In addition, it breaks current support of the directive (for example, wait(1)). Note that this patch doesn't actually implement the async or wait clause in the middle end yet, because that requires additional runtime support. Thanks, Cesar -- Ilmir.
Re: [patch][gomp4] openacc loops
Hi Cesar! Sorry for long delay, I was busy at the institute. On 05.06.2014 07:58, Cesar Philippidis wrote: I didn't see a whole lot different from your gfc_trans_oacc_loop and the existing gfc_trans_omp_do, so I augmented the latter to handle the openacc loop clause. It looks like the only important change is ensure that gfc_trans_omp_do creates an OACC_LOOP stmt for the for openacc. I know that gfc_trans_omp_do also handles the lastprivate clause, but that shouldn't matter for the loop directive since it can't get set. Likewise for the SIMD stuff. Is there any specific reason why you created a new function to handle openacc loops? Yes, there was... I was going to support DO CONCURRENT loops. I've replaced the asserts with sorry messages in my other patch, so it shouldn't ICE anymore. If this patch is OK with you, please commit it. Now this patch looks good for me. Thomas, could you, please, commit it? -- Ilmir.
Re: [patch][gomp4] openacc loops
Hi Cesar! This patch, which is derived from Ilmir Usmanov's work posted here https://gcc.gnu.org/ml/gcc-patches/2014-04/msg00027.html, implements the loop directive in openacc. The original patch is mostly intact, Thank you! I looked through the patch and found that you also added middle-end part. I don't know a lot about middle-end, so, probably, Thomas could review the part. However, there is a regression in middle-end. About front-ends, especially fortran front-end: I did disable support for do concurrent loops since openacc 2.0a supports fortran up to fortran 2003. As I can see, you didn't remove helper code for DO CONCURRENT loops transformation (see below). @@ -12217,8 +12221,8 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) { - gcc_assert (code != OACC_LOOP); - collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); + //gcc_assert (code != OACC_LOOP); I suppose you forgot to remove this comment. +++ b/gcc/testsuite/gfortran.dg/goacc/loop-4.f95 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-additional-options -fdump-tree-original -std=f2008 } + +PROGRAM test + IMPLICIT NONE + INTEGER :: a(64), b(64), c(64), i, j, k + ! Must be replaced by three loops. + !$acc loop + DO CONCURRENT (i=1:64, j=1:64, k=1:64, i==j .and. j==k) This test is obsolete. I think you should remove this testcase since you are not supporting DO CONCURRENT loops. +++ b/gcc/testsuite/gfortran.dg/goacc/loop-tree.f95 For this test you should update tree-pretty-print.c (I forgot this): @@ -675,13 +675,13 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags) case OMP_CLAUSE_WORKER: pp_string (buffer, worker(); - dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), spc, flags, false); + dump_generic_node (buffer, OMP_CLAUSE_WORKER_EXPR (clause), spc, flags, false); pp_character(buffer, ')'); break; case OMP_CLAUSE_VECTOR: pp_string (buffer, vector(); - dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), spc, flags, false); + dump_generic_node (buffer, OMP_CLAUSE_VECTOR_EXPR (clause), spc, flags, false); pp_character(buffer, ')'); break; +/* Recursively generate conditional expressions. */ +static tree +gfc_trans_oacc_loop_generate_mask_conds (gfc_code *code, int collapse) +{ + if (collapse 1) +return gfc_trans_oacc_loop_generate_mask_conds (code-block-next, + collapse - 1); + else +return gfc_trans_omp_code (code-block-next, true); +} +static tree +gfc_trans_oacc_loop (gfc_code *code, stmtblock_t *pblock, +gfc_omp_clauses *loop_clauses) +{ + /* DO CONCURRENT specific vars. */ + int nforloops = 0; + int current_for = 0; + + if (collapse = 0) +collapse = 1; + + code = code-block-next; + + if (code-op == EXEC_DO_CONCURRENT) +gfc_error (!$ACC LOOP directive is unsupported on DO CONCURRENT %L, + code-loc); + + gcc_assert (code-op == EXEC_DO); + + if (pblock == NULL) +{ + gfc_start_block (block); + pblock = block; +} + + /* Calculate number of required for loops. */ + old_code = code; + for (i = 0; i collapse; i++) +{ + if (code-op == EXEC_DO) + nforloops++; + else + gcc_unreachable (); + code = code-block-next; +} + code = old_code; + + /* Set the number of required for loops for collapse. */ + /* FIXME: this is probably correct, but OMP_CLAUSE_COLLAPSE isn't supported + yet. */ + loop_clauses-collapse = nforloops; + + omp_clauses = gfc_trans_omp_clauses (pblock, loop_clauses, code-loc); + + init = make_tree_vec (nforloops); + cond = make_tree_vec (nforloops); + incr = make_tree_vec (nforloops); + + for (i = 0; i collapse; i++) +{ + if (code-op == EXEC_DO) + gfc_trans_oacc_loop_generate_for (pblock, se, code-ext.iterator-var, + code-ext.iterator-start, + code-ext.iterator-end, + code-ext.iterator-step, + current_for++, init, cond, incr, + inits); + else + gcc_unreachable (); + if (i + 1 collapse) + code = code-block-next; +} + + if (pblock != block) +{ + pushlevel (); + gfc_start_block (block); +} This is complicated for simple DO loops. I think the following will be enough (see gfc_trans_omp_do). code = code-block-next; + if (code-op == EXEC_DO_CONCURRENT) +gfc_error (!$ACC LOOP directive is unsupported on DO CONCURRENT %L, + code-loc); gcc_assert (code-op == EXEC_DO); init = make_tree_vec (collapse); cond = make_tree_vec (collapse); incr = make_tree_vec (collapse); if
FWD: Re: OpenACC subarray specifications in the GCC Fortran front end
On 16.05.2014 19:44, Ilmir Usmanov wrote: Hi Thomas! On 16.05.2014 19:12, Thomas Schwinge wrote: Hi Ilmir! You recently indicated that you have already begun implementing OpenACC subarray specifications in the GCC Fortran front end, but have not been/are not currently able to complete that. Would you be willing to share your WIP patch with Cesar, who is now working on this, so that he doesn't have to duplicate your work? Sure! I'm glad to know that my work won't go directly to trash. BTW, another patch is still pending: http://gcc.gnu.org/ml/gcc-patches/2014-04/msg00027.html Cesar, You can find the patch in attachment. I started to implement sub-arrays in gfortran by implementing OpenMP 4.0 target map clause. This clause was already implemented in C/C++ FEs, so I could check the behavior. I don't know whether it's already implemented in gfortran or not. To represent OpenMP array sections (or OpenACC subarrays) I used gfc_expr. After implementing OpenMP target map clauses I was going to use it to represent OpenACC data clauses, just as Thomas recommended in his mail: http://gcc.gnu.org/ml/gcc-patches/2014-01/msg02040.html I hope this will be useful for you. If you will have any question feel free to ask. Grüße, Thomas -- Ilmir. From 5ba154b9af6499f567172b92f9abcf362584be58 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Tue, 8 Apr 2014 17:08:02 +0400 Subject: [PATCH] Subarrays --- gcc/fortran/dump-parse-tree.c | 55 +++-- gcc/fortran/gfortran.h| 21 +- gcc/fortran/match.h | 1 + gcc/fortran/openmp.c | 292 +++--- gcc/fortran/parse.c | 17 +- gcc/fortran/resolve.c | 3 + gcc/fortran/st.c | 1 + gcc/fortran/trans-openmp.c| 185 +++- gcc/fortran/trans.c | 1 + gcc/testsuite/gfortran.dg/goacc/subarrays.f95 | 36 gcc/testsuite/gfortran.dg/gomp/map-1.f90 | 101 + gcc/testsuite/gfortran.dg/gomp/target-1.f90 | 21 ++ 12 files changed, 674 insertions(+), 60 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/goacc/subarrays.f95 create mode 100644 gcc/testsuite/gfortran.dg/gomp/map-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/target-1.f90 diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index b6679ab..bdc30c2 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1023,6 +1023,17 @@ show_namelist (gfc_namelist *n) fprintf (dumpfile, %s, n-sym-name); } +static void +show_expr_list (gfc_expr_list *el) +{ + for (; el-next; el = el-next) +{ + show_expr (el-expr); + fputc (',', dumpfile); +} + show_expr (el-expr); +} + /* Show OpenMP or OpenACC clauses. */ @@ -1043,6 +1054,12 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) show_expr (omp_clauses-final_expr); fputc (')', dumpfile); } + if (omp_clauses-device_id) +{ + fputs ( DEVICE(, dumpfile); + show_expr (omp_clauses-device_id); + fputc (')', dumpfile); +} if (omp_clauses-num_threads) { fputs ( NUM_THREADS(, dumpfile); @@ -1148,28 +1165,35 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) } fprintf (dumpfile, DEFAULT(%s), type); } - if (omp_clauses-tile_list) + for (int kind = 0; kind OMP_MAP_LIST_LAST; kind++) { - gfc_expr_list *list; - fputs ( TILE(, dumpfile); - for (list = omp_clauses-tile_list; list; list = list-next) + const char *type; + if (omp_clauses-map_lists[kind] == NULL) + continue; + + switch (kind) { - show_expr (list-expr); - if (list-next) - fputs (, , dumpfile); + case OMP_MAP_LIST_ALLOC: type = ALLOC; break; + case OMP_MAP_LIST_TO: type = TO; break; + case OMP_MAP_LIST_FROM: type = FROM; break; + case OMP_MAP_LIST_TOFROM: type = TOFROM; break; + default: + gcc_unreachable (); } + fprintf (dumpfile, MAP(%s:, type); + show_expr_list (omp_clauses-map_lists[kind]); + fputc (')', dumpfile); +} + if (omp_clauses-tile_list) +{ + fputs ( TILE(, dumpfile); + show_expr_list (omp_clauses-tile_list); fputc (')', dumpfile); } if (omp_clauses-wait_list) { - gfc_expr_list *list; fputs ( WAIT(, dumpfile); - for (list = omp_clauses-wait_list; list; list = list-next) - { - show_expr (list-expr); - if (list-next) - fputs (, , dumpfile); - } + show_expr_list (omp_clauses-wait_list); fputc (')', dumpfile); } if (omp_clauses-seq) @@ -1286,6 +1310,7 @@ show_omp_node (int level, gfc_code *c) case EXEC_OMP_PARALLEL_WORKSHARE: name = PARALLEL WORKSHARE; break; case EXEC_OMP_SECTIONS: name = SECTIONS; break; case EXEC_OMP_SINGLE: name = SINGLE; break; +case EXEC_OMP_TARGET: name = TARGET; break
Re: [Fortran][PATCH][gomp4]: Transform OpenACC loop directive
Hi Tobias! Thanks a lot for your review! On 26.03.2014 03:16, Tobias Burnus wrote: * And do concurrent also supports masks: This is doable: generate mask conditions inside of the deepest for loop (see applied patch). That will work in the most common cases but not in general. At least it is my understanding that Fortran requires that one first evaluates the mask expression before one enters the loop. That's made explicit for FORALL and DO CONCURRENT uses a forall header and does some refs to FORALL (esp. 7.2.4.2.2 and 7.2.4.2.3), but it does not state so explicitly. I missed that, thanks! I believe that there is no general way to support nested DO CONCURRENT loops with mask expressions if they must be collapsed. I mean if we have example like outer: DO CONCURRENT (i=1:5, j=1:5, i .ne. j) inner: DO CONCURRENT (i=1:5, b(i,j) .eq. 1) ! do something ENDDO inner ENDDO outer we must generate mask of inner loop inside of outer one. Hence, the loop cannot be collapsed. Is this acceptable? -- Ilmir. From b3a6435a08612951ec8a330877e002a92a9b00f4 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Tue, 1 Apr 2014 21:02:50 +0400 Subject: [PATCH] Transform OpenACC loop directive to GENERIC --- gcc/fortran/ * openmp.c (resolve_oacc_nested_loops): New check. * trans-openmp.c (gfc_trans_oacc_loop_generate_for): New helper function. (gfc_trans_oacc_loop): New function. (gfc_trans_oacc_combined_directive, gfc_trans_oacc_directive): Call it. gcc/ * omp-low.c (scan_sharing_clauses): Skip OpenACC LOOP clauses. gcc/testsuite/ * gfortran.dg/goacc/loop-3.f95: New check. * gfortran.dg/goacc/loop-4.f95: New test. * gfortran.dg/goacc/loop-tree.f95: Likewise. diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 447faf8..2be8ba6 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -2573,6 +2573,9 @@ resolve_oacc_nested_loops (gfc_code *code, gfc_code* do_code, int collapse, break; } gcc_assert (do_code-op == EXEC_DO || do_code-op == EXEC_DO_CONCURRENT); + if (do_code-op == EXEC_DO_CONCURRENT do_code-expr1) + gfc_error (OpenACC LOOP directive doesn't support DO CONCURRENT loops + with mask expressions at %L, do_code-loc); if (do_code-ext.iterator-var-ts.type != BT_INTEGER) gfc_error (!$ACC LOOP iteration variable must be of type integer at %L, do_code-loc); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 29364f4..6997625 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1571,11 +1571,258 @@ typedef struct dovar_init_d { tree init; } dovar_init; +/* Helper function to generate a single for loop. */ +static void +gfc_trans_oacc_loop_generate_for (stmtblock_t *pblock, gfc_se *se, + gfc_expr *var_expr, gfc_expr *start_expr, + gfc_expr *end_expr, gfc_expr *step_expr, + int i, tree *init, tree *cond, tree *incr, + vecdovar_init* inits) +{ + int simple = 0; + tree dovar, from, to, step, type, tmp, count = NULL_TREE; + + /* Evaluate all the expressions. */ + gfc_init_se (se, NULL); + gfc_conv_expr_lhs (se, var_expr); + gfc_add_block_to_block (pblock, se-pre); + dovar = se-expr; + type = TREE_TYPE (dovar); + gcc_assert (TREE_CODE (type) == INTEGER_TYPE); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, start_expr); + gfc_add_block_to_block (pblock, se-pre); + from = gfc_evaluate_now (se-expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, end_expr); + gfc_add_block_to_block (pblock, se-pre); + to = gfc_evaluate_now (se-expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, step_expr); + gfc_add_block_to_block (pblock, se-pre); + step = gfc_evaluate_now (se-expr, pblock); + + /* Special case simple loops. */ + if (TREE_CODE (dovar) == VAR_DECL) +{ + if (integer_onep (step)) + simple = 1; + else if (tree_int_cst_equal (step, integer_minus_one_node)) + simple = -1; +} + + /* Loop body. */ + if (simple) +{ + TREE_VEC_ELT (*init, i) = build2_v (MODIFY_EXPR, dovar, from); + /* The condition should not be folded. */ + TREE_VEC_ELT (*cond, i) = build2_loc (input_location, simple 0 + ? LE_EXPR : GE_EXPR, + boolean_type_node, dovar, to); + TREE_VEC_ELT (*incr, i) = fold_build2_loc (input_location, PLUS_EXPR, + type, dovar, step); + TREE_VEC_ELT (*incr, i) = fold_build2_loc (input_location, + MODIFY_EXPR, + type, dovar, + TREE_VEC_ELT (*incr, i)); +} + else +{ + /* STEP is not 1 or -1. Use: + for (count = 0; count (to + step - from) / step; count++) + { + dovar = from + count * step; + body; + cycle_label:; + } */ + tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from); + tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp); + tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp, + step); + tmp
Re: [Fortran][PATCH][gomp4]: Transform OpenACC loop directive
Hi Tobias! Thanks a lot for your review! I fixed my patch. On 20.03.2014 00:16, Tobias Burnus wrote: * !$acc cache() - parsing supported, but then aborting with a not-implemented error * OpenACC 2.0a additions. Am I right? Not exactly, in addition to cache directive there are also subarrays (array sections in terms of OpenMP) to be implemented from OpenACC 1.0. Also, the support of OpenACC 2.0 is not full (remain ROUTINE and ATOMIC directives and lots of clauses). For DO CONCURRENT, it is not. I always forget about this kind of loops. I think we should really consider to reject DO CONCURRENT with a not permitted; it is currently not explicitly supported by OpenACC; I think we can still worry about it, when it will be explicitly added to OpenACC. I don't think so. Issues with DO CONCURRENT: * You use code-ext.iterator-var - that's fine with DO but not with DO CONCURRENT, which uses a code-ext.forall_iterator Fixed. * Do concurrent also handles multiple variables in a single statement, such as: integer :: i, j, b(3,5) DO CONCURRENT(i=1:3, j=1:5:2) b(i, j) = -42 END DO end For each variable in the statement single for loop is generated. Example !$acc loop DO CONCURRENT(i=1:3, j=1:5:2) b(i, j) = -42 END DO become #pragma acc loop collapse(2) for (i = 1; i 3; i++) for (count.0 = 0; count.0 = 2; count.0++) { j = count.0*2 + 1; b[j-1,i-1] = -42; } * And do concurrent also supports masks: logical :: my_mask(3) integer :: i, b(3) b(i) = [5, 5, 2] my_mask = [.true., .false., .true.] do concurrent (i=1:3, b(i) == 5 .and. my_mask(i)) b(i) = -42 end do end This is doable: generate mask conditions inside of the deepest for loop (see applied patch). So, GENERIC of your example will be like: #pragma acc loop collapse(1) for (i = 1; i 3; i++) { if (b[i-1] == 5 my_mask[i-1]) { b[i-1] = -42; } } Is it OK now? -- Ilmir. From 50c0eef6f0a48fa05ab5de8924376a75fb23aca6 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Sat, 22 Mar 2014 18:54:17 +0400 Subject: [PATCH] Transform OpenACC loop directive to GENERIC --- * gcc/fortran/trans-openmp.c (gfc_trans_oacc_loop): New function. (gfc_trans_oacc_combined_directive): Call it. (gfc_trans_oacc_directive): Likewise. (gfc_trans_oacc_loop_generate_for): New helper function. (gfc_trans_oacc_loop_generate_mask_conds): Likewise. * gcc/tree-pretty-print (dump_omp_clause): Fix WORKER and VECTOR. * gcc/omp-low.c (scan_sharing_clauses): Reject OpenACC loop clauses. gcc/testsuite/gfortran.dg/goacc/ * loop-tree.f95: New test. * loop-4.f95: Likewise. diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 29364f4..e4a4f9a 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1571,11 +1571,304 @@ typedef struct dovar_init_d { tree init; } dovar_init; +/* Helper function to generate a single for loop. */ +static void +gfc_trans_oacc_loop_generate_for (stmtblock_t *pblock, gfc_se *se, + gfc_expr *var_expr, gfc_expr *start_expr, + gfc_expr *end_expr, gfc_expr *step_expr, + int i, tree *init, tree *cond, tree *incr, + vecdovar_init* inits) +{ + int simple = 0; + tree dovar, from, to, step, type, tmp, count = NULL_TREE; + + /* Evaluate all the expressions. */ + gfc_init_se (se, NULL); + gfc_conv_expr_lhs (se, var_expr); + gfc_add_block_to_block (pblock, se-pre); + dovar = se-expr; + type = TREE_TYPE (dovar); + gcc_assert (TREE_CODE (type) == INTEGER_TYPE); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, start_expr); + gfc_add_block_to_block (pblock, se-pre); + from = gfc_evaluate_now (se-expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, end_expr); + gfc_add_block_to_block (pblock, se-pre); + to = gfc_evaluate_now (se-expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, step_expr); + gfc_add_block_to_block (pblock, se-pre); + step = gfc_evaluate_now (se-expr, pblock); + + /* Special case simple loops. */ + if (TREE_CODE (dovar) == VAR_DECL) +{ + if (integer_onep (step)) + simple = 1; + else if (tree_int_cst_equal (step, integer_minus_one_node)) + simple = -1; +} + + /* Loop body. */ + if (simple) +{ + TREE_VEC_ELT (*init, i) = build2_v (MODIFY_EXPR, dovar, from); + /* The condition should not be folded. */ + TREE_VEC_ELT (*cond, i) = build2_loc (input_location, simple 0 + ? LE_EXPR : GE_EXPR, + boolean_type_node, dovar, to); + TREE_VEC_ELT (*incr, i) = fold_build2_loc (input_location, PLUS_EXPR, + type, dovar, step); + TREE_VEC_ELT (*incr, i) = fold_build2_loc (input_location, + MODIFY_EXPR, + type, dovar, + TREE_VEC_ELT (*incr, i)); +} + else +{ + /* STEP is not 1 or -1. Use: + for (count = 0; count (to + step - from) / step; count++) + { + dovar = from + count * step; + body; + cycle_label
Re: [PATCH] [gomp4] Initial support of OpenACC loop directive in C front-end.
Hi Thomas! On 19.03.2014 23:35, Thomas Schwinge wrote: Do you intend to support loop constructs that are not nested in a parallel or kernels construct? As I'm reading it, the specification is not clear on this. (I guess I'll raise this question with the OpenACC guys.) Yes, I do. There are three reasons to support OpenACC loop directive without enclosing construct: 1) The spec doesn't require the directive to be inside of a construct. 2) PGI compiler does support this. 3) GCC OpenMP implementation supports loop construct without parallel. However, I agree that there no sense to use OpenACC loop without a construct. So, should there be a warning, perhaps? -- Ilmir.
Re: [PATCH] [gomp4] Initial support of OpenACC loop directive in C front-end.
Hi Thomas! On 20.03.2014 14:21, Thomas Schwinge wrote: I just realized that this is wrong usage of the dg-excess-errors directive, for this one will absorb *all* remaining errors, whereas you just wanted to mask out any »sorry, unimplemented: directive not yet implemented« ones. Sorry for that. Next time I will more precise. OK to fix as follows? Sure. Thanks! -- Ilmir.
Re: [PATCH 4/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
Hi Thomas! On 20.03.2014 14:22, Thomas Schwinge wrote: As in http://news.gmane.org/find-root.php?message_id=%3C87mwglf9vq.fsf%40schwinge.name%3E, this is wrong usage of the dg-excess-errors directive, for this one will absorb *all* remaining errors, whereas you just wanted to mask out any »sorry, unimplemented: [...]« ones. OK to fix as follows? Sure. Thanks! -- Ilmir.
[Fortran][PATCH][gomp4]: Transform OpenACC loop directive
Hi Tobias! This patch implements transformation of OpenACC loop directive from Fortran AST to GENERIC. Successfully bootstrapped and tested with no new regressions on x86_64-unknown-linux-gnu. OK for gomp4 branch? -- Ilmir. From de2dd5ba0c48500e8e9084bd46cbfac2f21352fe Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Wed, 19 Mar 2014 15:12:36 +0400 Subject: [PATCH] Transform OpenACC loop directive from fortran AST to GENERIC --- * gcc/fortran/trans-openmp.c (gfc_trans_oacc_loop): New function. (gfc_trans_oacc_combined_directive): Call it. (gfc_trans_oacc_directive): Likewise. * gcc/tree-pretty-print (dump_omp_clause): Fix WORKER and VECTOR. * gcc/testsuite/gfortran.dg/goacc/loop-tree.f95: New test. diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 29364f4..cb7c970 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1571,11 +1571,181 @@ typedef struct dovar_init_d { tree init; } dovar_init; + +static tree +gfc_trans_oacc_loop (gfc_code *code, stmtblock_t *pblock, + gfc_omp_clauses *loop_clauses) +{ + gfc_se se; + tree dovar, stmt, from, to, step, type, init, cond, incr; + tree count = NULL_TREE, cycle_label, tmp, omp_clauses; + stmtblock_t block; + stmtblock_t body; + gfc_omp_clauses *clauses = code-ext.omp_clauses; + int i, collapse = clauses-collapse; + vecdovar_init inits = vNULL; + dovar_init *di; + unsigned ix; + + if (collapse = 0) +collapse = 1; + + code = code-block-next; + gcc_assert (code-op == EXEC_DO || code-op == EXEC_DO_CONCURRENT); + + init = make_tree_vec (collapse); + cond = make_tree_vec (collapse); + incr = make_tree_vec (collapse); + + if (pblock == NULL) +{ + gfc_start_block (block); + pblock = block; +} + + omp_clauses = gfc_trans_omp_clauses (pblock, loop_clauses, code-loc); + + for (i = 0; i collapse; i++) +{ + int simple = 0; + + /* Evaluate all the expressions in the iterator. */ + gfc_init_se (se, NULL); + gfc_conv_expr_lhs (se, code-ext.iterator-var); + gfc_add_block_to_block (pblock, se.pre); + dovar = se.expr; + type = TREE_TYPE (dovar); + gcc_assert (TREE_CODE (type) == INTEGER_TYPE); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, code-ext.iterator-start); + gfc_add_block_to_block (pblock, se.pre); + from = gfc_evaluate_now (se.expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, code-ext.iterator-end); + gfc_add_block_to_block (pblock, se.pre); + to = gfc_evaluate_now (se.expr, pblock); + + gfc_init_se (se, NULL); + gfc_conv_expr_val (se, code-ext.iterator-step); + gfc_add_block_to_block (pblock, se.pre); + step = gfc_evaluate_now (se.expr, pblock); + + /* Special case simple loops. */ + if (TREE_CODE (dovar) == VAR_DECL) + { + if (integer_onep (step)) + simple = 1; + else if (tree_int_cst_equal (step, integer_minus_one_node)) + simple = -1; + } + + /* Loop body. */ + if (simple) + { + TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from); + /* The condition should not be folded. */ + TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple 0 + ? LE_EXPR : GE_EXPR, + boolean_type_node, dovar, to); + TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR, + type, dovar, step); + TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, + MODIFY_EXPR, + type, dovar, + TREE_VEC_ELT (incr, i)); + } + else + { + /* STEP is not 1 or -1. Use: + for (count = 0; count (to + step - from) / step; count++) + { + dovar = from + count * step; + body; + cycle_label:; + } */ + tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from); + tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp); + tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp, + step); + tmp = gfc_evaluate_now (tmp, pblock); + count = gfc_create_var (type, count); + TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count, + build_int_cst (type, 0)); + /* The condition should not be folded. */ + TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR, + boolean_type_node, + count, tmp); + TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR, + type, count, + build_int_cst (type, 1)); + TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, + MODIFY_EXPR, type, count, + TREE_VEC_ELT (incr, i)); + + /* Initialize DOVAR. */ + tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step); + tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp); + dovar_init e = {dovar, tmp}; + inits.safe_push (e); + } + + if (i + 1 collapse) + code = code-block-next; +} + + if (pblock != block) +{ + pushlevel
Re: [C++ PATCH] [gomp4] Initial OpenACC support to C++ front-end
Ping. On 13.03.2014 21:05, Ilmir Usmanov wrote: On 07.03.2014 15:37, Ilmir Usmanov wrote: Hi Thomas! I prepared simple patch to add support of OpenACC data, kernels and parallel constructs to C++ FE. It adds support of data clauses too. OK to gomp4 branch? Fixed subject: changed file extensions of tests and fixed comments. OK to gomp4 branch? -- Ilmir.
[PATCH] [gomp4] Initial support of OpenACC loop directive in C front-end.
Hi Thomas! This patch introduces support of OpenACC loop directive (and combined directives) in C front-end up to GENERIC. Currently no clause is allowed. This patch is necessary to finish implementation of OpenACC 1.0 in fortran front-end. As you know, OpenACC fortran implementation does parsing and resolving of loop directive but doesn't transformation to GENERIC. Bootstraped and tested with no new regressions on x86_64-unknown-linux-gnu. OK for gomp4 branch? -- Ilmir. From 1adbb9d2e504c7acac8be89b053fa677cf285b42 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Tue, 18 Mar 2014 16:13:14 +0400 Subject: [PATCH] Initial support of OpenACC loop --- Initial support of OpenACC loop directive in C front-end. gcc/ * tree.def (OACC_LOOP): New tree code. * tree-pretty-print.c (dump_generic_node): Show it. * tree.h (OACC_KERNELS_COMBINED, OACC_PARALLEL_COMBINED): New macros. * c-family/c-pragma.c (oacc_pragmas): Add loop directive. * c-family/c-pragma.h (enum pragma_kind): Likewise. * c/c-parser.c (c_parser_oacc_loop): New function. (c_parser_oacc_kernels): Parse combined directive. (c_parser_oacc_parallel): Likewise. (c_parser_omp_construct): Parse loop directive. * doc/generic.texi: Document loop directive. * gimplify.c (is_gimple_stmt, gimplify_expr): Stub gimplification of loop directive and combined directives. * testsuite/c-c++-common/goacc/loop-1.c: New test. diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index c8baba4..f99b087 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -1172,6 +1172,7 @@ static const struct omp_pragma_def oacc_pragmas[] = { { data, PRAGMA_OACC_DATA }, { kernels, PRAGMA_OACC_KERNELS }, { parallel, PRAGMA_OACC_PARALLEL }, + { loop, PRAGMA_OACC_LOOP }, }; static const struct omp_pragma_def omp_pragmas[] = { { atomic, PRAGMA_OMP_ATOMIC }, diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h index d55a511..16c74a9 100644 --- a/gcc/c-family/c-pragma.h +++ b/gcc/c-family/c-pragma.h @@ -30,6 +30,7 @@ typedef enum pragma_kind { PRAGMA_OACC_DATA, PRAGMA_OACC_KERNELS, PRAGMA_OACC_PARALLEL, + PRAGMA_OACC_LOOP, PRAGMA_OMP_ATOMIC, PRAGMA_OMP_BARRIER, PRAGMA_OMP_CANCEL, diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 3d8c0de..2300c6c 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11404,6 +11404,8 @@ c_parser_oacc_data (location_t loc, c_parser *parser) return stmt; } +static tree c_parser_oacc_loop (location_t, c_parser *, char *); + /* OpenACC 2.0: # pragma acc kernels oacc-kernels-clause[optseq] new-line structured-block @@ -11424,12 +11426,28 @@ c_parser_oacc_data (location_t loc, c_parser *parser) | (OMP_CLAUSE_MASK_1 PRAGMA_OMP_CLAUSE_PRESENT_OR_CREATE) ) static tree -c_parser_oacc_kernels (location_t loc, c_parser *parser) +c_parser_oacc_kernels (location_t loc, c_parser *parser, char *p_name) { - tree stmt, clauses, block; + tree stmt, clauses = NULL_TREE, block; + + strcat (p_name, kernels); + + if (c_parser_next_token_is (parser, CPP_NAME)) +{ + const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)-value); + if (strcmp (p, loop) == 0) + { + c_parser_consume_token (parser); + block = c_begin_omp_parallel (); + c_parser_oacc_loop (loc, parser, p_name); + stmt = c_finish_oacc_kernels (loc, clauses, block); + OACC_KERNELS_COMBINED (stmt) = 1; + return stmt; + } +} clauses = c_parser_oacc_all_clauses (parser, OACC_KERNELS_CLAUSE_MASK, - #pragma acc kernels); + p_name); block = c_begin_omp_parallel (); add_stmt (c_parser_omp_structured_block (parser)); @@ -11459,12 +11477,28 @@ c_parser_oacc_kernels (location_t loc, c_parser *parser) | (OMP_CLAUSE_MASK_1 PRAGMA_OMP_CLAUSE_PRESENT_OR_CREATE) ) static tree -c_parser_oacc_parallel (location_t loc, c_parser *parser) +c_parser_oacc_parallel (location_t loc, c_parser *parser, char *p_name) { - tree stmt, clauses, block; + tree stmt, clauses = NULL_TREE, block; + + strcat (p_name, parallel); + + if (c_parser_next_token_is (parser, CPP_NAME)) +{ + const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)-value); + if (strcmp (p, loop) == 0) + { + c_parser_consume_token (parser); + block = c_begin_omp_parallel (); + c_parser_oacc_loop (loc, parser, p_name); + stmt = c_finish_oacc_parallel (loc, clauses, block); + OACC_PARALLEL_COMBINED (stmt) = 1; + return stmt; + } +} clauses = c_parser_oacc_all_clauses (parser, OACC_PARALLEL_CLAUSE_MASK, - #pragma acc parallel); + p_name); block = c_begin_omp_parallel (); add_stmt (c_parser_omp_structured_block (parser)); @@ -12243,6 +12277,32 @@ omp_split_clauses (location_t loc, enum tree_code code, cclauses[i] = c_finish_omp_clauses (cclauses[i]); } +/* OpenACC 2.0: + # pragma acc loop oacc-loop-clause[optseq] new-line + structured-block + + LOC is the location of the #pragma token
Re: [PATCH] [gomp4] Initial support of OpenACC loop directive in C front-end.
Committed as r208649. -- Ilmir.
Re: [PATCH 1/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
Committed as r208533. -- Ilmir.
Re: [PATCH 1/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
Hi Thomas! On 13.03.2014 15:38, Thomas Schwinge wrote: Hi Ilmir! On Thu, 13 Mar 2014 13:34:54 +0400, Ilmir Usmanov i.usma...@samsung.com wrote: Committed as r208533. Yay! \o/ Thanks! Yay indeed. And thanks a lot for your comments. The following change seems the right thing to do -- but why doesn't the current code trigger a GCC ICE due to a failing subcode check? (At least I thought you had test cases exercising the respective OpenACC vector clauses?) Can you please check that? If it's just missing a test case, feel free to commit that together with my patch. Unfortunally, I can't check this using a test right now, since OpenACC loop directive is not implemented yet. The following cleanup should be fine to check in, or is there a reason for using OMP_WAIT_EXPR instead of OMP_CLAUSE_WAIT_EXPR? No, there is no reason for using OMP_WAIT_EXPR. Thanks! -- Ilmir.
Re: [PATCH 1/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
On 13.03.2014 16:19, Ilmir Usmanov wrote: The following change seems the right thing to do -- but why doesn't the current code trigger a GCC ICE due to a failing subcode check? (At least I thought you had test cases exercising the respective OpenACC vector clauses?) Can you please check that? If it's just missing a test case, feel free to commit that together with my patch. Unfortunally, I can't check this using a test right now, since OpenACC loop directive is not implemented yet. The following cleanup should be fine to check in, or is there a reason for using OMP_WAIT_EXPR instead of OMP_CLAUSE_WAIT_EXPR? No, there is no reason for using OMP_WAIT_EXPR. Thanks! Committed as r208541. -- Ilmir.
[C++ PATCH] [gomp4] Initial OpenACC support to C++ front-end
On 07.03.2014 15:37, Ilmir Usmanov wrote: Hi Thomas! I prepared simple patch to add support of OpenACC data, kernels and parallel constructs to C++ FE. It adds support of data clauses too. OK to gomp4 branch? Fixed subject: changed file extensions of tests and fixed comments. OK to gomp4 branch? -- Ilmir. From 8368b5196c1201401e1f8301107f11c9e6f064b1 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 13 Mar 2014 20:59:34 +0400 Subject: [PATCH] Initial OpenACC support to C++ FE --- Initial OpenACC support to C++ front-end: parallel, kernels and data construct with data clauses. gcc/cp/ * cp-tree.h (finish_oacc_data): New function prototype. (finish_oacc_kernels, finish_oacc_parallel): Likewise. * parser.c (cp_parser_omp_clause_name): Support data clauses. (cp_parser_oacc_data_clause): New function. (cp_parser_oacc_data_clause_deviceptr, cp_parser_oacc_all_clauses, cp_parser_oacc_data, cp_parser_oacc_kernels, cp_parser_oacc_parallel): Likewise. (OACC_DATA_CLAUSE_MASK): New define. (OACC_KERNELS_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK): Likewise. (cp_parser_omp_construct, cp_parser_pragma): Support OpenACC directives. * semantics.c (finish_oacc_data): New function. (finish_oacc_kernels, finish_oacc_parallel): Likewise. * gcc/testsuite/c-c++-common/goacc/deviceptr-1.c: Move to ... * gcc/testsuite/gcc.dg/goacc/deviceptr-1.c ... here. * gcc/testsuite/g++.dg/goacc/goacc.exp: New test directory. * gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp: Likewise. gcc/testsuite/g++.dg/goacc/ * deviceptr-1.cpp: New test. * sb-1.cpp: Likewise. * sb-2.cpp: Likewise. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8ec7d6a..9b966d2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5825,6 +5825,9 @@ extern tree finish_omp_clauses (tree); extern void finish_omp_threadprivate (tree); extern tree begin_omp_structured_block (void); extern tree finish_omp_structured_block (tree); +extern tree finish_oacc_data (tree, tree); +extern tree finish_oacc_kernels (tree, tree); +extern tree finish_oacc_parallel (tree, tree); extern tree begin_omp_parallel (void); extern tree finish_omp_parallel (tree, tree); extern tree begin_omp_task (void); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8c167c7..94d9e22 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -26935,16 +26935,26 @@ cp_parser_omp_clause_name (cp_parser *parser) case 'c': if (!strcmp (collapse, p)) result = PRAGMA_OMP_CLAUSE_COLLAPSE; + else if (!strcmp (copy, p)) + result = PRAGMA_OMP_CLAUSE_COPY; else if (!strcmp (copyin, p)) result = PRAGMA_OMP_CLAUSE_COPYIN; + else if (!strcmp (copyout, p)) + result = PRAGMA_OMP_CLAUSE_COPYOUT; else if (!strcmp (copyprivate, p)) result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; + else if (!strcmp (create, p)) + result = PRAGMA_OMP_CLAUSE_CREATE; break; case 'd': - if (!strcmp (depend, p)) + if (!strcmp (delete, p)) + result = PRAGMA_OMP_CLAUSE_DELETE; + else if (!strcmp (depend, p)) result = PRAGMA_OMP_CLAUSE_DEPEND; else if (!strcmp (device, p)) result = PRAGMA_OMP_CLAUSE_DEVICE; + else if (!strcmp (deviceptr, p)) + result = PRAGMA_OMP_CLAUSE_DEVICEPTR; else if (!strcmp (dist_schedule, p)) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; break; @@ -26993,6 +27003,22 @@ cp_parser_omp_clause_name (cp_parser *parser) case 'p': if (!strcmp (parallel, p)) result = PRAGMA_OMP_CLAUSE_PARALLEL; + else if (!strcmp (present, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT; + else if (!strcmp (present_or_copy, p) + || !strcmp (pcopy, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPY; + else if (!strcmp (present_or_copyin, p) + || !strcmp (pcopyin, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYIN; + else if (!strcmp (present_or_copyout, p) + || !strcmp (pcopyout, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYOUT; + else if (!strcmp (present_or_create, p) + || !strcmp (pcreate, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_CREATE; + else if (!strcmp (private, p)) + result = PRAGMA_OMP_CLAUSE_PRIVATE; else if (!strcmp (proc_bind, p)) result = PRAGMA_OMP_CLAUSE_PROC_BIND; break; @@ -27200,6 +27226,111 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list) return list; } +/* OpenACC 2.0: + copy ( variable-list ) + copyin ( variable-list ) + copyout ( variable-list ) + create ( variable-list ) + delete ( variable-list ) + present ( variable-list ) + present_or_copy ( variable-list ) + pcopy ( variable-list ) + present_or_copyin ( variable-list ) + pcopyin ( variable-list ) + present_or_copyout ( variable-list ) + pcopyout ( variable-list ) + present_or_create ( variable-list ) + pcreate ( variable-list ) */ + +static tree +cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind, + tree list) +{ + enum
Re: [PATCH 1/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
Hi Tobias! Thanks a lot for your review! !$acc loop outer_loop: do i = 1, n inner_loop: do j = 1,m ! ... cycle outer_loop exit outer_loop end do inner_loop end do outer_loop That's a new Fortran 2008 feature that CYCLE and EXIT can leave the inner DO loop. I added the following to test suite: !$acc loop outer_loop: do i = 1, 5 inner_loop: do j = 1,5 if (i .eq. j) cycle outer_loop if (i .ne. j) exit outer_loop ! { dg-error EXIT statement } end do inner_loop end do outer_loop outer_loop1: do i = 1, 5 !$acc loop inner_loop1: do j = 1,5 if (i .eq. j) cycle outer_loop1 ! { dg-error CYCLE statement } end do inner_loop1 end do outer_loop1 !$acc loop collapse(2) outer_loop2: do i = 1, 5 inner_loop2: do j = 1,5 if (i .eq. j) cycle outer_loop2 ! { dg-error CYCLE statement } if (i .ne. j) exit outer_loop2 ! { dg-error EXIT statement } end do inner_loop2 end do outer_loop2 All cases pass. The second one passes due to check of structured blocks: if (o != NULL) { gfc_error (%s statement at %C leaving OpenMP structured block, gfc_ascii_statement (st)); return MATCH_ERROR; } So, I needed to change error message. Also I fixed checks of polymofphic type and indentation. OK for gomp4 branch? -- Ilmir.
Re: [PATCH 2/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- matching and resolving. * gcc/fortran/openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses. (gfc_free_expr_list): New function to clear expression list. (match_oacc_expr_list): New function to match expression list. (match_oacc_clause_gang): New function to match OpenACC 2.0 gang clauses. (OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_OACC_COPYIN, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New clauses. (OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES, OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES, OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES, OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES, OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES): New defines. (gfc_match_oacc_parallel_loop, gfc_match_oacc_parallel, gfc_match_oacc_kernels_loop, gfc_match_oacc_kernels, gfc_match_oacc_data, gfc_match_oacc_host_data, gfc_match_oacc_loop, gfc_match_oacc_declare, gfc_match_oacc_update, gfc_match_oacc_enter_data, gfc_match_oacc_exit_data, gfc_match_oacc_wait, gfc_match_oacc_cache, oacc_is_loop, check_symbol_not_pointer, resolve_oacc_scalar_int_expr, resolve_oacc_positive_int_expr, check_array_not_assumed, resolve_oacc_data_clauses, resolve_oacc_deviceptr_clause, oacc_is_parallel, oacc_is_kernels, omp_code_to_statement, oacc_code_to_statement, resolve_oacc_directive_inside_omp_region, resolve_omp_directive_inside_oacc_region, resolve_oacc_nested_loops, resolve_oacc_params_in_parallel, resolve_oacc_loop_blocks, gfc_resolve_oacc_blocks, resolve_oacc_loop, resolve_oacc_cache, resolve_oacc_wait, gfc_resolve_oacc_declare, gfc_resolve_oacc_directive): New functions. (resolve_omp_clauses): Resolve also OpenACC clauses. (gfc_resolve_omp_directive): Check for enclosing OpenACC region. From b783a60855f6649b6b8b440f177c1076f9af6521 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 7 Mar 2014 14:33:17 +0400 Subject: [PATCH 2/4] OpenACC Fortran FE -- part 2 --- gcc/fortran/openmp.c | 1222 +- 1 file changed, 1200 insertions(+), 22 deletions(-) diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index dff3ab1..e37c4c2 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -69,11 +69,37 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c-final_expr); gfc_free_expr (c-num_threads); gfc_free_expr (c-chunk_size); + gfc_free_expr (c-async_expr); + gfc_free_expr (c-gang_expr); + gfc_free_expr (c-worker_expr); + gfc_free_expr (c-vector_expr); + gfc_free_expr (c-num_gangs_expr); + gfc_free_expr (c-num_workers_expr); + gfc_free_expr (c-vector_length_expr); + gfc_free_expr (c-non_clause_wait_expr); + for (i = 0; i OMP_LIST_NUM; i++) gfc_free_namelist (c-lists[i]); + + gfc_free_expr_list (c-wait_list); + gfc_free_expr_list (c-tile_list); + free (c); } +/* Free expression list. */ +void +gfc_free_expr_list (gfc_expr_list *list) +{ + gfc_expr_list *n; + + for (; list; list = n) +{ + n = list-next; + free (list); +} +} + /* Match a variable/common block list and construct a namelist from it. */ static match @@ -169,6 +195,87 @@ cleanup: return MATCH_ERROR; } +static match +match_oacc_expr_list (const char *str, gfc_expr_list **list, bool allow_asterisk) +{ + gfc_expr_list *head, *tail, *p; + locus old_loc; + gfc_expr *expr; + match m; + + head = tail = NULL; + + old_loc = gfc_current_locus; + + m = gfc_match (str); + if (m != MATCH_YES) +return m; + + for (;;) +{ + m = gfc_match_expr (expr); + if (m == MATCH_YES || allow_asterisk) + { + p = gfc_get_expr_list (); + if (head == NULL) + head = tail = p; + else + { + tail-next = p; + tail = tail-next; + } + if (m == MATCH_YES) + tail-expr = expr; + else if (gfc_match ( *) != MATCH_YES) + goto syntax; + goto next_item; + } + if (m == MATCH_ERROR) + goto cleanup; + goto syntax; + +next_item: + if (gfc_match_char (')') == MATCH_YES) + break; + if (gfc_match_char (',') != MATCH_YES) + goto syntax; +} + + while (*list) +list = (*list)-next; + + *list = head; + return MATCH_YES; + +syntax: + gfc_error (Syntax error in OpenACC expression list at %C); + +cleanup: + gfc_free_expr_list (head); + gfc_current_locus = old_loc
Re: [PATCH 3/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- translation to GENERIC. gcc/fortran/ * trans-decl.c (gfc_generate_function_code): Insert OACC_DECLARE GENERIC node. * trans-openmp.c (gfc_convert_expr_to_tree): New helper function. (gfc_trans_omp_array_reduction): Support also OpenACC. Add parameter. (gfc_trans_omp_reduction_list): Update. (gfc_trans_oacc_construct): New transform function. (gfc_trans_omp_map_clause_list): Likewise. (gfc_trans_oacc_executable_directive): Likewise. (gfc_trans_oacc_combined_directive, gfc_trans_oacc_declare): Likewise. (gfc_trans_oacc_directive): Use them. (gfc_trans_oacc_loop): Stub. (gfc_trans_omp_clauses): Transform OpenACC clauses. * trans-stmt.h (gfc_trans_oacc_directive): New function prototype. (gfc_trans_oacc_declare): Likewise. * trans.c (trans_code): Transform also OpenACC directives. From 70dca7f32b50e762f1295a2054bb484ef7fbb42e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 7 Mar 2014 14:33:47 +0400 Subject: [PATCH 3/4] OpenACC Fortran FE -- part 3 --- gcc/fortran/trans-decl.c | 7 + gcc/fortran/trans-openmp.c | 357 + gcc/fortran/trans-stmt.c | 8 + gcc/fortran/trans-stmt.h | 4 + gcc/fortran/trans.c| 15 ++ 5 files changed, 391 insertions(+) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 9c86653..ad26ef8 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -5606,6 +5606,13 @@ gfc_generate_function_code (gfc_namespace * ns) if ((gfc_option.rtcheck GFC_RTCHECK_BOUNDS) !sym-attr.is_bind_c) add_argument_checking (body, sym); + /* Generate !$ACC DECLARE directive. */ + if (ns-oacc_declare_clauses) +{ + tree tmp = gfc_trans_oacc_declare (body, ns); + gfc_add_expr_to_block (body, tmp); +} + tmp = gfc_trans_code (ns-code); gfc_add_expr_to_block (body, tmp); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 41020a8..a1abd66 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -767,6 +767,40 @@ gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list, } static tree +gfc_trans_omp_map_clause_list (enum omp_clause_map_kind kind, + gfc_namelist *namelist, tree list) +{ + for (; namelist != NULL; namelist = namelist-next) +if (namelist-sym-attr.referenced) + { + tree t = gfc_trans_omp_variable (namelist-sym); + if (t != error_mark_node) + { + tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP); + OMP_CLAUSE_DECL (node) = t; + OMP_CLAUSE_MAP_KIND (node) = kind; + list = gfc_trans_add_clause (node, list); + } + } + return list; +} + +static inline tree +gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr) +{ + gfc_se se; + tree result; + + gfc_init_se (se, NULL ); + gfc_conv_expr (se, expr); + gfc_add_block_to_block (block, se.pre); + result = gfc_evaluate_now (se.expr, block); + gfc_add_block_to_block (block, se.post); + + return result; +} + +static tree gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, locus where) { @@ -834,6 +868,51 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, where); continue; } + if (list = OMP_LIST_DATA_CLAUSE_FIRST + list = OMP_LIST_DATA_CLAUSE_LAST) + { + enum omp_clause_map_kind kind; + switch (list) + { + case OMP_LIST_COPY: + kind = OMP_CLAUSE_MAP_FORCE_TOFROM; + break; + case OMP_LIST_OACC_COPYIN: + kind = OMP_CLAUSE_MAP_FORCE_TO; + break; + case OMP_LIST_COPYOUT: + kind = OMP_CLAUSE_MAP_FORCE_FROM; + break; + case OMP_LIST_CREATE: + kind = OMP_CLAUSE_MAP_FORCE_ALLOC; + break; + case OMP_LIST_DELETE: + kind = OMP_CLAUSE_MAP_FORCE_DEALLOC; + break; + case OMP_LIST_PRESENT: + kind = OMP_CLAUSE_MAP_FORCE_PRESENT; + break; + case OMP_LIST_PRESENT_OR_COPY: + kind = OMP_CLAUSE_MAP_TOFROM; + break; + case OMP_LIST_PRESENT_OR_COPYIN: + kind = OMP_CLAUSE_MAP_TO; + break; + case OMP_LIST_PRESENT_OR_COPYOUT: + kind = OMP_CLAUSE_MAP_FROM; + break; + case OMP_LIST_PRESENT_OR_CREATE: + kind = OMP_CLAUSE_MAP_ALLOC; + break; + case OMP_LIST_DEVICEPTR: + kind = OMP_CLAUSE_MAP_FORCE_DEVICEPTR; + break; + default: + gcc_unreachable (); + } + omp_clauses = gfc_trans_omp_map_clause_list (kind, n, omp_clauses); + continue; + } switch (list) { case OMP_LIST_PRIVATE: @@ -853,6 +932,21 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, goto add_clause; case OMP_LIST_COPYPRIVATE: clause_code = OMP_CLAUSE_COPYPRIVATE; + goto add_clause; + case OMP_LIST_USE_DEVICE: + clause_code = OMP_CLAUSE_USE_DEVICE; + goto add_clause; + case OMP_LIST_DEVICE_RESIDENT: + clause_code
[PATCH] [gomp4] Initial OpenACC support to C++ front-end
Hi Thomas! I prepared simple patch to add support of OpenACC data, kernels and parallel constructs to C++ FE. It adds support of data clauses too. OK to gomp4 branch? -- Ilmir.
Re: [PATCH 2/2] [gomp4] Initial OpenACC support to C++ front-end
Initial OpenACC support to C++ front-end -- tests * gcc/testsuite/c-c++-common/goacc/deviceptr-1.c: Move to ... * gcc/testsuite/gcc.dg/goacc/deviceptr-1.c ... here. * gcc/testsuite/g++.dg/goacc/goacc.exp: New test directory. * gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp: Likewise. gcc/testsuite/g++.dg/goacc/ * deviceptr-1.cpp: New test. * sb-1.cpp: Likewise. * sb-2.cpp: Likewise. From c7cbe59516a1c21cfbad48863311e6d5389c Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 7 Mar 2014 15:12:30 +0400 Subject: [PATCH 2/2] Initial OpenACC support to C++ front-end -- tests --- gcc/testsuite/c-c++-common/goacc/deviceptr-1.c | 64 - gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp | 39 gcc/testsuite/g++.dg/goacc/deviceptr-1.cpp | 65 ++ gcc/testsuite/g++.dg/goacc/goacc.exp | 38 +++ gcc/testsuite/g++.dg/goacc/sb-1.cpp| 59 +++ gcc/testsuite/g++.dg/goacc/sb-2.cpp| 25 ++ gcc/testsuite/gcc.dg/goacc/deviceptr-1.c | 64 + 7 files changed, 290 insertions(+), 64 deletions(-) delete mode 100644 gcc/testsuite/c-c++-common/goacc/deviceptr-1.c create mode 100644 gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp create mode 100644 gcc/testsuite/g++.dg/goacc/deviceptr-1.cpp create mode 100644 gcc/testsuite/g++.dg/goacc/goacc.exp create mode 100644 gcc/testsuite/g++.dg/goacc/sb-1.cpp create mode 100644 gcc/testsuite/g++.dg/goacc/sb-2.cpp create mode 100644 gcc/testsuite/gcc.dg/goacc/deviceptr-1.c diff --git a/gcc/testsuite/c-c++-common/goacc/deviceptr-1.c b/gcc/testsuite/c-c++-common/goacc/deviceptr-1.c deleted file mode 100644 index 1ac63bd..000 --- a/gcc/testsuite/c-c++-common/goacc/deviceptr-1.c +++ /dev/null @@ -1,64 +0,0 @@ -void -fun1 (void) -{ -#pragma acc parallel deviceptr(u) /* { dg-error 'u' undeclared } */ - ; -#pragma acc kernels deviceptr(u[0:4]) /* { dg-error expected '\\\)' before '\\\[' token } */ - ; - -#pragma acc data deviceptr(fun1) /* { dg-error 'fun1' is not a variable } */ - ; -#pragma acc parallel deviceptr(fun1[2:5]) - /* { dg-error 'fun1' is not a variable not a variable { target *-*-* } 11 } */ - /* { dg-error expected '\\\)' before '\\\[' token array { target *-*-* } 11 } */ - ; - - int i; -#pragma acc kernels deviceptr(i) /* { dg-error 'i' is not a pointer variable } */ - ; -#pragma acc data deviceptr(i[0:4]) - /* { dg-error 'i' is not a pointer variable not a pointer variable { target *-*-* } 19 } */ - /* { dg-error expected '\\\)' before '\\\[' token array { target *-*-* } 19 } */ - ; - - float fa[10]; -#pragma acc parallel deviceptr(fa) /* { dg-error 'fa' is not a pointer variable } */ - ; -#pragma acc kernels deviceptr(fa[1:5]) - /* { dg-error 'fa' is not a pointer variable not a pointer variable { target *-*-* } 27 } */ - /* { dg-error expected '\\\)' before '\\\[' token array { target *-*-* } 27 } */ - ; - - float *fp; -#pragma acc data deviceptr(fp) - ; -#pragma acc parallel deviceptr(fp[0:4]) /* { dg-error expected '\\\)' before '\\\[' token } */ - ; -} - -void -fun2 (void) -{ - int i; - float *fp; -#pragma acc kernels deviceptr(fp,u,fun2,i,fp) - /* { dg-error 'u' undeclared u undeclared { target *-*-* } 44 } */ - /* { dg-error 'fun2' is not a variable fun2 not a variable { target *-*-* } 44 } */ - /* { dg-error 'i' is not a pointer variable i not a pointer variable { target *-*-* } 44 } */ - /* { dg-error 'fp' appears more than once in map clauses fp more than once { target *-*-* } 44 } */ - ; -} - -void -fun3 (void) -{ - float *fp; -#pragma acc data deviceptr(fp,fp) /* { dg-error 'fp' appears more than once in map clauses } */ - ; -#pragma acc parallel deviceptr(fp) deviceptr(fp) /* { dg-error 'fp' appears more than once in map clauses } */ - ; -#pragma acc kernels copy(fp) deviceptr(fp) /* { dg-error 'fp' appears more than once in map clauses } */ - ; -} - -/* { dg-prune-output sorry, unimplemented: data clause not yet implemented } */ diff --git a/gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp b/gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp new file mode 100644 index 000..0658b4a --- /dev/null +++ b/gcc/testsuite/g++.dg/goacc-gomp/goacc-gomp.exp @@ -0,0 +1,39 @@ +# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC
Re: [PATCH 1/2] [gomp4] Initial OpenACC support to C++ front-end
Initial OpenACC support to C++ front-end: parallel, kernels and data construct with data clauses. gcc/cp/ * cp-tree.h (finish_oacc_data): New function prototype. (finish_oacc_kernels, finish_oacc_parallel): Likewise. * parser.c (cp_parser_omp_clause_name): Support data clauses. (cp_parser_oacc_data_clause): New function. (cp_parser_oacc_data_clause_deviceptr, cp_parser_oacc_all_clauses, cp_parser_oacc_data, cp_parser_oacc_kernels, cp_parser_oacc_parallel): Likewise. (OACC_DATA_CLAUSE_MASK): New define. (OACC_KERNELS_CLAUSE_MASK, OACC_PARALLEL_CLAUSE_MASK): Likewise. (cp_parser_omp_construct, cp_parser_pragma): Support OpenACC directives. * semantics.c (finish_oacc_data): New function. (finish_oacc_kernels, finish_oacc_parallel): Likewise. From 422e398c375ce6a62691bfc4cc9dd71c38f87b40 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 7 Mar 2014 15:09:47 +0400 Subject: [PATCH 1/2] Initial OpenACC support to C++ front-end --- gcc/cp/cp-tree.h | 3 + gcc/cp/parser.c| 347 - gcc/cp/semantics.c | 54 + 3 files changed, 403 insertions(+), 1 deletion(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7681b27..3d734ac 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5822,6 +5822,9 @@ extern tree finish_omp_clauses (tree); extern void finish_omp_threadprivate (tree); extern tree begin_omp_structured_block (void); extern tree finish_omp_structured_block (tree); +extern tree finish_oacc_data (tree, tree); +extern tree finish_oacc_kernels (tree, tree); +extern tree finish_oacc_parallel (tree, tree); extern tree begin_omp_parallel (void); extern tree finish_omp_parallel (tree, tree); extern tree begin_omp_task (void); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ff481ab..ba9cda65 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -26868,16 +26868,26 @@ cp_parser_omp_clause_name (cp_parser *parser) case 'c': if (!strcmp (collapse, p)) result = PRAGMA_OMP_CLAUSE_COLLAPSE; + else if (!strcmp (copy, p)) + result = PRAGMA_OMP_CLAUSE_COPY; else if (!strcmp (copyin, p)) result = PRAGMA_OMP_CLAUSE_COPYIN; + else if (!strcmp (copyout, p)) + result = PRAGMA_OMP_CLAUSE_COPYOUT; else if (!strcmp (copyprivate, p)) result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; + else if (!strcmp (create, p)) + result = PRAGMA_OMP_CLAUSE_CREATE; break; case 'd': - if (!strcmp (depend, p)) + if (!strcmp (delete, p)) + result = PRAGMA_OMP_CLAUSE_DELETE; + else if (!strcmp (depend, p)) result = PRAGMA_OMP_CLAUSE_DEPEND; else if (!strcmp (device, p)) result = PRAGMA_OMP_CLAUSE_DEVICE; + else if (!strcmp (deviceptr, p)) + result = PRAGMA_OMP_CLAUSE_DEVICEPTR; else if (!strcmp (dist_schedule, p)) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; break; @@ -26926,6 +26936,22 @@ cp_parser_omp_clause_name (cp_parser *parser) case 'p': if (!strcmp (parallel, p)) result = PRAGMA_OMP_CLAUSE_PARALLEL; + else if (!strcmp (present, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT; + else if (!strcmp (present_or_copy, p) + || !strcmp (pcopy, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPY; + else if (!strcmp (present_or_copyin, p) + || !strcmp (pcopyin, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYIN; + else if (!strcmp (present_or_copyout, p) + || !strcmp (pcopyout, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYOUT; + else if (!strcmp (present_or_create, p) + || !strcmp (pcreate, p)) + result = PRAGMA_OMP_CLAUSE_PRESENT_OR_CREATE; + else if (!strcmp (private, p)) + result = PRAGMA_OMP_CLAUSE_PRIVATE; else if (!strcmp (proc_bind, p)) result = PRAGMA_OMP_CLAUSE_PROC_BIND; break; @@ -27133,6 +27159,111 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list) return list; } +/* OpenACC 2.0: + copy ( variable-list ) + copyin ( variable-list ) + copyout ( variable-list ) + create ( variable-list ) + delete ( variable-list ) + present ( variable-list ) + present_or_copy ( variable-list ) + pcopy ( variable-list ) + present_or_copyin ( variable-list ) + pcopyin ( variable-list ) + present_or_copyout ( variable-list ) + pcopyout ( variable-list ) + present_or_create ( variable-list ) + pcreate ( variable-list ) */ + +static tree +cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind, + tree list) +{ + enum omp_clause_map_kind kind; + switch (c_kind) +{ +default: + gcc_unreachable (); +case PRAGMA_OMP_CLAUSE_COPY: + kind = OMP_CLAUSE_MAP_FORCE_TOFROM; + break; +case PRAGMA_OMP_CLAUSE_COPYIN: + kind = OMP_CLAUSE_MAP_FORCE_TO; + break; +case PRAGMA_OMP_CLAUSE_COPYOUT: + kind = OMP_CLAUSE_MAP_FORCE_FROM; + break; +case PRAGMA_OMP_CLAUSE_CREATE: + kind
Re: [PATCH 1/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
Hi Tobias! I fixed my patches. Could you review them? I'd use integer instead of INTEGER as it is not a 'reserved' word OpenMP implementation uses capital letters, so, perhaps, we also should do this, for consistency? -- Ilmir.
Re: [PATCH 2/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- matching and resolving. * gcc/fortran/openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses. (gfc_free_expr_list): New function to clear expression list. (match_oacc_expr_list): New function to match expression list. (match_oacc_clause_gang): New function to match OpenACC 2.0 gang clauses. (OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_OACC_COPYIN, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New clauses. (OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES, OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES, OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES, OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES, OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES): New defines. (gfc_match_oacc_parallel_loop, gfc_match_oacc_parallel, gfc_match_oacc_kernels_loop, gfc_match_oacc_kernels, gfc_match_oacc_data, gfc_match_oacc_host_data, gfc_match_oacc_loop, gfc_match_oacc_declare, gfc_match_oacc_update, gfc_match_oacc_enter_data, gfc_match_oacc_exit_data, gfc_match_oacc_wait, gfc_match_oacc_cache, oacc_is_loop, check_symbol_not_pointer, resolve_oacc_scalar_int_expr, resolve_oacc_positive_int_expr, check_array_not_assumed, resolve_oacc_data_clauses, resolve_oacc_deviceptr_clause, oacc_is_parallel, oacc_is_kernels, omp_code_to_statement, oacc_code_to_statement, resolve_oacc_directive_inside_omp_region, resolve_omp_directive_inside_oacc_region, resolve_oacc_nested_loops, resolve_oacc_params_in_parallel, resolve_oacc_loop_blocks, gfc_resolve_oacc_blocks, resolve_oacc_loop, resolve_oacc_cache, resolve_oacc_wait, gfc_resolve_oacc_declare, gfc_resolve_oacc_directive): New functions. (resolve_omp_clauses): Resolve also OpenACC clauses. (gfc_resolve_omp_directive): Check for enclosing OpenACC region. From 11beca16743c66a112ec44717eaf9ed61f203d1e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Wed, 26 Feb 2014 19:03:12 +0400 Subject: [PATCH 2/5] OpenACC Fortran FE: part 2 --- gcc/fortran/openmp.c | 1221 +- 1 file changed, 1199 insertions(+), 22 deletions(-) diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index dff3ab1..c582d51 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -69,11 +69,37 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c-final_expr); gfc_free_expr (c-num_threads); gfc_free_expr (c-chunk_size); + gfc_free_expr (c-async_expr); + gfc_free_expr (c-gang_expr); + gfc_free_expr (c-worker_expr); + gfc_free_expr (c-vector_expr); + gfc_free_expr (c-num_gangs_expr); + gfc_free_expr (c-num_workers_expr); + gfc_free_expr (c-vector_length_expr); + gfc_free_expr (c-non_clause_wait_expr); + for (i = 0; i OMP_LIST_NUM; i++) gfc_free_namelist (c-lists[i]); + + gfc_free_expr_list (c-wait_list); + gfc_free_expr_list (c-tile_list); + free (c); } +/* Free expression list. */ +void +gfc_free_expr_list (gfc_expr_list *list) +{ + gfc_expr_list *n; + + for (; list; list = n) +{ + n = list-next; + free (list); +} +} + /* Match a variable/common block list and construct a namelist from it. */ static match @@ -169,6 +195,87 @@ cleanup: return MATCH_ERROR; } +static match +match_oacc_expr_list (const char *str, gfc_expr_list **list, bool allow_asterisk) +{ + gfc_expr_list *head, *tail, *p; + locus old_loc; + gfc_expr *expr; + match m; + + head = tail = NULL; + + old_loc = gfc_current_locus; + + m = gfc_match (str); + if (m != MATCH_YES) +return m; + + for (;;) +{ + m = gfc_match_expr (expr); + if (m == MATCH_YES || allow_asterisk) + { + p = gfc_get_expr_list (); + if (head == NULL) + head = tail = p; + else + { + tail-next = p; + tail = tail-next; + } + if (m == MATCH_YES) + tail-expr = expr; + else if (gfc_match ( *) != MATCH_YES) + goto syntax; + goto next_item; + } + if (m == MATCH_ERROR) + goto cleanup; + goto syntax; + +next_item: + if (gfc_match_char (')') == MATCH_YES) + break; + if (gfc_match_char (',') != MATCH_YES) + goto syntax; +} + + while (*list) +list = (*list)-next; + + *list = head; + return MATCH_YES; + +syntax: + gfc_error (Syntax error in OpenACC expression list at %C); + +cleanup: + gfc_free_expr_list (head); + gfc_current_locus = old_loc
Re: [PATCH 3/4] [GOMP4] [Fortran] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- translation to GENERIC. gcc/fortran/ * trans-decl.c (gfc_generate_function_code): Insert OACC_DECLARE GENERIC node. * trans-openmp.c (gfc_convert_expr_to_tree): New helper function. (gfc_trans_omp_array_reduction): Support also OpenACC. Add parameter. (gfc_trans_omp_reduction_list): Update. (gfc_trans_oacc_construct): New transform function. (gfc_trans_omp_map_clause_list): Likewise. (gfc_trans_oacc_executable_directive): Likewise. (gfc_trans_oacc_combined_directive, gfc_trans_oacc_declare): Likewise. (gfc_trans_oacc_directive): Use them. (gfc_trans_oacc_loop): Stub. (gfc_trans_omp_clauses): Transform OpenACC clauses. * trans-stmt.h (gfc_trans_oacc_directive): New function prototype. (gfc_trans_oacc_declare): Likewise. * trans.c (trans_code): Transform also OpenACC directives. From b5010b30cc9fe6495cb9b9df356c044d267210c9 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Wed, 26 Feb 2014 19:03:24 +0400 Subject: [PATCH 3/5] OpenACC Fortran FE: part 3 --- gcc/fortran/trans-decl.c | 7 + gcc/fortran/trans-openmp.c | 357 + gcc/fortran/trans-stmt.c | 8 + gcc/fortran/trans-stmt.h | 4 + gcc/fortran/trans.c| 15 ++ 5 files changed, 391 insertions(+) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 9c86653..ad26ef8 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -5606,6 +5606,13 @@ gfc_generate_function_code (gfc_namespace * ns) if ((gfc_option.rtcheck GFC_RTCHECK_BOUNDS) !sym-attr.is_bind_c) add_argument_checking (body, sym); + /* Generate !$ACC DECLARE directive. */ + if (ns-oacc_declare_clauses) +{ + tree tmp = gfc_trans_oacc_declare (body, ns); + gfc_add_expr_to_block (body, tmp); +} + tmp = gfc_trans_code (ns-code); gfc_add_expr_to_block (body, tmp); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 41020a8..a1abd66 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -767,6 +767,40 @@ gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list, } static tree +gfc_trans_omp_map_clause_list (enum omp_clause_map_kind kind, + gfc_namelist *namelist, tree list) +{ + for (; namelist != NULL; namelist = namelist-next) +if (namelist-sym-attr.referenced) + { + tree t = gfc_trans_omp_variable (namelist-sym); + if (t != error_mark_node) + { + tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP); + OMP_CLAUSE_DECL (node) = t; + OMP_CLAUSE_MAP_KIND (node) = kind; + list = gfc_trans_add_clause (node, list); + } + } + return list; +} + +static inline tree +gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr) +{ + gfc_se se; + tree result; + + gfc_init_se (se, NULL ); + gfc_conv_expr (se, expr); + gfc_add_block_to_block (block, se.pre); + result = gfc_evaluate_now (se.expr, block); + gfc_add_block_to_block (block, se.post); + + return result; +} + +static tree gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, locus where) { @@ -834,6 +868,51 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, where); continue; } + if (list = OMP_LIST_DATA_CLAUSE_FIRST + list = OMP_LIST_DATA_CLAUSE_LAST) + { + enum omp_clause_map_kind kind; + switch (list) + { + case OMP_LIST_COPY: + kind = OMP_CLAUSE_MAP_FORCE_TOFROM; + break; + case OMP_LIST_OACC_COPYIN: + kind = OMP_CLAUSE_MAP_FORCE_TO; + break; + case OMP_LIST_COPYOUT: + kind = OMP_CLAUSE_MAP_FORCE_FROM; + break; + case OMP_LIST_CREATE: + kind = OMP_CLAUSE_MAP_FORCE_ALLOC; + break; + case OMP_LIST_DELETE: + kind = OMP_CLAUSE_MAP_FORCE_DEALLOC; + break; + case OMP_LIST_PRESENT: + kind = OMP_CLAUSE_MAP_FORCE_PRESENT; + break; + case OMP_LIST_PRESENT_OR_COPY: + kind = OMP_CLAUSE_MAP_TOFROM; + break; + case OMP_LIST_PRESENT_OR_COPYIN: + kind = OMP_CLAUSE_MAP_TO; + break; + case OMP_LIST_PRESENT_OR_COPYOUT: + kind = OMP_CLAUSE_MAP_FROM; + break; + case OMP_LIST_PRESENT_OR_CREATE: + kind = OMP_CLAUSE_MAP_ALLOC; + break; + case OMP_LIST_DEVICEPTR: + kind = OMP_CLAUSE_MAP_FORCE_DEVICEPTR; + break; + default: + gcc_unreachable (); + } + omp_clauses = gfc_trans_omp_map_clause_list (kind, n, omp_clauses); + continue; + } switch (list) { case OMP_LIST_PRIVATE: @@ -853,6 +932,21 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, goto add_clause; case OMP_LIST_COPYPRIVATE: clause_code = OMP_CLAUSE_COPYPRIVATE; + goto add_clause; + case OMP_LIST_USE_DEVICE: + clause_code = OMP_CLAUSE_USE_DEVICE; + goto add_clause; + case OMP_LIST_DEVICE_RESIDENT: + clause_code
Re: [PATCH, GOMP4] Fix OpenACC async clause
Hi Thomas! Fixed patch and ChangeLog in attachment. On 27.02.2014 12:59, Thomas Schwinge wrote: GANG/ASYNC/WAIT, for consistency? Fixed. For consistency, also move OMP_CLAUSE_ASYNC_EXPR in gcc/tree.h, and also adapt OMP_CLAUSE_ASYNC in gcc/tree-pretty-print.c:dump_omp_clause? It is already adapted: case OMP_CLAUSE_ASYNC: pp_string (buffer, async); if (OMP_CLAUSE_DECL (clause)) { pp_character(buffer, '('); dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), spc, flags, false); pp_character(buffer, ')'); } break; -- Ilmir. From bff6eb6dd930316bab91f222c1673e699fa97b96 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 27 Feb 2014 13:46:24 +0400 Subject: [PATCH] Fix ASYNC --- gcc/gimplify.c | 4 ++-- gcc/omp-low.c | 4 ++-- gcc/tree-core.h | 6 +++--- gcc/tree.c | 6 +++--- gcc/tree.h | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index fd4305c..d0a4779 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -6186,10 +6186,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: @@ -6546,10 +6546,10 @@ gimplify_adjust_omp_clauses (tree *list_p) case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 6dec687..eec862e 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1776,10 +1776,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: @@ -1916,10 +1916,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/tree-core.h b/gcc/tree-core.h index fcdeb44..e9aeb65 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -286,6 +286,9 @@ enum omp_clause_code { size-expression: * | integer-expression. */ OMP_CLAUSE_GANG, + /* OpenACC clause: async [(integer-expression)]. */ + OMP_CLAUSE_ASYNC, + /* OpenACC clause/directive: wait [(integer-expression-list)]. */ OMP_CLAUSE_WAIT, @@ -372,9 +375,6 @@ enum omp_clause_code { /* OpenACC clause: independent. */ OMP_CLAUSE_INDEPENDENT, - /* OpenACC clause: async [(integer-expression)]. */ - OMP_CLAUSE_ASYNC, - /* OpenACC clause: worker [( [num:] integer-expression)]. */ OMP_CLAUSE_WORKER, diff --git a/gcc/tree.c b/gcc/tree.c index 0655db0..d9a577b 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -264,6 +264,7 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_DEVICE_RESIDENT */ 1, /* OMP_CLAUSE_USE_DEVICE */ 1, /* OMP_CLAUSE_GANG */ + 1, /* OMP_CLAUSE_ASYNC */ 1, /* OMP_CLAUSE_WAIT */ 1, /* OMP_NO_CLAUSE_CACHE */ 1, /* OMP_CLAUSE__LOOPTEMP_ */ @@ -292,7 +293,6 @@ unsigned const char omp_clause_num_ops[] = 0, /* OMP_CLAUSE_TASKGROUP */ 1, /* OMP_CLAUSE__SIMDUID_ */ 0, /* OMP_CLAUSE_INDEPENDENT */ - 1, /* OMP_CLAUSE_ASYNC */ 1, /* OMP_CLAUSE_WORKER */ 1, /* OMP_CLAUSE_VECTOR */ 1, /* OMP_CLAUSE_NUM_GANGS */ @@ -322,6 +322,7 @@ const char * const omp_clause_code_name[] = device_resident, use_device, gang, + async, wait, _cache_, _looptemp_, @@ -350,7 +351,6 @@ const char * const omp_clause_code_name[] = taskgroup, _simduid_, independent, - async, worker, vector, num_gangs, @@ -11062,9 +11062,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/tree.h b/gcc/tree.h index 4d598d1..84801ff 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1315,15 +1315,15 @@ extern void protected_set_expr_location (tree, location_t); #define
Re: [PATCH, GOMP4] Fix OpenACC async clause
Committed as r208197. -- Ilmir.
[PATCH, GOMP4] Fix OpenACC async clause
Hi Thomas! This patch is pretty obvious. Currently ASYNC clause cannot have integer-expression-list. Patch fixes this. OK for gomp4 branch? -- Ilmir. From df76a29ebf869687209d7a606e243624cc136dbc Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Wed, 26 Feb 2014 19:04:47 +0400 Subject: [PATCH 4/5] Fix ASYNC --- gcc/gimplify.c | 4 ++-- gcc/omp-low.c | 4 ++-- gcc/tree-core.h | 6 +++--- gcc/tree.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index fd4305c..ce2f6a4 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -6186,10 +6186,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: @@ -6545,11 +6545,11 @@ gimplify_adjust_omp_clauses (tree *list_p) case OMP_CLAUSE_OACC_DEVICE: case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_GANG: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 6dec687..eec862e 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1776,10 +1776,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: @@ -1916,10 +1916,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/tree-core.h b/gcc/tree-core.h index fcdeb44..e9aeb65 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -286,6 +286,9 @@ enum omp_clause_code { size-expression: * | integer-expression. */ OMP_CLAUSE_GANG, + /* OpenACC clause: async [(integer-expression)]. */ + OMP_CLAUSE_ASYNC, + /* OpenACC clause/directive: wait [(integer-expression-list)]. */ OMP_CLAUSE_WAIT, @@ -372,9 +375,6 @@ enum omp_clause_code { /* OpenACC clause: independent. */ OMP_CLAUSE_INDEPENDENT, - /* OpenACC clause: async [(integer-expression)]. */ - OMP_CLAUSE_ASYNC, - /* OpenACC clause: worker [( [num:] integer-expression)]. */ OMP_CLAUSE_WORKER, diff --git a/gcc/tree.c b/gcc/tree.c index 0655db0..7d4805e 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -263,6 +263,7 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_OACC_DEVICE */ 1, /* OMP_CLAUSE_DEVICE_RESIDENT */ 1, /* OMP_CLAUSE_USE_DEVICE */ + 1, /* OMP_CLAUSE_ASYNC */ 1, /* OMP_CLAUSE_GANG */ 1, /* OMP_CLAUSE_WAIT */ 1, /* OMP_NO_CLAUSE_CACHE */ @@ -292,7 +293,6 @@ unsigned const char omp_clause_num_ops[] = 0, /* OMP_CLAUSE_TASKGROUP */ 1, /* OMP_CLAUSE__SIMDUID_ */ 0, /* OMP_CLAUSE_INDEPENDENT */ - 1, /* OMP_CLAUSE_ASYNC */ 1, /* OMP_CLAUSE_WORKER */ 1, /* OMP_CLAUSE_VECTOR */ 1, /* OMP_CLAUSE_NUM_GANGS */ @@ -322,6 +322,7 @@ const char * const omp_clause_code_name[] = device_resident, use_device, gang, + async, wait, _cache_, _looptemp_, @@ -350,7 +351,6 @@ const char * const omp_clause_code_name[] = taskgroup, _simduid_, independent, - async, worker, vector, num_gangs, @@ -11062,9 +11062,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_DEVICE_RESIDENT: case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_GANG: + case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_NO_CLAUSE_CACHE: - case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_NUM_GANGS: -- 1.8.3.2
Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Tobias! On 20.02.2014 03:51, Tobias Burnus wrote: On 10.02.2014 02:22, Tobias Burnus wrote: a) Does this part work well when both -fopenmp and -fopenacc is used? I mean: !$acc loop followed/preceded by !$omp do? I could imagine that there could be clashes, especially when - e.g. - collapse doesn't match. PGI: Silently ignores OpenMP pragmas. CAPS: Ignored option '--define' (_OPENMP=). I like how Cray handles it: It permits both - but neither OpenMP - OpenACC nesting nor vice versa. (It might not always detectable.) ERROR: The !$OMP PARALLEL DO directive cannot be specified within a !$ACC PARALLEL region. And adding OpenACC to an OpenMP loop fails with: ERROR: The !$ACC LOOP directive cannot be specified within a !$OMP PARALLEL DO region. (One gets the same error independent whether one tries to place the pragma on the same loop or just nested in the parallel pragma or on different loops.) I think doing likewise would be best. I agree. + if (gfc_implicit_pure (NULL)) +gfc_current_ns-proc_name-attr.implicit_pure = 0; I believe that will fail with BLOCK - cf. gfc_implicit_pure() Fortunally, it doesn't. Are you sure that it works? A block starts a new namespace, hence, gfc_implicit_pure() does: After your notice about namespaces, I tested !$acc declare attribute. Viola, it fails. However, other directives work. Side question: Do we also need to unset implicit_pure for OpenMP? As you can see in decode_omp_directive function, the flag is already unset. -- Ilmir.
Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Tobias! Thanks a lot for your review! I have tested your notes on two compilers which support OpenACC: PGI 14.1 and CAPS 3.4.1. If I made a mistake and you've collected results which differ from mine (whether you compiler is one of the above or not), please, let me know. Unfortunally, neither PGI nor CAPS don't support Fortran 2008. These are results: On 10.02.2014 02:22, Tobias Burnus wrote: a) Does this part work well when both -fopenmp and -fopenacc is used? I mean: !$acc loop followed/preceded by !$omp do? I could imagine that there could be clashes, especially when - e.g. - collapse doesn't match. PGI: Silently ignores OpenMP pragmas. CAPS: Ignored option '--define' (_OPENMP=). b) Do you also handle DO CONCURRENT - either by rejecting it or by accepting it? Namely, !$acc loop do concurrent(i=1:5) end do !$acc end loop end Side remark, with -fopenmp, it does ICE: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60127 My implemetation also fails, will fix. By the way, should we support these loops? I think we should, since DO CONCURRENT loops are parallelizable. Talking about !$acc loop: I vaguely remember that OpenACC 1.0's spec doesn't have !$acc end loop while I have seen OpenACC programs which use it. How do you handle !$acc end loop? Looking at parse.c, it seems to simply error out. I wonder whether one should be a bit more graceful. For instance, the following examples use !$acc end loop: http://devblogs.nvidia.com/parallelforall/openacc-example-part-2/ [If I remember correctly, pgf95 and Cray ftn silently accepts end loop while pathf95 accepts it with a warning.] And looking at the spec of OpenACC 1.0 and 2.0a, the end loop seems to be invalid. How about following PathScale's ENZO and accepting end loop with a warning? Or at least error out with a good error message. No, the spec doesn't specify !$acc end loop. However, compilers handle this construction differently: PGI: silently accepts. CAPS: Syntax error: expecting ('parallel' ('loop' or end)) or (('kernels' or 'dfkernels') ('loop' or end)) or 'data' or 'host_data' !$acc end loop My implementation also errors out, but I agree, we should accept this with warning. + if (gfc_pure (NULL)) +{ + gfc_error_now (OpenACC directives at %C may not appear in PURE + or ELEMENTAL procedures); Using gfc_pure() you do not check for ELEMENTAL: Since Fortran 2008, there are also IMPURE ELEMENTAL procedures. I don't know the spec, but I don't really see a reason why OpenACC shouldn't be permitted in IMPURE ELEMENTAL procedures. (BTW: ELEMENTAL implies PURE unless an explicit IMPURE is used.) In any case, either drop or ELEMENTAL or also check for the elemental attribute. I think I should drop or ELEMENTAL since OpenMP also accepts directives in IMPURE ELEMENTAL procecdures. + if (gfc_implicit_pure (NULL)) +gfc_current_ns-proc_name-attr.implicit_pure = 0; I believe that will fail with BLOCK - cf. gfc_implicit_pure() real function foo(n) integer, value :: n BLOCK integer i real sum !$acc loop reduce(+:sum) do i=1, n sum += sin(real(i)) end do END BLOCK end Fortunally, it doesn't. -- Ilmir.
Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Tobias! On 10.02.2014 03:10, Tobias Burnus wrote: Shouldn't you also reject polymorphic types (BT_CLASS and BT_ASSUMED)? [BT_CLASS = class(derived_type_name) or class(*); BT_ASSUMED = type(*)] + if (n-sym-attr.pointer) +gfc_error (POINTER object '%s' in %s clause at %L, + n-sym-name, name, code-loc); Actually, here and probably elsewhere: Do you need to take care of derived-type components? I mean something like clause(derived_type%comp) Do you also need to reject AS_ASSUMED_RANK (new since Fortran Technical Specification ISO/IEC TS 29113:2012)? I mean code like: subroutine foo(x) integer, DIMENSION(..) :: x ... openacc_clause(x) Side note: One should also check how OpenMP handles those. I think we should reject assumed size, assumed shape and assumed rank variables, as OpenMP does. + case OMP_LIST_DEVICEPTR: +if (n-sym-attr.pointer) + gfc_error (POINTER object '%s' in %s clause at %L, + n-sym-name, name, code-loc); Talking about pointers, you probably also want to reject Cray pointers (attr.cray_pointee - and cray_pointee). [One should also check what OpenMP does; I think it does handle it correctly.] I agree, currently my implementation does not handle Cray pointers correctly, will fix. And another point: I think you have to check whether the argument is a named constant (PARAMETER, attr.flavor == FL_PARAMETER), I think those you cannot put them there either. What happens if you try to use a literal such as deviceptr(5)? Both parameter and literal are rejected. By the way, PGI compiler accepts parameters with warning, CAPS silently accepts. I think, we also should support parameters with warning. + resolve_oacc_positive_int_expr (el-expr, TILE); + if (el-expr-expr_type != EXPR_CONSTANT) +gfc_error (TILE requires constant expression at %L, code-loc); Is the following permitted: tile(4+5)? If so, do you need to call gfc_simplify_expr() as some point? (Or is this already done at some point?) Yes, the syntax is allowed, but ... CAPSCompilers-3.4.1/bin/hmpp: [Error HP0112] tile.f95:30: Syntax error: expecting ')' !$acc parallel loop collapse(1+ 1) CAPS compiler doesn't support this. But PGI does. There is no need to simplify expression since it is constant anyway. The simplification is done during match stage (gfc_match_expr calls gfc_add). -- Ilmir.
Re: [PATCH 4/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Thomas! Thanks a lot for your review! I agree with all your notes. On 11.02.2014 20:51, Thomas Schwinge wrote: For ChangeLog files updates (on gomp-4_0-branch, use the respective ChangeLog.gomp files, by the way), should just you be listed as the author, or also your colleagues? Thank you for the notice, I added Evgeny and Dmitry as authors for this part (see attached ChangeLog entry). With these issues addressed, this patch is ready for commit to gomp-4_0-branch. Use your own judgement; if you feel confident, just commit it, or otherwise post it again for a final review -- as you prefer. I fixed patch according to your review and ready to commit it. OK for GOMP4 branch? -- Ilmir. From bf14158b1a28c2c5b29c41071fa62c011d9f4f65 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 13 Feb 2014 15:58:28 +0400 Subject: [PATCH] OpenACC GENERIC nodes --- gcc/doc/generic.texi| 45 ++ gcc/gimplify.c | 62 + gcc/omp-low.c | 96 -- gcc/tree-core.h | 61 ++--- gcc/tree-pretty-print.c | 119 gcc/tree.c | 44 +- gcc/tree.def| 42 + gcc/tree.h | 61 - 8 files changed, 507 insertions(+), 23 deletions(-) diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index a56715b..ce14620 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -2052,6 +2052,15 @@ edge. Rethrowing the exception is represented using @code{RESX_EXPR}. @node OpenMP @subsection OpenMP @tindex OACC_PARALLEL +@tindex OACC_KERNELS +@tindex OACC_DATA +@tindex OACC_HOST_DATA +@tindex OACC_DECLARE +@tindex OACC_UPDATE +@tindex OACC_ENTER_DATA +@tindex OACC_EXIT_DATA +@tindex OACC_WAIT +@tindex OACC_CACHE @tindex OMP_PARALLEL @tindex OMP_FOR @tindex OMP_SECTIONS @@ -2073,6 +2082,42 @@ clauses used by the OpenMP API @w{@uref{http://www.openmp.org/}}. Represents @code{#pragma acc parallel [clause1 @dots{} clauseN]}. +@item OACC_KERNELS + +Represents @code{#pragma acc kernels [clause1 @dots{} clauseN]}. + +@item OACC_DATA + +Represents @code{#pragma acc data [clause1 @dots{} clauseN]}. + +@item OACC_HOST_DATA + +Represents @code{#pragma acc host_data [clause1 @dots{} clauseN]}. + +@item OACC_DECLARE + +Represents @code{#pragma acc declare [clause1 @dots{} clauseN]}. + +@item OACC_UPDATE + +Represents @code{#pragma acc update [clause1 @dots{} clauseN]}. + +@item OACC_ENTER_DATA + +Represents @code{#pragma acc enter data [clause1 @dots{} clauseN]}. + +@item OACC_EXIT_DATA + +Represents @code{#pragma acc exit data [clause1 @dots{} clauseN]}. + +@item OACC_WAIT + +Represents @code{#pragma acc wait [(num @dots{})]}. + +@item OACC_CACHE + +Represents @code{#pragma acc cache (var @dots{})}. + @item OMP_PARALLEL Represents @code{#pragma omp parallel [clause1 @dots{} clauseN]}. It diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d20f07f..06d7790 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4333,6 +4333,15 @@ is_gimple_stmt (tree t) case ASM_EXPR: case STATEMENT_LIST: case OACC_PARALLEL: +case OACC_KERNELS: +case OACC_DATA: +case OACC_HOST_DATA: +case OACC_DECLARE: +case OACC_UPDATE: +case OACC_ENTER_DATA: +case OACC_EXIT_DATA: +case OACC_WAIT: +case OACC_CACHE: case OMP_PARALLEL: case OMP_FOR: case OMP_SIMD: @@ -6157,6 +6166,23 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, remove = true; break; + case OMP_CLAUSE_HOST: + case OMP_CLAUSE_OACC_DEVICE: + case OMP_CLAUSE_DEVICE_RESIDENT: + case OMP_CLAUSE_USE_DEVICE: + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_WAIT: + case OMP_NO_CLAUSE_CACHE: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_WORKER: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_NUM_GANGS: + case OMP_CLAUSE_NUM_WORKERS: + case OMP_CLAUSE_VECTOR_LENGTH: + remove = true; + break; + case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_UNTIED: @@ -6498,6 +6524,20 @@ gimplify_adjust_omp_clauses (tree *list_p) case OMP_CLAUSE_DEPEND: break; + case OMP_CLAUSE_HOST: + case OMP_CLAUSE_OACC_DEVICE: + case OMP_CLAUSE_DEVICE_RESIDENT: + case OMP_CLAUSE_USE_DEVICE: + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_WAIT: + case OMP_NO_CLAUSE_CACHE: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_WORKER: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_NUM_GANGS: + case OMP_CLAUSE_NUM_WORKERS: + case OMP_CLAUSE_VECTOR_LENGTH: default: gcc_unreachable (); } @@ -7988,6 +8028,19 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ret = GS_ALL_DONE; break; + case OACC_KERNELS: + case OACC_DATA: + case OACC_HOST_DATA: + case OACC_DECLARE: + case OACC_UPDATE: + case OACC_ENTER_DATA: + case OACC_EXIT_DATA: + case OACC_WAIT: + case OACC_CACHE
Re: [PATCH 4/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Committed as r207776. -- Ilmir.
Re: [PATCH 5/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Thomas! On 10.02.2014 12:52, Thomas Schwinge wrote: --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/goacc.exp @@ -0,0 +1,36 @@ +# Load support procs. +load_lib gfortran-dg.exp + +if ![check_effective_target_fopenmp] { + return +} I assume that this should be indeed fopenmp here and not fopenacc as both share libgomp? It should be fopenacc, because it tests whether the compiler accepts -fopenacc. My bad. I've missed the fact that you use check_effective_target_fopenacc in gcc.gd/goacc/goacc.exp. +# Main loop. +gfortran-dg-runtest [lsort \ + [find $srcdir/$subdir *.\[fF\]{,90,95,03,08} ] ] -fopenacc -fdump-parse-tree As you use -fopenacc here, you probably can get rid of it in dg-options. Right. Can't you? I am not sure whether -fdump-parse-tree is needed; on the other hand, it just clutters the *log files. Yes, I think that should just be in the test case files that actually need it? I've also missed this, will fix. I think, we need GENERIC nodes checks right now since the implementation is up to GENERIC. However, in future, when back-end will be implemented, we can remove them. -- Regards, Ilmir.
Re: [PATCH 5/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Tobias! Thanks a lot for your review! I'm going to test you notes in reference implementation (PGI compiler), and then share the results. On 10.02.2014 03:42, Tobias Burnus wrote: Is there a reason that you don't automatically add that flag via goacc.exp? Ditto. Also spaces before/after the pattern should make it more unique. I assume that this should be indeed fopenmp here and not fopenacc as both share libgomp? Yes, I'll fix this, thank you. As -fopenmp seemingly can be mixed with -fopenacc, I think it would be nice to have some test cases where !$omp and !$acc are both placed - in either order - before the same Fortran statement. I'm going to test this, too. There are can be some compilcations while using both !$omp and !$acc on single statement. -- Ilmir.
Re: [PING] [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Jakub! On 31.01.2014 15:45, Ilmir Usmanov wrote: Hi Jakub! Thank you for review and quick answer. The above are OpenACC specific clauses, so they should have OACC_LIST_*? I just followed Thomas's style recomendations: If we're adding new names for implementing OpenACC things, maybe we should also name these OMP_*, to keep things simple to read in the code that uses them. And I agree with him. + case OMP_LIST_DEVICE: type = DEVICE; break; This one is in OpenMP 4.0 too (though, I didn't get to OpenMP 4.0 / fortran support yet), so this should be OMP_LIST_DEVICE. As far as I know, OpenMP device clause requires integer-expression, not variable-list, so, I think, we can use OMP_LIST_DEVICE to represent OpenACC device clause. So, what should I do? Is current naming OK? Or you think it's better to use OACC_ prefix for OpenACC specific stuff in Fortran front-end and OMP_ prefix in middle-end? -- Ilmir.
Re: [PATCH] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Thomas! I fixed these patches: http://gcc.gnu.org/ml/gcc-patches/2014-01/msg01520.html . Instead of adding new OACC_* data structures and macros for OpenACC clauses these patches reuse existing OMP_* functionality and extends it. But OpenACC-specific constructs and directives still named as OACC_*. Thomas, as I noticed you privately, I can't use OpenMP 4.0 map clause to represent OpenACC data clauses in front-end, so old form of them still there. Successfully bootstrapped with no new regressions on x86_64-unknown-linux-gnu. OK for gomp-4_0-branch? -- Ilmir.
Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 support to fortran FE -- core. gcc/fortran/ * dump-parse-tree.c (show_omp_node): Dump also OpenACC executable statements. (show_code_node): Call it. * gfortran.h (ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA, ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_KERNELS_LOOP, ST_OACC_END_KERNELS_LOOP, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA): New statements. (gfc_exprlist): New structure to hold list of expressions. (OMP_LIST_COPY, OMP_LIST_DATA_CLAUSE_FIRST, OMP_LIST_OACC_COPYIN, OMP_LIST_COPYOUT, OMP_LIST_CREATE, OMP_LIST_DELETE, OMP_LIST_PRESENT, OMP_LIST_PRESENT_OR_COPY, OMP_LIST_PRESENT_OR_COPYIN, OMP_LIST_PRESENT_OR_COPYOUT, OMP_LIST_PRESENT_OR_CREATE, OMP_LIST_DEVICEPTR, OMP_LIST_DATA_CLAUSE_LAST, OMP_LIST_USE_DEVICE, OMP_LIST_DEVICE_RESIDENT, OMP_LIST_HOST, OMP_LIST_DEVICE, OMP_LIST_CACHE): New types of list, allowed in clauses. (gfc_omp_clauses): Add OpenACC clauses. (gfc_namespace): Add OpenACC declare directive clauses. (EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA): New executable statements. (gfc_free_exprlist): New function declaration. (gfc_resolve_oacc_directive): Likewise. (gfc_resolve_oacc_parallel_loop_blocks): Likewise. (gfc_resolve_oacc_blocks): Likewise. * match.c (match_exit_cycle): Add support of OpenACC regions and loops. * match.h (gfc_match_oacc_cache): New function declaration. (gfc_match_oacc_wait, gfc_match_oacc_update): Likewise. (gfc_match_oacc_declare, gfc_match_oacc_loop): Likewise. (gfc_match_oacc_host_data, gfc_match_oacc_data): Likewise. (gfc_match_oacc_kernels, gfc_match_oacc_kernels_loop): Likewise. (gfc_match_oacc_parallel, gfc_match_oacc_parallel_loop): Likewise. (gfc_match_oacc_enter_data, gfc_match_oacc_exit_data): Likewise. * parse.c (decode_oacc_directive): New function. (verify_token_free, verify_token_fixed): New helper functions. (next_free, next_fixed): Decode !$ACC sentinel. (case_executable): Add ST_OACC_UPDATE, ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_ENTER_DATA and ST_OACC_EXIT_DATA directives. (case_exec_markers): Add ST_OACC_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA, ST_OACC_LOOP and ST_OACC_KERNELS_LOOP directives. (push_state): Initialize OpenACC declare clauses. (gfc_ascii_statement): Dump names of OpenACC directives. (verify_st_order): Verify OpenACC declare directive as declarative. (parse_spec): Push clauses to state stack when declare directive is parsed. (parse_oacc_structured_block, parse_oacc_loop): New functions. (parse_executable): Call them. (parse_progunit): Move declare clauses from state stack to namespace. * parse.h (gfc_state_data): Add declare directive's clauses. * resolve.c (gfc_resolve_blocks): Resolve OpenACC directives. (resolve_code): Likewise. * scanner.c (openacc_flag, openacc_locus): New static variables. (skip_oacc_attribute, skip_omp_attribute): New helper functions. (skip_free_comments, skip_fixed_comments): Don't skip !$ACC sentinel. (gfc_next_char_literal): Support OpenACC directives. * st.c (gfc_free_statement): Free also OpenACC directives. From f8f10537d2555e596bdd1655990150d45ef08f9b Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:25:42 +0400 Subject: [PATCH 1/6] OpenACC fortran front-end -- part 1 --- gcc/fortran/dump-parse-tree.c | 135 +- gcc/fortran/gfortran.h| 59 ++ gcc/fortran/match.c | 27 +++ gcc/fortran/match.h | 15 ++ gcc/fortran/parse.c | 425 ++ gcc/fortran/parse.h | 1 + gcc/fortran/resolve.c | 36 gcc/fortran/scanner.c | 376 ++--- gcc/fortran/st.c | 12 ++ 9 files changed, 980 insertions(+), 106 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index b1343bc..9ef9db4 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1031,9 +1031,22 @@ show_omp_node (int level, gfc_code *c) { gfc_omp_clauses *omp_clauses = NULL; const char *name = NULL; + bool is_oacc = false; switch (c-op) { +case EXEC_OACC_PARALLEL_LOOP: name = PARALLEL LOOP; is_oacc = true; break; +case EXEC_OACC_PARALLEL: name = PARALLEL; is_oacc = true; break; +case EXEC_OACC_KERNELS_LOOP: name = KERNELS LOOP; is_oacc = true; break; +case
Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- matching and resolving. * openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses. (gfc_free_exprlist): New function to clear expression list. (match_oacc_exprlist): New function to match expression list. (match_oacc_clause_gang): New function to match OpenACC 2.0 gang clauses. (OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_OACC_COPYIN, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New clauses. (OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES, OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES, OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES, OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES, OACC_ENTER_DATA_CLAUSES, OACC_EXIT_DATA_CLAUSES): New defines. From 64b05eeeadf25fca4f92f083cc11aaad1a7a692a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:26:13 +0400 Subject: [PATCH 2/6] OpenACC fortran front-end -- part 2 --- gcc/fortran/openmp.c | 942 ++- 1 file changed, 940 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index dff3ab1..d4e3ebd 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -69,11 +69,36 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c-final_expr); gfc_free_expr (c-num_threads); gfc_free_expr (c-chunk_size); + gfc_free_expr (c-async_expr); + gfc_free_expr (c-gang_expr); + gfc_free_expr (c-worker_expr); + gfc_free_expr (c-vector_expr); + gfc_free_expr (c-num_gangs_expr); + gfc_free_expr (c-num_workers_expr); + gfc_free_expr (c-vector_length_expr); + gfc_free_expr (c-non_clause_wait_expr); + for (i = 0; i OMP_LIST_NUM; i++) gfc_free_namelist (c-lists[i]); + + gfc_free_exprlist (c-waitlist); + free (c); } +/* Free expression list. */ +void +gfc_free_exprlist (gfc_exprlist *list) +{ + gfc_exprlist *n; + + for (; list; list = n) +{ + n = list-next; + free (list); +} +} + /* Match a variable/common block list and construct a namelist from it. */ static match @@ -169,6 +194,87 @@ cleanup: return MATCH_ERROR; } +static match +match_oacc_exprlist (const char *str, gfc_exprlist **list, bool allow_asterisk) +{ + gfc_exprlist *head, *tail, *p; + locus old_loc; + gfc_expr *expr; + match m; + + head = tail = NULL; + + old_loc = gfc_current_locus; + + m = gfc_match (str); + if (m != MATCH_YES) +return m; + + for (;;) +{ + m = gfc_match_expr (expr); + if (m == MATCH_YES || allow_asterisk) +{ + p = gfc_get_exprlist (); + if (head == NULL) +head = tail = p; + else +{ + tail-next = p; + tail = tail-next; +} + if (m == MATCH_YES) +tail-expr = expr; + else if (gfc_match ( *) != MATCH_YES) +goto syntax; + goto next_item; +} + if (m == MATCH_ERROR) +goto cleanup; + goto syntax; + +next_item: + if (gfc_match_char (')') == MATCH_YES) +break; + if (gfc_match_char (',') != MATCH_YES) +goto syntax; +} + + while (*list) +list = (*list)-next; + + *list = head; + return MATCH_YES; + +syntax: + gfc_error (Syntax error in OpenACC expression list at %C); + +cleanup: + gfc_free_exprlist (head); + gfc_current_locus = old_loc; + return MATCH_ERROR; +} + +static match +match_oacc_clause_gang (gfc_omp_clauses *cp) +{ + if (gfc_match_char ('(') != MATCH_YES) +return MATCH_NO; + if (gfc_match ( num :) == MATCH_YES) +{ + cp-gang_static = false; + return gfc_match ( %e ), cp-gang_expr); +} + if (gfc_match ( static :) == MATCH_YES) +{ + cp-gang_static = true; + if (gfc_match ( * )) != MATCH_YES) +return gfc_match ( %e ), cp-gang_expr); + return MATCH_YES; +} + return gfc_match ( %e ), cp-gang_expr); +} + #define OMP_CLAUSE_PRIVATE (1 0) #define OMP_CLAUSE_FIRSTPRIVATE (1 1) #define OMP_CLAUSE_LASTPRIVATE (1 2) @@ -186,11 +292,40 @@ cleanup: #define OMP_CLAUSE_FINAL (1 14) #define OMP_CLAUSE_MERGEABLE (1 15) +/* OpenACC 2.0 clauses. */ +#define OMP_CLAUSE_ASYNC(1 16) +#define OMP_CLAUSE_NUM_GANGS(1 17) +#define OMP_CLAUSE_NUM_WORKERS (1 18) +#define OMP_CLAUSE_VECTOR_LENGTH(1 19) +#define OMP_CLAUSE_COPY (1 20) +#define
Re: [PATCH 3/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- translation to GENERIC. * trans-decl.c (gfc_generate_function_code): Insert OACC_DECLARE GENERIC node. * trans-openmp.c (gfc_convert_expr_to_tree): New helper function. (gfc_trans_omp_array_reduction): Support also OpenACC. Add parameter. (gfc_trans_omp_reduction_list): Update. (gfc_trans_oacc_construct): New transform function. (gfc_trans_omp_map_clause_list): Likewise. (gfc_trans_oacc_executable_directive): Likewise. (gfc_trans_oacc_combined_directive, gfc_trans_oacc_declare): Likewise. (gfc_trans_oacc_directive): Use them. (gfc_trans_oacc_loop): Stub. (gfc_trans_omp_clauses): Transform OpenACC clauses. * trans-stmt.h (gfc_trans_oacc_directive): New function prototype. (gfc_trans_oacc_declare): Likewise. * trans.c (trans_code): Transform also OpenACC directives. From c7fcfb4e2aaeb1833dad4d5e370da330bb1a3760 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:27:24 +0400 Subject: [PATCH 3/6] OpenACC fortran front-end -- part 3 --- gcc/fortran/trans-decl.c | 7 + gcc/fortran/trans-openmp.c | 367 + gcc/fortran/trans-stmt.h | 4 + gcc/fortran/trans.c| 15 ++ 4 files changed, 393 insertions(+) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index bb02f43..69f33dd 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -5602,6 +5602,13 @@ gfc_generate_function_code (gfc_namespace * ns) if ((gfc_option.rtcheck GFC_RTCHECK_BOUNDS) !sym-attr.is_bind_c) add_argument_checking (body, sym); + /* Generate !$ACC DECLARE directive. */ + if (ns-declare_clauses) +{ + tmp = gfc_trans_oacc_declare(body, ns); + gfc_add_expr_to_block(body, tmp); +} + tmp = gfc_trans_code (ns-code); gfc_add_expr_to_block (body, tmp); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 41020a8..a9d1bbc 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -767,6 +767,40 @@ gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list, } static tree +gfc_trans_omp_map_clause_list (enum omp_clause_map_kind kind, + gfc_namelist *namelist, tree list) +{ + for (; namelist != NULL; namelist = namelist-next) +if (namelist-sym-attr.referenced) + { +tree t = gfc_trans_omp_variable (namelist-sym); +if (t != error_mark_node) + { +tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP); +OMP_CLAUSE_DECL (node) = t; +OMP_CLAUSE_MAP_KIND (node) = kind; +list = gfc_trans_add_clause (node, list); + } + } + return list; +} + +static inline tree +gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr) +{ + gfc_se se; + tree result; + + gfc_init_se (se, NULL ); + gfc_conv_expr (se, expr); + gfc_add_block_to_block (block, se.pre); + result = gfc_evaluate_now (se.expr, block); + gfc_add_block_to_block (block, se.post); + + return result; +} + +static tree gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, locus where) { @@ -834,6 +868,51 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, where); continue; } + if (list = OMP_LIST_DATA_CLAUSE_FIRST + list = OMP_LIST_DATA_CLAUSE_LAST) +{ + enum omp_clause_map_kind kind; + switch (list) +{ +case OMP_LIST_COPY: + kind = OMP_CLAUSE_MAP_FORCE_TOFROM; + break; +case OMP_LIST_OACC_COPYIN: + kind = OMP_CLAUSE_MAP_FORCE_TO; + break; +case OMP_LIST_COPYOUT: + kind = OMP_CLAUSE_MAP_FORCE_FROM; + break; +case OMP_LIST_CREATE: + kind = OMP_CLAUSE_MAP_FORCE_ALLOC; + break; +case OMP_LIST_DELETE: + kind = OMP_CLAUSE_MAP_FORCE_DEALLOC; + break; +case OMP_LIST_PRESENT: + kind = OMP_CLAUSE_MAP_FORCE_PRESENT; + break; +case OMP_LIST_PRESENT_OR_COPY: + kind = OMP_CLAUSE_MAP_TOFROM; + break; +case OMP_LIST_PRESENT_OR_COPYIN: + kind = OMP_CLAUSE_MAP_TO; + break; +case OMP_LIST_PRESENT_OR_COPYOUT: + kind = OMP_CLAUSE_MAP_FROM; + break; +case OMP_LIST_PRESENT_OR_CREATE: + kind = OMP_CLAUSE_MAP_ALLOC; + break; +case OMP_LIST_DEVICEPTR: + kind = OMP_CLAUSE_MAP_FORCE_DEVICEPTR; + break; +default: + gcc_unreachable (); +} + omp_clauses = gfc_trans_omp_map_clause_list (kind, n, omp_clauses); + continue; +} switch (list) { case OMP_LIST_PRIVATE: @@ -853,6 +932,21
Re: [PATCH 4/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 support -- GENERIC nodes and gimplify stubs. gcc/ * gimplify.c (is_gimple_stmt): Stub OpenACC directives and clauses. (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses): Likewise. (gimplify_expr): Likewise. * omp-low.c (scan_sharing_clauses): Likewise. (gimple_code_is_oacc): New helper function. (scan_sharing_clauses): Use it. * tree-core.h (OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_OACC_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT): New clauses. * tree-pretty-print.c (dump_omp_clause): Print OpenACC clause. (dump_generic_node): Print OpenACC directives and its clauses. * tree.c (omp_clause_num_ops): Add OpenACC clauses. (omp_clause_code_name): Likewise. (walk_tree_1): Likewise. * tree.def (OACC_KERNELS): New tree node. (OACC_DATA, OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE): Likewise. (OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_WAIT, OACC_CACHE): Likewise. * tree.h (OACC_BODY): New macros. (OACC_KERNELS_BODY, OACC_KERNELS_CLAUSES, OACC_CLAUSE_NUM_GANGS_EXPR, OMP_CLAUSE_NUM_WORKERS_EXPR, OMP_CLAUSE_VECTOR_LENGTH_EXPR, OMP_CLAUSE_VECTOR_EXPR, OMP_CLAUSE_WORKER_EXPR, OMP_CLAUSE_GANG_EXPR, OMP_CLAUSE_ASYNC_EXPR, OMP_WAIT_EXPR, OACC_DATA_BODY, OACC_DATA_CLAUSES, OACC_DECLARE_CLAUSES, OACC_UPDATE_CLAUSES, OACC_WAIT_CLAUSES, OACC_CACHE_CLAUSES, OACC_HOST_DATA_BODY, OACC_HOST_DATA_CLAUSES): Likewise. From 3383f24ea09611525311e3e2147672421c31f9cb Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:28:47 +0400 Subject: [PATCH 4/6] OpenACC GENERIC nodes --- gcc/gimplify.c | 53 + gcc/omp-low.c | 96 +--- gcc/tree-core.h | 61 +--- gcc/tree-pretty-print.c | 103 gcc/tree.c | 44 - gcc/tree.def| 50 +++ gcc/tree.h | 53 + 7 files changed, 438 insertions(+), 22 deletions(-) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d20f07f..34fd8ca 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4333,6 +4333,15 @@ is_gimple_stmt (tree t) case ASM_EXPR: case STATEMENT_LIST: case OACC_PARALLEL: +case OACC_KERNELS: +case OACC_DATA: +case OACC_CACHE: +case OACC_WAIT: +case OACC_HOST_DATA: +case OACC_DECLARE: +case OACC_UPDATE: +case OACC_ENTER_DATA: +case OACC_EXIT_DATA: case OMP_PARALLEL: case OMP_FOR: case OMP_SIMD: @@ -6157,6 +6166,20 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, remove = true; break; + case OMP_CLAUSE_HOST: + case OMP_CLAUSE_OACC_DEVICE: + case OMP_CLAUSE_DEVICE_RESIDENT: + case OMP_CLAUSE_USE_DEVICE: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_WAIT: + case OMP_NO_CLAUSE_CACHE: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_WORKER: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_NUM_GANGS: + case OMP_CLAUSE_NUM_WORKERS: + case OMP_CLAUSE_VECTOR_LENGTH: case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_UNTIED: @@ -6476,6 +6499,23 @@ gimplify_adjust_omp_clauses (tree *list_p) } break; + case OMP_CLAUSE_HOST: + case OMP_CLAUSE_OACC_DEVICE: + case OMP_CLAUSE_DEVICE_RESIDENT: + case OMP_CLAUSE_USE_DEVICE: + case OMP_CLAUSE_ASYNC: + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_WAIT: + case OMP_NO_CLAUSE_CACHE: + case OMP_CLAUSE_INDEPENDENT: + case OMP_CLAUSE_WORKER: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_NUM_GANGS: + case OMP_CLAUSE_NUM_WORKERS: + case OMP_CLAUSE_VECTOR_LENGTH: +sorry (Clause not supported yet); +break; + case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: @@ -7988,6 +8028,19 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ret = GS_ALL_DONE; break; + case OACC_KERNELS: + case OACC_DATA: + case OACC_CACHE: + case OACC_WAIT: + case OACC_HOST_DATA: + case OACC_DECLARE: + case OACC_UPDATE: + case OACC_ENTER_DATA: + case OACC_EXIT_DATA: +sorry (directive not yet implemented); +ret = GS_ALL_DONE; +break; + case OMP_PARALLEL: gimplify_omp_parallel (expr_p, pre_p); ret = GS_ALL_DONE; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 4bbe6d6..88de870 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1491,6 +1491,18 @@ fixup_child_record_type (omp_context *ctx) TREE_TYPE (ctx-receiver_decl) = build_pointer_type (type); } +static bool +gimple_code_is_oacc (const_gimple g) +{ + switch (gimple_code (g)) +{ +case GIMPLE_OACC_PARALLEL: + return true; +default
Re: [PATCH 5/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 fortran FE support -- tests. gcc/testsuite/gfortran.dg/goacc/ * goacc.exp: New test directory. * branch.f95: New test. * continuation-free-form.f95: Likewise. * data-clauses.f95: Likewise. * data-tree.f95: Likewise. * declare-1.f95: Likewise. * declare.f95: Likewise. * directive-names.f95: Likewise. * enter-exit-data.f95: Likewise. * host_data-tree.f95: Likewise. * if.f95: Likewise. * kernels-tree.f95: Likewise. * list.f95: Likewise. * parallel-kernels-clauses.f95: Likewise. * parallel-kernels-regions.f95: Likewise. * parallel-tree.f95: Likewise. * pure-elemental-procedures.f95: Likewise. * reduction.f95: Likewise. * sentinel-free-form.f95: Likewise. * several-directives.f95: Likewise. * sie.f95: Likewise. From 9850a2e343e506fa06edf1518414ac71eed60d48 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:29:44 +0400 Subject: [PATCH 5/6] OpenACC fortran tests --- gcc/testsuite/gfortran.dg/goacc/branch.f95 | 55 + .../gfortran.dg/goacc/continuation-free-form.f95 | 24 ++ gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 | 261 + gcc/testsuite/gfortran.dg/goacc/data-tree.f95 | 33 +++ gcc/testsuite/gfortran.dg/goacc/declare-1.f95 | 13 + .../gfortran.dg/goacc/directive-names.f95 | 20 ++ .../gfortran.dg/goacc/enter-exit-data.f95 | 89 +++ gcc/testsuite/gfortran.dg/goacc/goacc.exp | 36 +++ gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 | 13 + gcc/testsuite/gfortran.dg/goacc/if.f95 | 53 + gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 | 34 +++ gcc/testsuite/gfortran.dg/goacc/list.f95 | 111 + .../gfortran.dg/goacc/parallel-kernels-clauses.f95 | 96 .../gfortran.dg/goacc/parallel-kernels-regions.f95 | 57 + gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95 | 42 .../goacc/pure-elemental-procedures.f95| 46 gcc/testsuite/gfortran.dg/goacc/reduction.f95 | 138 +++ .../gfortran.dg/goacc/sentinel-free-form.f95 | 22 ++ .../gfortran.dg/goacc/several-directives.f95 | 7 + gcc/testsuite/gfortran.dg/goacc/sie.f95| 252 20 files changed, 1402 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/goacc/branch.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/data-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/declare-1.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/directive-names.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/enter-exit-data.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/goacc.exp create mode 100644 gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/if.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/list.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/reduction.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/several-directives.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/sie.f95 diff --git a/gcc/testsuite/gfortran.dg/goacc/branch.f95 b/gcc/testsuite/gfortran.dg/goacc/branch.f95 new file mode 100644 index 000..e470ce2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/branch.f95 @@ -0,0 +1,55 @@ +! { dg-do compile } +! { dg-options -fopenacc } + +program test + implicit none + + integer :: i + + if (.true.) then + !$acc parallel + end if ! { dg-error Unexpected } + !$acc end parallel + end if + + if (.true.) then + !$acc kernels + end if ! { dg-error Unexpected } + !$acc end kernels + end if + + !$acc parallel + if (.true.) then + !$acc end parallel ! { dg-error Unexpected } + end if + !$acc end parallel + + !$acc kernels + if (.true.) then + !$acc end kernels ! { dg-error Unexpected } + end if + !$acc end kernels + + !$acc parallel + if (.true.) then + end if + !$acc end parallel + + !$acc kernels + if (.true.) then + end if + !$acc end kernels + + if (.true.) then + !$acc parallel + !$acc end parallel + end if + + if (.true.) then + !$acc kernels + !$acc end kernels + end if +10 i = 0 + + +end program test \ No newline at end of file diff --git a/gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 b/gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 new file
Re: [PATCH 6/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
OpenACC 1.0 support -- documentation. gcc/doc/ * generic.texi: Document OACC_KERNELS, OACC_DATA, OACC_HOST_DATA, OACC_DECLARE, OACC_UPDATE, OACC_ENTER_DATA, OACC_EXIT_DATA, OACC_WAIT, OACC_CACHE. From 2550374183627d221f8881d14939ea7b0045bfba Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Fri, 31 Jan 2014 13:30:18 +0400 Subject: [PATCH 6/6] OpenACC GENERIC docs --- gcc/doc/generic.texi | 40 1 file changed, 40 insertions(+) diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index a56715b..8153a6e 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -2052,6 +2052,14 @@ edge. Rethrowing the exception is represented using @code{RESX_EXPR}. @node OpenMP @subsection OpenMP @tindex OACC_PARALLEL +@tindex OACC_KERNELS +@tindex OACC_DATA +@tindex OACC_HOST_DATA +@tindex OACC_UPDATE +@tindex OACC_ENTER_DATA +@tindex OACC_EXIT_DATA +@tindex OACC_WAIT +@tindex OACC_CACHE @tindex OMP_PARALLEL @tindex OMP_FOR @tindex OMP_SECTIONS @@ -2073,6 +2081,38 @@ clauses used by the OpenMP API @w{@uref{http://www.openmp.org/}}. Represents @code{#pragma acc parallel [clause1 @dots{} clauseN]}. +@item OACC_KERNELS + +Represents @code{#pragma acc kernels [clause1 @dots{} clauseN]}. + +@item OACC_DATA + +Represents @code{#pragma acc data [clause1 @dots{} clauseN]}. + +@item OACC_HOST_DATA + +Represents @code{#pragma acc host_data [clause1 @dots{} clauseN]}. + +@item OACC_UPDATE + +Represents @code{#pragma acc update [clause1 @dots{} clauseN]}. + +@item OACC_ENTER_DATA + +Represents @code{#pragma acc enter data [clause1 @dots{} clauseN]}. + +@item OACC_EXIT_DATA + +Represents @code{#pragma acc exit data [clause1 @dots{} clauseN]}. + +@item OACC_WAIT + +Represents @code{#pragma acc wait [(num @dots{})]}. + +@item OACC_CACHE + +Represents @code{#pragma acc cache (var @dots{})}. + @item OMP_PARALLEL Represents @code{#pragma omp parallel [clause1 @dots{} clauseN]}. It -- 1.8.3.2
Re: [PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi Jakub! Thank you for review and quick answer. The above are OpenACC specific clauses, so they should have OACC_LIST_*? I just followed Thomas's style recomendations: If we're adding new names for implementing OpenACC things, maybe we should also name these OMP_*, to keep things simple to read in the code that uses them. And I agree with him. + case OMP_LIST_DEVICE: type = DEVICE; break; This one is in OpenMP 4.0 too (though, I didn't get to OpenMP 4.0 / fortran support yet), so this should be OMP_LIST_DEVICE. As far as I know, OpenMP device clause requires integer-expression, not variable-list, so, I think, we can use OMP_LIST_DEVICE to represent OpenACC device clause. -- Thanks, Ilmir.
Re: [PATCH] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi, Thomas! Likewise, if you have any comments on my patch series for »initial support for OpenACC data clauses«, I'd like to hear them. Sure: + else if (!strcmp (present_or_copy, p)) +result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPY; + else if (!strcmp (present_or_copyin, p)) +result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYIN; + else if (!strcmp (present_or_copyout, p)) +result = PRAGMA_OMP_CLAUSE_PRESENT_OR_COPYOUT; + else if (!strcmp (present_or_create, p)) +result = PRAGMA_OMP_CLAUSE_PRESENT_OR_CREATE; For these combined clauses the specification specifies short names: pcopy, pcopyin, pcopyout and pcreate (see 2.6.5.9 - 2.6.5.12 of OpenACC 2.0). And otherwise, as you state that you'd base your work on this, it probably makes sense if I commit my patches soon? (I now also have to rebase my patches onto the updated gomp-4_0-branch.) Yes, it would be great! -- Ilmir.
Re: [PATCH] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi, Thomas! Thank you for your review. I agree with all your notes. I'm going to reuse your implementation of data clauses, add minimal GIMPLE infrastructure, and then resend patches. -- Ilmir.
[PATCH] [GOMP4] OpenACC 1.0+ support in fortran front-end
Hi all. Jakub, could you review these patches, if they are OK to gomp-4_0-branch? Thomas, please, have a look whether this implementation applies current OpenACC support style. These patches port OpenACC 1.0 support in fortran front-end from openacc-1_0-branch to gomp-4_0-branch. In addition, they extend middle-end infrastructure with necessary GENERIC nodes. Patches support almost all directives (except loop) and all clauses from the specification ver. 1.0 (without subarrays). In addition to OpenACC version 1.0, patches add functionality from OpenACC 2.0: enter data and exit data directives. Patches stub gimplification of OpenACC constructs and directives, except OACC_PARALLEL node, to prevent crashes. I didn't port loop directive, since in openacc-1_0-branch we consider it as OpenACC construct, like kernels or parallel. Hence, OpenACC loop and OpenMP for directives differ. It means there are no checks in C FE (in openacc-1_0-branch) and the functionality will be modified, in both FEs and back-end. As far as loop directive doesn't exist in GENERIC, fortran FE doesn't transform it from internal EXEC_OACC_LOOP statement. Consequenly, there are no tests to check the directive. Lately, I'm going to port loop directive, too. Inspite of the fact that subarrays do exist in openacc-1_0-branch, they don't present in patches. Currently, we are using our own GENERIC nodes to represent subarrays. I'm going to replace them with existing functionality, like ARRAY_RANGE_REF. Full list of supported fuctionality is the following: Constructs/directives: Namefront-end GENERIC tests parallelY Y Y kernels Y Y Y dataY Y Y host_data Y Y Y loopY N N update Y Y Y waitY Y N cache Y Y N declare Y Y Y kernels loopY N N parallel loop Y N N enter data (2.0)Y Y Y exit data (2.0) Y Y Y Clauses Namefront-end GENERIC tests async Y Y Y waitY Y Y num_gangs Y Y Y num_workers Y Y Y vector_length Y Y Y if Y Y Y reduction Y Y Y copyY Y Y copyin Y Y Y copyout Y Y Y create Y Y Y delete (2.0)Y Y Y present Y Y Y present_or_copy Y Y Y present_or_copyin Y Y Y present_or_copyout Y Y Y present_or_create Y Y Y deviceptr Y Y Y private Y Y Y firstprivateY Y Y default(none) (2.0) Y N Y collapseY Y N gangY Y N worker Y Y N vector Y Y N seq Y Y N auto (2.0) Y N N tileY N N independent Y Y N device_resident Y Y N Successfully bootstraps on x86_64 with no regressions. OK to commit? -- Ilmir
[PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From 69bf2531e4512b7cdb2feba8541de1eaf9c2aa56 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:05:11 +0400 Subject: [PATCH 2/6] OpenACC fortran FE part 2 --- gcc/fortran/openmp.c | 1032 +- 1 file changed, 1019 insertions(+), 13 deletions(-) diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 6c4dccb..ce13e52 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -69,11 +69,36 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c-final_expr); gfc_free_expr (c-num_threads); gfc_free_expr (c-chunk_size); - for (i = 0; i OMP_LIST_NUM; i++) + gfc_free_expr (c-async_expr); + gfc_free_expr (c-gang_expr); + gfc_free_expr (c-worker_expr); + gfc_free_expr (c-vector_expr); + gfc_free_expr (c-num_gangs_expr); + gfc_free_expr (c-num_workers_expr); + gfc_free_expr (c-vector_length_expr); + gfc_free_expr (c-non_clause_wait_expr); + + for (i = 0; i OACC_LIST_NUM; i++) gfc_free_namelist (c-lists[i]); + + gfc_free_exprlist (c-waitlist); + free (c); } +/* Free expression list. */ +void +gfc_free_exprlist (gfc_exprlist *list) +{ + gfc_exprlist *n; + + for (; list; list = n) +{ + n = list-next; + free (list); +} +} + /* Match a variable/common block list and construct a namelist from it. */ static match @@ -169,6 +194,87 @@ cleanup: return MATCH_ERROR; } +static match +match_oacc_exprlist (const char *str, gfc_exprlist **list, bool allow_asterisk) +{ + gfc_exprlist *head, *tail, *p; + locus old_loc; + gfc_expr *expr; + match m; + + head = tail = NULL; + + old_loc = gfc_current_locus; + + m = gfc_match (str); + if (m != MATCH_YES) +return m; + + for (;;) +{ + m = gfc_match_expr (expr); + if (m == MATCH_YES || allow_asterisk) +{ + p = gfc_get_exprlist (); + if (head == NULL) +head = tail = p; + else +{ + tail-next = p; + tail = tail-next; +} + if (m == MATCH_YES) +tail-expr = expr; + else if (gfc_match ( *) != MATCH_YES) +goto syntax; + goto next_item; +} + if (m == MATCH_ERROR) +goto cleanup; + goto syntax; + +next_item: + if (gfc_match_char (')') == MATCH_YES) +break; + if (gfc_match_char (',') != MATCH_YES) +goto syntax; +} + + while (*list) +list = (*list)-next; + + *list = head; + return MATCH_YES; + +syntax: + gfc_error (Syntax error in OpenACC expression list at %C); + +cleanup: + gfc_free_exprlist (head); + gfc_current_locus = old_loc; + return MATCH_ERROR; +} + +static match +match_oacc_clause_gang (gfc_oacc_clauses *cp) +{ + if (gfc_match_char ('(') != MATCH_YES) +return MATCH_NO; + if (gfc_match ( num :) == MATCH_YES) +{ + cp-gang_static = false; + return gfc_match ( %e ), cp-gang_expr); +} + if (gfc_match ( static :) == MATCH_YES) +{ + cp-gang_static = true; + if (gfc_match ( * )) != MATCH_YES) +return gfc_match ( %e ), cp-gang_expr); + return MATCH_YES; +} + return gfc_match ( %e ), cp-gang_expr); +} + #define OMP_CLAUSE_PRIVATE (1 0) #define OMP_CLAUSE_FIRSTPRIVATE (1 1) #define OMP_CLAUSE_LASTPRIVATE (1 2) @@ -186,15 +292,51 @@ cleanup: #define OMP_CLAUSE_FINAL (1 14) #define OMP_CLAUSE_MERGEABLE (1 15) +/* OpenACC 2.0 clauses. */ +#define OACC_CLAUSE_IF OMP_CLAUSE_IF +#define OACC_CLAUSE_ASYNC(1 16) +#define OACC_CLAUSE_NUM_GANGS(1 17) +#define OACC_CLAUSE_NUM_WORKERS (1 18) +#define OACC_CLAUSE_VECTOR_LENGTH(1 19) +#define OACC_CLAUSE_REDUCTIONOMP_CLAUSE_REDUCTION +#define OACC_CLAUSE_COPY (1 20) +#define OACC_CLAUSE_COPYIN OMP_CLAUSE_COPYIN +#define OACC_CLAUSE_COPYOUT (1 21) +#define OACC_CLAUSE_CREATE (1 22) +#define OACC_CLAUSE_PRESENT (1 23) +#define OACC_CLAUSE_PRESENT_OR_COPY (1 24) +#define OACC_CLAUSE_PRESENT_OR_COPYIN(1 25) +#define OACC_CLAUSE_PRESENT_OR_COPYOUT (1 26) +#define OACC_CLAUSE_PRESENT_OR_CREATE(1 27) +#define OACC_CLAUSE_DEVICEPTR(1 28) +#define OACC_CLAUSE_PRIVATE OMP_CLAUSE_PRIVATE +#define OACC_CLAUSE_FIRSTPRIVATE OMP_CLAUSE_FIRSTPRIVATE +#define OACC_CLAUSE_COLLAPSE OMP_CLAUSE_COLLAPSE +#define OACC_CLAUSE_GANG (1 29) +#define OACC_CLAUSE_WORKER (1 30) +#define OACC_CLAUSE_VECTOR (1 31) +#define OACC_CLAUSE_SEQ (1ll 32) +#define OACC_CLAUSE_INDEPENDENT (1ll 33) +#define OACC_CLAUSE_USE_DEVICE (1ll 34) +#define OACC_CLAUSE_DEVICE_RESIDENT (1ll 35) +#define OACC_CLAUSE_HOST (1ll 36) +#define OACC_CLAUSE_DEVICE (1ll 37) +#define OACC_CLAUSE_DEFAULT
[PATCH 1/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From 84dc72f88c1b23ae995afdda0b946ebd73af102f Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:04:37 +0400 Subject: [PATCH 1/6] OpenACC fortran FE part 1 --- gcc/fortran/decl.c| 1 + gcc/fortran/dump-parse-tree.c | 203 gcc/fortran/gfortran.h| 81 +++- gcc/fortran/match.c | 34 +++- gcc/fortran/match.h | 15 ++ gcc/fortran/parse.c | 425 ++ gcc/fortran/parse.h | 4 +- gcc/fortran/resolve.c | 36 gcc/fortran/scanner.c | 382 + gcc/fortran/st.c | 14 +- 10 files changed, 1082 insertions(+), 113 deletions(-) diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 0a0f8e0..e988983 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -6000,6 +6000,7 @@ gfc_match_end (gfc_statement *st) case COMP_CONTAINS: case COMP_DERIVED_CONTAINS: +case COMP_OACC_STRUCTURED_BLOCK: state = gfc_state_stack-previous-state; block_name = gfc_state_stack-previous-sym == NULL ? NULL : gfc_state_stack-previous-sym-name; diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 14ff004..74be9ba 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1230,6 +1230,194 @@ show_omp_node (int level, gfc_code *c) fprintf (dumpfile, (%s), c-ext.omp_name); } +/* Show a single OpenACC directive node and everything underneath it + if necessary. */ + +static void +show_oacc_node (int level, gfc_code *c) +{ + gfc_oacc_clauses *acc_clauses = NULL; + const char *name = NULL; + + switch (c-op) +{ +case EXEC_OACC_PARALLEL_LOOP: name = PARALLEL LOOP; break; +case EXEC_OACC_PARALLEL: name = PARALLEL; break; +case EXEC_OACC_KERNELS_LOOP: name = KERNELS LOOP; break; +case EXEC_OACC_KERNELS: name = KERNELS; break; +case EXEC_OACC_DATA: name = DATA; break; +case EXEC_OACC_HOST_DATA: name = HOST_DATA; break; +case EXEC_OACC_LOOP: name = LOOP; break; +case EXEC_OACC_UPDATE: name = UPDATE; break; +case EXEC_OACC_WAIT: name = WAIT; break; +case EXEC_OACC_CACHE: name = CACHE; break; +case EXEC_OACC_ENTER_DATA: name = ENTER DATA; break; +case EXEC_OACC_EXIT_DATA: name = EXIT DATA; break; +default: + gcc_unreachable (); +} + fprintf (dumpfile, !$ACC %s, name); + acc_clauses = c-ext.omp_clauses; + if (acc_clauses) +{ + int list; + + if (acc_clauses-if_expr) +{ + fputs ( IF(, dumpfile); + show_expr (acc_clauses-if_expr); + fputc (')', dumpfile); +} + if (acc_clauses-async) +{ + fputs ( ASYNC, dumpfile); + if (acc_clauses-async_expr) +{ + fputc ('(', dumpfile); + show_expr (acc_clauses-async_expr); + fputc (')', dumpfile); +} +} + if (acc_clauses-num_gangs_expr) +{ + fputs ( NUM_GANGS(, dumpfile); + show_expr (acc_clauses-num_gangs_expr); + fputc (')', dumpfile); +} + if (acc_clauses-num_workers_expr) +{ + fputs ( NUM_WORKERS(, dumpfile); + show_expr (acc_clauses-num_workers_expr); + fputc (')', dumpfile); +} + if (acc_clauses-vector_length_expr) +{ + fputs ( VECTOR_LENGTH(, dumpfile); + show_expr (acc_clauses-vector_length_expr); + fputc (')', dumpfile); +} + if (acc_clauses-collapse) +{ + fputs ( COLLAPSE(, dumpfile); + fprintf (dumpfile, %d, acc_clauses-collapse); + fputc (')', dumpfile); +} + if (acc_clauses-gang) +{ + fputs ( GANG, dumpfile); + if (acc_clauses-gang_expr) +{ + fputc ('(', dumpfile); + show_expr (acc_clauses-gang_expr); + fputc (')', dumpfile); +} +} + if (acc_clauses-worker) +{ + fputs ( WORKER, dumpfile); + if (acc_clauses-worker_expr) +{ + fputc ('(', dumpfile); + show_expr (acc_clauses-worker_expr); + fputc (')', dumpfile); +} +} + if (acc_clauses-vector) +{ + fputs ( VECTOR, dumpfile); + if (acc_clauses-vector_expr) +{ + fputc ('(', dumpfile); + show_expr (acc_clauses-vector_expr); + fputc (')', dumpfile); +} +} + if (acc_clauses-non_clause_wait_expr) +{ + fputc ('(', dumpfile); + show_expr (acc_clauses-non_clause_wait_expr); + fputc (')', dumpfile); +} + if (acc_clauses-seq) +fputs ( SEQ, dumpfile); + if (acc_clauses-independent) +fputs ( INDEPENDENT, dumpfile); + for (list = 0; list
[PATCH 3/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From 0658580cf665b8da8cc4533901989b7a1d54f73a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:06:00 +0400 Subject: [PATCH 3/6] OpenACC fortran FE part 3 --- gcc/fortran/trans-decl.c | 7 + gcc/fortran/trans-openmp.c | 526 - gcc/fortran/trans-stmt.h | 4 + gcc/fortran/trans.c| 15 ++ 4 files changed, 543 insertions(+), 9 deletions(-) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index f974c6e..a7dde4f 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -5529,6 +5529,13 @@ gfc_generate_function_code (gfc_namespace * ns) if ((gfc_option.rtcheck GFC_RTCHECK_BOUNDS) !sym-attr.is_bind_c) add_argument_checking (body, sym); + /* Generate !$ACC DECLARE directive. */ + if (ns-declare_clauses) +{ + tmp = gfc_trans_oacc_declare(body, ns); + gfc_add_expr_to_block(body, tmp); +} + tmp = gfc_trans_code (ns-code); gfc_add_expr_to_block (body, tmp); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index d23af17..c43b375 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -418,6 +418,12 @@ gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type) } } +static inline tree +gfc_trans_oacc_add_clause (tree node, tree tail) +{ + OACC_CLAUSE_CHAIN (node) = tail; + return node; +} static inline tree gfc_trans_add_clause (tree node, tree tail) @@ -480,6 +486,27 @@ gfc_trans_omp_variable (gfc_symbol *sym) return t; } +static inline tree +gfc_trans_oacc_variable (gfc_symbol *sym) +{ + return gfc_trans_omp_variable (sym); +} + +static inline tree +gfc_convert_oacc_expr_to_tree (stmtblock_t *block, gfc_expr *expr) +{ + gfc_se se; + tree result; + + gfc_init_se (se, NULL ); + gfc_conv_expr (se, expr); + gfc_add_block_to_block (block, se.pre); + result = gfc_evaluate_now (se.expr, block); + gfc_add_block_to_block (block, se.post); + + return result; +} + static tree gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist, tree list) @@ -498,20 +525,33 @@ gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist, return list; } +static tree +gfc_trans_oacc_variable_list (enum omp_clause_code code, + gfc_namelist *namelist, tree list) +{ + return gfc_trans_omp_variable_list (code, namelist, list); +} + static void -gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) +gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where, + bool is_acc) { gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL; gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL; gfc_symbol init_val_sym, outer_sym, intrinsic_sym; gfc_expr *e1, *e2, *e3, *e4; gfc_ref *ref; - tree decl, backend_decl, stmt, type, outer_decl; + tree decl, backend_decl, stmt, type, outer_decl, prev_decl; + enum tree_code reduction_code; locus old_loc = gfc_current_locus; const char *iname; bool t; - decl = OMP_CLAUSE_DECL (c); + if (is_acc) +decl = prev_decl = OACC_CLAUSE_DECL (c); + else +decl = prev_decl = OMP_CLAUSE_DECL (c); + gfc_current_locus = where; type = TREE_TYPE (decl); outer_decl = create_tmp_var_raw (type, NULL); @@ -542,7 +582,7 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) outer_sym.attr.result = 0; outer_sym.attr.flavor = FL_VARIABLE; outer_sym.backend_decl = outer_decl; - if (decl != OMP_CLAUSE_DECL (c)) + if (decl != prev_decl) outer_sym.backend_decl = build_fold_indirect_ref (outer_decl); /* Create fake symtrees for it. */ @@ -587,7 +627,12 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) gcc_assert (t); iname = NULL; - switch (OMP_CLAUSE_REDUCTION_CODE (c)) + if (is_acc) +reduction_code = OACC_CLAUSE_REDUCTION_CODE (c); + else +reduction_code = OMP_CLAUSE_REDUCTION_CODE (c); + + switch (reduction_code) { case PLUS_EXPR: case MINUS_EXPR: @@ -702,7 +747,11 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); else poplevel (0, 0); - OMP_CLAUSE_REDUCTION_INIT (c) = stmt; + + if (is_acc) +OACC_CLAUSE_REDUCTION_INIT (c) = stmt; + else +OMP_CLAUSE_REDUCTION_INIT (c) = stmt; /* Create the merge statement list. */ pushlevel (); @@ -726,10 +775,18 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); else poplevel (0, 0); - OMP_CLAUSE_REDUCTION_MERGE (c) = stmt; /* And stick the placeholder VAR_DECL into the clause as well. */ - OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl; + if (is_acc) +{ + OACC_CLAUSE_REDUCTION_MERGE (c) = stmt
[PATCH 4/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From 37806068fffcab95a21b51829c900d49be14961d Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:08:05 +0400 Subject: [PATCH 4/6] OpenACC GENERIC nodes --- gcc/gimplify.c | 73 gcc/omp-low.c | 84 -- gcc/tree-core.h | 106 +- gcc/tree-pretty-print.c | 286 +++- gcc/tree-pretty-print.h | 7 ++ gcc/tree.c | 96 ++-- gcc/tree.def| 50 + gcc/tree.h | 95 +++- 8 files changed, 770 insertions(+), 27 deletions(-) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e45bed2..8af4368 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4274,6 +4274,15 @@ is_gimple_stmt (tree t) case ASM_EXPR: case STATEMENT_LIST: case OACC_PARALLEL: +case OACC_KERNELS: +case OACC_DATA: +case OACC_CACHE: +case OACC_WAIT: +case OACC_HOST_DATA: +case OACC_DECLARE: +case OACC_UPDATE: +case OACC_ENTER_DATA: +case OACC_EXIT_DATA: case OMP_PARALLEL: case OMP_FOR: case OMP_SIMD: @@ -6025,6 +6034,32 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, remove = true; break; + case OACC_CLAUSE_COPY: + case OACC_CLAUSE_COPYOUT: + case OACC_CLAUSE_CREATE: + case OACC_CLAUSE_PRESENT: + case OACC_CLAUSE_PRESENT_OR_COPY: + case OACC_CLAUSE_PRESENT_OR_COPYIN: + case OACC_CLAUSE_PRESENT_OR_COPYOUT: + case OACC_CLAUSE_PRESENT_OR_CREATE: + case OACC_CLAUSE_HOST: + case OACC_CLAUSE_DEVICE: + case OACC_CLAUSE_DEVICEPTR: + case OACC_CLAUSE_DEVICE_RESIDENT: + case OACC_CLAUSE_USE_DEVICE: + case OACC_CLAUSE_DELETE: + case OACC_CLAUSE_ASYNC: + case OACC_CLAUSE_GANG: + case OACC_CLAUSE_WAIT: + case OACC_NO_CLAUSE_WAIT: + case OACC_NO_CLAUSE_CACHE: + case OACC_CLAUSE_SEQ: + case OACC_CLAUSE_INDEPENDENT: + case OACC_CLAUSE_WORKER: + case OACC_CLAUSE_VECTOR: + case OACC_CLAUSE_NUM_GANGS: + case OACC_CLAUSE_NUM_WORKERS: + case OACC_CLAUSE_VECTOR_LENGTH: case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_UNTIED: @@ -6339,6 +6374,32 @@ gimplify_adjust_omp_clauses (tree *list_p) } break; + case OACC_CLAUSE_COPY: + case OACC_CLAUSE_COPYOUT: + case OACC_CLAUSE_CREATE: + case OACC_CLAUSE_PRESENT: + case OACC_CLAUSE_PRESENT_OR_COPY: + case OACC_CLAUSE_PRESENT_OR_COPYIN: + case OACC_CLAUSE_PRESENT_OR_COPYOUT: + case OACC_CLAUSE_PRESENT_OR_CREATE: + case OACC_CLAUSE_HOST: + case OACC_CLAUSE_DEVICE: + case OACC_CLAUSE_DEVICEPTR: + case OACC_CLAUSE_DEVICE_RESIDENT: + case OACC_CLAUSE_USE_DEVICE: + case OACC_CLAUSE_DELETE: + case OACC_CLAUSE_ASYNC: + case OACC_CLAUSE_GANG: + case OACC_CLAUSE_WAIT: + case OACC_NO_CLAUSE_WAIT: + case OACC_NO_CLAUSE_CACHE: + case OACC_CLAUSE_SEQ: + case OACC_CLAUSE_INDEPENDENT: + case OACC_CLAUSE_WORKER: + case OACC_CLAUSE_VECTOR: + case OACC_CLAUSE_NUM_GANGS: + case OACC_CLAUSE_NUM_WORKERS: + case OACC_CLAUSE_VECTOR_LENGTH: case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: @@ -7846,6 +7907,18 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ret = GS_ALL_DONE; break; + case OACC_KERNELS: + case OACC_DATA: + case OACC_CACHE: + case OACC_WAIT: + case OACC_HOST_DATA: + case OACC_DECLARE: + case OACC_UPDATE: + case OACC_ENTER_DATA: + case OACC_EXIT_DATA: +ret = GS_ALL_DONE; +break; + case OMP_PARALLEL: gimplify_omp_parallel (expr_p, pre_p); ret = GS_ALL_DONE; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index eb755c3..6da5977 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1543,10 +1543,12 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; /* FALLTHRU */ - case OMP_CLAUSE_FIRSTPRIVATE: - case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_LINEAR: gcc_assert (gimple_code (ctx-stmt) != GIMPLE_OACC_PARALLEL); +/* FALLTHRU. */ + + case OMP_CLAUSE_FIRSTPRIVATE: /* == OACC_CLAUSE_FIRSTPRIVATE. */ + case OMP_CLAUSE_REDUCTION: /* == OACC_CLAUSE_REDUCTION. */ decl = OMP_CLAUSE_DECL (c); do_private: if (is_variable_sized (decl)) @@ -1583,8 +1585,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; case OMP_CLAUSE_COPYPRIVATE: - case OMP_CLAUSE_COPYIN: gcc_assert (gimple_code (ctx-stmt) != GIMPLE_OACC_PARALLEL); +/* FALLTHRU. */ + + case OMP_CLAUSE_COPYIN: /* == OACC_CLAUSE_COPYIN. */ decl = OMP_CLAUSE_DECL (c); by_ref = use_pointer_for_field (decl, NULL); install_var_field (decl, by_ref, 3, ctx); @@ -1596,7 +1600,6 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; case OMP_CLAUSE_FINAL: - case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_NUM_TEAMS: case OMP_CLAUSE_THREAD_LIMIT: @@ -1605,6 +1608,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_DEPEND: gcc_assert (gimple_code (ctx
[PATCH 5/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From ae0ba17c51f6ed3529976a0cdf8f80046d1ed9b7 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:10:41 +0400 Subject: [PATCH 5/6] OpenACC fortran tests --- gcc/testsuite/gfortran.dg/goacc/branch.f95 | 55 + .../gfortran.dg/goacc/continuation-free-form.f95 | 24 ++ gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 | 261 + gcc/testsuite/gfortran.dg/goacc/data-tree.f95 | 32 +++ gcc/testsuite/gfortran.dg/goacc/declare-1.f95 | 11 + gcc/testsuite/gfortran.dg/goacc/declare.f95| 9 + .../gfortran.dg/goacc/directive-names.f95 | 19 ++ .../gfortran.dg/goacc/enter-exit-data.f95 | 89 +++ gcc/testsuite/gfortran.dg/goacc/goacc.exp | 36 +++ gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 | 12 + gcc/testsuite/gfortran.dg/goacc/if.f95 | 53 + gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 | 33 +++ gcc/testsuite/gfortran.dg/goacc/list.f95 | 111 + .../gfortran.dg/goacc/parallel-kernels-clauses.f95 | 96 .../gfortran.dg/goacc/parallel-kernels-regions.f95 | 56 + gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95 | 41 .../goacc/pure-elemental-procedures.f95| 46 gcc/testsuite/gfortran.dg/goacc/reduction.f95 | 139 +++ .../gfortran.dg/goacc/sentinel-free-form.f95 | 22 ++ .../gfortran.dg/goacc/several-directives.f95 | 7 + gcc/testsuite/gfortran.dg/goacc/sie.f95| 252 21 files changed, 1404 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/goacc/branch.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/data-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/declare-1.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/declare.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/directive-names.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/enter-exit-data.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/goacc.exp create mode 100644 gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/if.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/list.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/parallel-tree.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/reduction.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/several-directives.f95 create mode 100644 gcc/testsuite/gfortran.dg/goacc/sie.f95 diff --git a/gcc/testsuite/gfortran.dg/goacc/branch.f95 b/gcc/testsuite/gfortran.dg/goacc/branch.f95 new file mode 100644 index 000..e470ce2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/branch.f95 @@ -0,0 +1,55 @@ +! { dg-do compile } +! { dg-options -fopenacc } + +program test + implicit none + + integer :: i + + if (.true.) then + !$acc parallel + end if ! { dg-error Unexpected } + !$acc end parallel + end if + + if (.true.) then + !$acc kernels + end if ! { dg-error Unexpected } + !$acc end kernels + end if + + !$acc parallel + if (.true.) then + !$acc end parallel ! { dg-error Unexpected } + end if + !$acc end parallel + + !$acc kernels + if (.true.) then + !$acc end kernels ! { dg-error Unexpected } + end if + !$acc end kernels + + !$acc parallel + if (.true.) then + end if + !$acc end parallel + + !$acc kernels + if (.true.) then + end if + !$acc end kernels + + if (.true.) then + !$acc parallel + !$acc end parallel + end if + + if (.true.) then + !$acc kernels + !$acc end kernels + end if +10 i = 0 + + +end program test \ No newline at end of file diff --git a/gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 b/gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 new file mode 100644 index 000..df32d9c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/continuation-free-form.f95 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options -fopenacc } + +program test + implicit none + + integer :: i + real :: x + + !$acc parallel + !$acc loop ! continuation + !$acc reduction(+:x) + + ! this line must be ignored + !$acc ! kernels + do i = 1,10 + x = x + 0.3 + enddo + ! continuation must begin with sentinel + !$acc end parallel ! { dg-error Unclassifiable OpenACC directive } + ! loop + + print *, x +end \ No newline at end of file diff --git a/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 b/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 new file
[PATCH 6/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
From 668a50443d0a70a633707ec49759d9e8b6d00b1e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov i.usma...@samsung.com Date: Thu, 23 Jan 2014 21:26:50 +0400 Subject: [PATCH 6/6] OpenACC GENERIC docs --- gcc/doc/generic.texi | 40 1 file changed, 40 insertions(+) diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index d51033e..dd88489 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -2052,6 +2052,14 @@ edge. Rethrowing the exception is represented using @code{RESX_EXPR}. @node OpenMP @subsection OpenMP @tindex OACC_PARALLEL +@tindex OACC_KERNELS +@tindex OACC_DATA +@tindex OACC_HOST_DATA +@tindex OACC_UPDATE +@tindex OACC_ENTER_DATA +@tindex OACC_EXIT_DATA +@tindex OACC_WAIT +@tindex OACC_CACHE @tindex OMP_PARALLEL @tindex OMP_FOR @tindex OMP_SECTIONS @@ -2073,6 +2081,38 @@ clauses used by the OpenMP API @w{@uref{http://www.openmp.org/}}. Represents @code{#pragma acc parallel [clause1 @dots{} clauseN]}. +@item OACC_KERNELS + +Represents @code{#pragma acc kernels [clause1 @dots{} clauseN]}. + +@item OACC_DATA + +Represents @code{#pragma acc data [clause1 @dots{} clauseN]}. + +@item OACC_HOST_DATA + +Represents @code{#pragma acc host_data [clause1 @dots{} clauseN]}. + +@item OACC_UPDATE + +Represents @code{#pragma acc update [clause1 @dots{} clauseN]}. + +@item OACC_ENTER_DATA + +Represents @code{#pragma acc enter data [clause1 @dots{} clauseN]}. + +@item OACC_EXIT_DATA + +Represents @code{#pragma acc exit data [clause1 @dots{} clauseN]}. + +@item OACC_WAIT + +Represents @code{#pragma acc wait [(num @dots{})]}. + +@item OACC_CACHE + +Represents @code{#pragma acc cache (var @dots{})}. + @item OMP_PARALLEL Represents @code{#pragma omp parallel [clause1 @dots{} clauseN]}. It -- 1.8.3.2
[PATCH 7/6] [GOMP4] OpenACC 1.0+ support in fortran front-end
Finally, ChangeLog entry. 23-01-2014 Ilmir Usmanov i.usma...@samsung.com Add OpenACC 1.0 support to fortran FE and GENERIC, except loop directive and subarrays. gcc/fortran/ * decl.c (gfc_match_end): Match end of OpenACC region. * dump-parse-tree.c (show_oacc_node): New function to dump OpenACC executable statements. (show_code_node): Call it. * gfortran.h (ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA, ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_KERNELS_LOOP, ST_OACC_END_KERNELS_LOOP, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA): New statements. (gfc_exprlist): New structure to hold list of expressions. (OACC_LIST_PRIVATE, OACC_LIST_REDUCTION_FIRST, OACC_LIST_REDUCTION_LAST, OACC_LIST_COPY, OACC_LIST_FIRST, OACC_LIST_DATA_CLAUSE_FIRST, OACC_LIST_COPYIN, OACC_LIST_COPYOUT, OACC_LIST_CREATE, OACC_LIST_DELETE, OACC_LIST_PRESENT, OACC_LIST_PRESENT_OR_COPY, OACC_LIST_PRESENT_OR_COPYIN, OACC_LIST_PRESENT_OR_COPYOUT, OACC_LIST_PRESENT_OR_CREATE, OACC_LIST_DEVICEPTR, OACC_LIST_DATA_CLAUSE_LAST, OACC_LIST_USE_DEVICE, OACC_LIST_DEVICE_RESIDENT, OACC_LIST_HOST, OACC_LIST_DEVICE, OACC_LIST_CACHE, OACC_LIST_NUM): New types of list, allowed in clauses. (gfc_omp_clauses): Add OpenACC clauses. (gfc_oacc_clauses): Pseudo structure. (gfc_get_oacc_clauses): New function. (gfc_namespace): Add OpenACC declare directive clauses. (EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA): New executable statements. (gfc_free_exprlist): New function declaration. (gfc_resolve_oacc_directive): Likewise. (gfc_resolve_oacc_parallel_loop_blocks): Likewise. (gfc_resolve_oacc_blocks): Likewise. * match.c (match_exit_cycle): Add support of OpenACC regions and loops. * match.h (gfc_match_oacc_cache): New function declaration. (gfc_match_oacc_wait, gfc_match_oacc_update): Likewise. (gfc_match_oacc_declare, gfc_match_oacc_loop): Likewise. (gfc_match_oacc_host_data, gfc_match_oacc_data): Likewise. (gfc_match_oacc_kernels, gfc_match_oacc_kernels_loop): Likewise. (gfc_match_oacc_parallel, gfc_match_oacc_parallel_loop): Likewise. (gfc_match_oacc_enter_data, gfc_match_oacc_exit_data): Likewise. * parse.c (decode_oacc_directive): New function. (verify_token_free, verify_token_fixed): New helper functions. (next_free, next_fixed): Decode !$ACC sentinel. (case_executable): Add ST_OACC_UPDATE, ST_OACC_WAIT, ST_OACC_CACHE, ST_OACC_ENTER_DATA and ST_OACC_EXIT_DATA directives. (case_exec_markers): Add ST_OACC_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_KERNELS, ST_OACC_DATA, ST_OACC_HOST_DATA, ST_OACC_LOOP and ST_OACC_KERNELS_LOOP directives. (push_state): Initialize OpenACC declare clauses. (gfc_ascii_statement): Dump names of OpenACC directives. (verify_st_order): Verify OpenACC declare directive as declarative. (parse_spec): Push clauses to state stack when declare directive is parsed. (parse_oacc_structured_block, parse_oacc_loop): New functions. (parse_executable): Call them. (parse_progunit): Move declare clauses from state stack to namespace. * parse.h (COMP_OACC_STRUCTURED_BLOCK): New structured block to represent OpenACC region. (gfc_state_data): Add declare directive's clauses. * resolve.c (gfc_resolve_blocks): Resolve OpenACC directives. (resolve_code): Likewise. * scanner.c (openacc_flag, openacc_locus): New static variables. (skip_oacc_attribute, skip_omp_attribute): New helper functions. (skip_free_comments, skip_fixed_comments): Don't skip !$ACC sentinel. (gfc_next_char_literal): Support OpenACC directives. * st.c (gfc_free_statement): Free also OpenACC directives. * openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses. (gfc_free_exprlist): New function to clear expression list. (match_oacc_exprlist): New function to match expression list. (match_oacc_clause_gang): New function to match OpenACC 2.0 gang clauses. (OACC_CLAUSE_IF, OACC_CLAUSE_ASYNC, OACC_CLAUSE_NUM_GANGS, OACC_CLAUSE_NUM_WORKERS, OACC_CLAUSE_VECTOR_LENGTH, OACC_CLAUSE_REDUCTION, OACC_CLAUSE_COPY, OACC_CLAUSE_COPYIN, OACC_CLAUSE_COPYOUT