Hi Jakub!

On Wed, 10 Dec 2014 11:02:24 +0100, I wrote:
>     OpenACC: Rework nested constructs checking.
>     
>       gcc/
>       * omp-low.c (scan_omp_target): Remove taskreg_nesting_level and
>       target_nesting_level assertions.
>       (check_omp_nesting_restrictions): Rework OpenACC constructs
>       handling.  Update and extend the relevant test cases.

Regarding the check_omp_nesting_restrictions rework:

> --- gcc/omp-low.c
> +++ gcc/omp-low.c
> @@ -2706,46 +2700,26 @@ scan_omp_teams (gimple stmt, omp_context *outer_ctx)
>    scan_omp (gimple_omp_body_ptr (stmt), ctx);
>  }
>  
> -/* Check OpenMP nesting restrictions.  */
> +/* Check nesting restrictions.  */
>  static bool
>  check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
>  {
> -  /* TODO: While the OpenACC specification does allow for certain kinds of
> -     nesting, we don't support many of these yet.  */
> -  if (is_gimple_omp (stmt)
> -      && is_gimple_omp_oacc_specifically (stmt))
> +  /* TODO: Some OpenACC/OpenMP nesting should be allowed.  */
> +
> +  /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP 
> builtin)
> +     inside an OpenACC CTX.  */
> +  if (!(is_gimple_omp (stmt)
> +     && is_gimple_omp_oacc_specifically (stmt)))
>      {
> -      /* Regular handling of OpenACC loop constructs.  */
> -      if (gimple_code (stmt) == GIMPLE_OMP_FOR
> -       && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
> -     goto cont;
> -      /* No nesting of OpenACC STMT inside any OpenACC or OpenMP CTX 
> different
> -      from an OpenACC data construct.  */
> -      for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
> -     if (is_gimple_omp (ctx_->stmt)
> -         && !(gimple_code (ctx_->stmt) == GIMPLE_OMP_TARGET
> -              && (gimple_omp_target_kind (ctx_->stmt)
> -                  == GF_OMP_TARGET_KIND_OACC_DATA)))
> -       {
> -         error_at (gimple_location (stmt),
> -                   "may not be nested");
> -         return false;
> -       }
> -    }
> -  else
> -    {
> -      /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP
> -      builtin) inside any OpenACC CTX.  */
>        for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
>       if (is_gimple_omp (ctx_->stmt)
>           && is_gimple_omp_oacc_specifically (ctx_->stmt))
>         {
>           error_at (gimple_location (stmt),
> -                   "may not be nested");
> +                   "non-OpenACC construct inside of OpenACC region");
>           return false;
>         }
>      }
> - cont:
>  
>    if (ctx != NULL)
>      {
> @@ -3003,20 +2977,74 @@ check_omp_nesting_restrictions (gimple stmt, 
> omp_context *ctx)
>        break;
>      case GIMPLE_OMP_TARGET:
>        for (; ctx != NULL; ctx = ctx->outer)
> -     if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
> -         && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
> -       {
> -         const char *name;
> -         switch (gimple_omp_target_kind (stmt))
> -           {
> -           case GF_OMP_TARGET_KIND_REGION: name = "target"; break;
> -           case GF_OMP_TARGET_KIND_DATA: name = "target data"; break;
> -           case GF_OMP_TARGET_KIND_UPDATE: name = "target update"; break;
> -           default: gcc_unreachable ();
> -           }
> -         warning_at (gimple_location (stmt), 0,
> -                     "%s construct inside of target region", name);
> -       }
> +     {
> +       if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
> +         {
> +           if (is_gimple_omp (stmt)
> +               && is_gimple_omp_oacc_specifically (stmt)
> +               && is_gimple_omp (ctx->stmt))
> +             {
> +               error_at (gimple_location (stmt),
> +                         "OpenACC construct inside of non-OpenACC region");
> +               return false;
> +             }
> +           continue;
> +         }
> +
> +       const char *stmt_name, *ctx_stmt_name;
> +       switch (gimple_omp_target_kind (stmt))
> +         {
> +         case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
> +         case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
> +         case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
> +         case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; 
> break;
> +         case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
> +         case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
> +         case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
> +         case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = 
> "enter/exit data"; break;
> +         default: gcc_unreachable ();
> +         }
> +       switch (gimple_omp_target_kind (ctx->stmt))
> +         {
> +         case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
> +         case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
> +         case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; 
> break;
> +         case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; 
> break;
> +         case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
> +         default: gcc_unreachable ();
> +         }
> +
> +       /* OpenACC/OpenMP mismatch?  */
> +       if (is_gimple_omp_oacc_specifically (stmt)
> +           != is_gimple_omp_oacc_specifically (ctx->stmt))
> +         {
> +           error_at (gimple_location (stmt),
> +                     "%s %s construct inside of %s %s region",
> +                     (is_gimple_omp_oacc_specifically (stmt)
> +                      ? "OpenACC" : "OpenMP"), stmt_name,
> +                     (is_gimple_omp_oacc_specifically (ctx->stmt)
> +                      ? "OpenACC" : "OpenMP"), ctx_stmt_name);
> +           return false;
> +         }
> +       if (is_gimple_omp_offloaded (ctx->stmt))
> +         {
> +           /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
> +           if (is_gimple_omp_oacc_specifically (ctx->stmt))
> +             {
> +               error_at (gimple_location (stmt),
> +                         "%s construct inside of %s region",
> +                         stmt_name, ctx_stmt_name);
> +               return false;
> +             }
> +           else
> +             {
> +               gcc_assert (!is_gimple_omp_oacc_specifically (stmt));
> +               warning_at (gimple_location (stmt), 0,
> +                           "%s construct inside of %s region",
> +                           stmt_name, ctx_stmt_name);
> +             }
> +         }
> +     }
>        break;
>      default:
>        break;

For guarding against OpenMP target regressions, I used the following
tests -- OK to commit to trunk?

 gcc/testsuite/c-c++-common/gomp/nesting-1.c      | 77 ++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c | 23 +++++++
 2 files changed, 100 insertions(+)

diff --git gcc/testsuite/c-c++-common/gomp/nesting-1.c 
gcc/testsuite/c-c++-common/gomp/nesting-1.c
new file mode 100644
index 0000000..70b3e8d
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/nesting-1.c
@@ -0,0 +1,77 @@
+void
+f_omp_parallel (void)
+{
+#pragma omp parallel
+  {
+    int i;
+
+#pragma omp parallel
+    ;
+
+#pragma omp target
+    ;
+
+#pragma omp target data
+    ;
+
+#pragma omp target update to(i)
+
+#pragma omp target data
+    {
+#pragma omp parallel
+      ;
+
+#pragma omp target
+      ;
+
+#pragma omp target data
+      ;
+
+#pragma omp target update to(i)
+    }
+  }
+}
+
+void
+f_omp_target (void)
+{
+#pragma omp target
+  {
+#pragma omp parallel
+    ;
+  }
+}
+
+void
+f_omp_target_data (void)
+{
+#pragma omp target data
+  {
+    int i;
+
+#pragma omp parallel
+    ;
+
+#pragma omp target
+    ;
+
+#pragma omp target data
+    ;
+
+#pragma omp target update to(i)
+
+#pragma omp target data
+    {
+#pragma omp parallel
+      ;
+
+#pragma omp target
+      ;
+
+#pragma omp target data
+      ;
+
+#pragma omp target update to(i)
+    }
+  }
+}
diff --git gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c 
gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c
new file mode 100644
index 0000000..6a65699
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c
@@ -0,0 +1,23 @@
+void
+f_omp_target (void)
+{
+#pragma omp target
+  {
+    int i;
+
+#pragma omp target /* { dg-warning "target construct inside of target region" 
} */
+    ;
+#pragma omp target data /* { dg-warning "target data construct inside of 
target region" } */
+    ;
+#pragma omp target update to(i) /* { dg-warning "target update construct 
inside of target region" } */
+
+#pragma omp parallel
+    {
+#pragma omp target /* { dg-warning "target construct inside of target region" 
} */
+      ;
+#pragma omp target data /* { dg-warning "target data construct inside of 
target region" } */
+      ;
+#pragma omp target update to(i) /* { dg-warning "target update construct 
inside of target region" } */
+    }
+  }
+}


Grüße,
 Thomas

Attachment: signature.asc
Description: PGP signature

Reply via email to