https://gcc.gnu.org/g:22ada6bbe4e66747dcf6ee121c20730685cf5b03

commit r17-1805-g22ada6bbe4e66747dcf6ee121c20730685cf5b03
Author: Paul-Antoine Arras <[email protected]>
Date:   Thu Jun 18 18:40:22 2026 +0200

    openmp: Add barrier kind to GOMP_barrier and GOMP_barrier_cancel
    
    GOMP_barrier is called for at least three distinct purposes: implicit
    barriers at the end of parallel/teams regions, implicit barriers at the
    end of worksharing constructs, and explicit `#pragma omp barrier'
    directives. OMPT requires distinguishing these in its sync-region
    callbacks.
    
    Create new, semantically equivalent functions GOMP_barrier_ext and
    GOMP_barrier_cancel_ext with an integer `kind' parameter. Update all 
compiler
    call sites to pass the appropriate constant. Preserve now unused functions
    GOMP_barrier and GOMP_barrier_cancel for backward compatibility.
    
    The `kind' parameter is accepted but not yet acted upon in libgomp; it
    is reserved for future OMPT instrumentation.
    
    gcc/c-family/ChangeLog:
    
            * c-omp.cc (c_finish_omp_barrier): Pass GOMP_BARRIER_EXPLICIT to
            GOMP_barrier_ext.
    
    gcc/cp/ChangeLog:
    
            * semantics.cc (finish_omp_barrier): Push GOMP_BARRIER_EXPLICIT
            onto the argument vector.
    
    gcc/fortran/ChangeLog:
    
            * trans-openmp.cc (gfc_trans_omp_barrier): Pass 
GOMP_BARRIER_EXPLICIT
            to GOMP_barrier_ext.
    
    gcc/ChangeLog:
    
            * omp-builtins.def (BUILT_IN_GOMP_BARRIER): Change function to
            GOMP_barrier_ext and type to BT_FN_VOID_INT.
            (BUILT_IN_GOMP_BARRIER_CANCEL): Change function to
            GOMP_barrier_cancel_ext and type to BT_FN_VOID_INT.
            * omp-expand.cc (expand_omp_for_static_nochunk): Pass
            GOMP_BARRIER_IMPLICIT_WORKSHARE to omp_build_barrier.
            (expand_omp_for_static_chunk): Likewise.
            (expand_omp_single): Likewise.
            * omp-general.cc (omp_build_barrier): Add kind parameter; pass it
            to GOMP_barrier_ext or GOMP_barrier_cancel_ext.
            * omp-general.h (omp_build_barrier): Update declaration to add
            kind parameter.
            * omp-low.cc (lower_rec_input_clauses): Determine barrier kind from
            the enclosing gimple statement code and pass it to 
omp_build_barrier.
            (lower_omp_for_scan): Pass GOMP_BARRIER_IMPLICIT_WORKSHARE to
            omp_build_barrier.
    
    include/ChangeLog:
    
            * gomp-constants.h (GOMP_BARRIER_IMPLICIT_PARALLEL): New macro.
            (GOMP_BARRIER_IMPLICIT_WORKSHARE): New macro.
            (GOMP_BARRIER_EXPLICIT): New macro.
    
    libgomp/ChangeLog:
    
            * barrier.c (GOMP_barrier_ext): New function.
            (GOMP_barrier_cancel_ext): Likewise.
            * libgomp_g.h (GOMP_barrier_ext): Declare.
            (GOMP_barrier_cancel_ext): Likewise.
            * libgomp.map (GOMP_6.0.2): Add GOMP_barrier_ext and
            GOMP_barrier_cancel_ext.
            * testsuite/libgomp.c/barrier-1.c: Update GOMP_barrier_ext calls to 
pass
            GOMP_BARRIER_EXPLICIT.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/gomp/barrier-1.C: Update scan dump.
            * g++.dg/gomp/tpl-barrier-1.C: Likewise.
            * gcc.dg/gomp/barrier-1.c: Likewise.
            * c-c++-common/gomp/implicit-barrier-1.c: New test.
            * gfortran.dg/gomp/lastprivate-allocatable-barrier-1.f90: New test.

Diff:
---
 gcc/c-family/c-omp.cc                              |   4 +-
 gcc/cp/semantics.cc                                |   1 +
 gcc/fortran/trans-openmp.cc                        |   4 +-
 gcc/omp-builtins.def                               |   8 +-
 gcc/omp-expand.cc                                  |  14 ++-
 gcc/omp-general.cc                                 |   5 +-
 gcc/omp-general.h                                  |   2 +-
 gcc/omp-low.cc                                     |  24 ++++-
 .../c-c++-common/gomp/implicit-barrier-1.c         | 102 +++++++++++++++++++++
 gcc/testsuite/g++.dg/gomp/barrier-1.C              |   2 +-
 gcc/testsuite/g++.dg/gomp/tpl-barrier-1.C          |   2 +-
 gcc/testsuite/gcc.dg/gomp/barrier-1.c              |   2 +-
 .../gomp/lastprivate-allocatable-barrier-1.f90     |  33 +++++++
 include/gomp-constants.h                           |   6 ++
 libgomp/barrier.c                                  |  30 ++++++
 libgomp/libgomp.map                                |   2 +
 libgomp/libgomp_g.h                                |   2 +
 libgomp/testsuite/libgomp.c/barrier-1.c            |   8 +-
 18 files changed, 229 insertions(+), 22 deletions(-)

diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 181dfb3c7b7b..006e54d1e3d9 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -175,7 +175,9 @@ c_finish_omp_barrier (location_t loc)
   tree x;
 
   x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
-  x = build_call_expr_loc (loc, x, 0);
+  x = build_call_expr_loc (loc, x, 1,
+                          build_int_cst (integer_type_node,
+                                         GOMP_BARRIER_EXPLICIT));
   add_stmt (x);
 }
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 684c6550345b..3a7e19c190a4 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12547,6 +12547,7 @@ finish_omp_barrier (void)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
   releasing_vec vec;
+  vec->quick_push (build_int_cst (integer_type_node, GOMP_BARRIER_EXPLICIT));
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   finish_expr_stmt (stmt);
 }
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 0f368d3d805e..8d5842685a55 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -6977,7 +6977,9 @@ static tree
 gfc_trans_omp_barrier (void)
 {
   tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
-  return build_call_expr_loc (input_location, decl, 0);
+  return build_call_expr_loc (input_location, decl, 1,
+                             build_int_cst (integer_type_node,
+                                            GOMP_BARRIER_EXPLICIT));
 }
 
 static tree
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index 82736e773407..0a9dde8f6187 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -98,10 +98,10 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_START, 
"GOMP_atomic_start",
                  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_END, "GOMP_atomic_end",
                  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
-DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER, "GOMP_barrier",
-                 BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
-DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER_CANCEL, "GOMP_barrier_cancel",
-                 BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER, "GOMP_barrier_ext", BT_FN_VOID_INT,
+                 ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER_CANCEL, "GOMP_barrier_cancel_ext",
+                 BT_FN_BOOL_INT, ATTR_NOTHROW_LEAF_LIST)
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT, "GOMP_taskwait",
                  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT_DEPEND, "GOMP_taskwait_depend",
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index de8889a96496..3d799d280329 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -5602,7 +5602,10 @@ expand_omp_for_static_nochunk (struct omp_region *region,
          gsi_insert_after (&gsi, g, GSI_SAME_STMT);
        }
       else
-       gsi_insert_after (&gsi, omp_build_barrier (t), GSI_SAME_STMT);
+       gsi_insert_after (&gsi,
+                         omp_build_barrier (t,
+                                            GOMP_BARRIER_IMPLICIT_WORKSHARE),
+                         GSI_SAME_STMT);
     }
   else if ((fd->have_pointer_condtemp || fd->have_scantemp)
           && !fd->have_nonctrl_scantemp)
@@ -6324,7 +6327,10 @@ expand_omp_for_static_chunk (struct omp_region *region,
          gsi_insert_after (&gsi, g, GSI_SAME_STMT);
        }
       else
-       gsi_insert_after (&gsi, omp_build_barrier (t), GSI_SAME_STMT);
+       gsi_insert_after (&gsi,
+                         omp_build_barrier (t,
+                                            GOMP_BARRIER_IMPLICIT_WORKSHARE),
+                         GSI_SAME_STMT);
     }
   else if (fd->have_pointer_condtemp)
     {
@@ -8702,7 +8708,9 @@ expand_omp_single (struct omp_region *region)
   if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
     {
       tree t = gimple_omp_return_lhs (gsi_stmt (si));
-      gsi_insert_after (&si, omp_build_barrier (t), GSI_SAME_STMT);
+      gsi_insert_after (&si,
+                       omp_build_barrier (t, GOMP_BARRIER_IMPLICIT_WORKSHARE),
+                       GSI_SAME_STMT);
     }
   gsi_remove (&si, true);
   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index d0307aeba88b..564fe858cdd4 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -920,11 +920,12 @@ omp_extract_for_data (gomp_for *for_stmt, struct 
omp_for_data *fd,
 /* Build a call to GOMP_barrier.  */
 
 gimple *
-omp_build_barrier (tree lhs)
+omp_build_barrier (tree lhs, int kind)
 {
   tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
                                           : BUILT_IN_GOMP_BARRIER);
-  gcall *g = gimple_build_call (fndecl, 0);
+  gcall *g = gimple_build_call (fndecl, 1,
+                               build_int_cst (integer_type_node, kind));
   if (lhs)
     gimple_call_set_lhs (g, lhs);
   return g;
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index a5126269650c..ebfe16d0a4fe 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -189,7 +189,7 @@ extern void omp_adjust_for_condition (location_t loc, enum 
tree_code *cond_code,
 extern tree omp_get_for_step_from_incr (location_t loc, tree incr);
 extern void omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
                                  struct omp_for_data_loop *loops);
-extern gimple *omp_build_barrier (tree lhs);
+extern gimple *omp_build_barrier (tree lhs, int kind);
 extern tree find_combined_omp_for (tree *, int *, void *);
 extern poly_uint64 omp_max_vf (bool);
 extern int omp_max_simt_vf (void);
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 9ac0da173a51..30a4d02f2e20 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -7043,7 +7043,25 @@ lower_rec_input_clauses (tree clauses, gimple_seq 
*ilist, gimple_seq *dlist,
       if (!is_task_ctx (ctx)
          && (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
              || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR))
-       gimple_seq_add_stmt (ilist, omp_build_barrier (NULL_TREE));
+       {
+         int barrier_kind;
+         switch (gimple_code (ctx->stmt))
+           {
+           case GIMPLE_OMP_SECTIONS:
+           case GIMPLE_OMP_SCOPE:
+           case GIMPLE_OMP_FOR:
+             barrier_kind = GOMP_BARRIER_IMPLICIT_WORKSHARE;
+             break;
+           case GIMPLE_OMP_PARALLEL:
+           case GIMPLE_OMP_TEAMS:
+             barrier_kind = GOMP_BARRIER_IMPLICIT_PARALLEL;
+             break;
+           default:
+             gcc_unreachable ();
+           }
+         gimple_seq_add_stmt (ilist,
+                              omp_build_barrier (NULL_TREE, barrier_kind));
+       }
     }
 
   /* If max_vf is non-zero, then we can use only a vectorization factor
@@ -11477,7 +11495,7 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq 
*dlist, gomp_for *stmt,
   g = gimple_build_label (lab1);
   gimple_seq_add_stmt (body_p, g);
 
-  g = omp_build_barrier (NULL);
+  g = omp_build_barrier (NULL, GOMP_BARRIER_IMPLICIT_WORKSHARE);
   gimple_seq_add_stmt (body_p, g);
 
   tree down = create_tmp_var (unsigned_type_node);
@@ -11594,7 +11612,7 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq 
*dlist, gomp_for *stmt,
   g = gimple_build_label (lab12);
   gimple_seq_add_stmt (body_p, g);
 
-  g = omp_build_barrier (NULL);
+  g = omp_build_barrier (NULL, GOMP_BARRIER_IMPLICIT_WORKSHARE);
   gimple_seq_add_stmt (body_p, g);
 
   g = gimple_build_cond (NE_EXPR, k, build_zero_cst (unsigned_type_node),
diff --git a/gcc/testsuite/c-c++-common/gomp/implicit-barrier-1.c 
b/gcc/testsuite/c-c++-common/gomp/implicit-barrier-1.c
new file mode 100644
index 000000000000..d53b424233f6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/implicit-barrier-1.c
@@ -0,0 +1,102 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-ompexp" } */
+
+/* Check that implicit barriers are emitted with the correct kind.  */
+
+void body (void);
+void bar (int);
+void foo (int);
+
+/* OMP for construct with static schedule (with and without chunk) -> workshare
+   barrier.  */
+void wfor (int n) {
+  int i;
+  #pragma omp for schedule(static)
+  for (i = 0; i < n; i++) bar (i);
+  #pragma omp for schedule(static, 4)
+  for (i = 0; i < n; i++) bar (i);
+}
+
+/* OMP for construct with inscan reduction -> workshare barrier.  */
+int r;
+void wfor_scan (int n)
+{
+  int i;
+  #pragma omp for reduction(inscan, + : r) private(i)
+  for (i = 0; i < n; i = i + 1)
+    {
+      {
+       bar (r);
+      }
+      #pragma omp scan inclusive(r)
+      {
+       foo (r);
+      }
+    }
+}
+
+/* OMP sections construct with firstprivate and lastprivate clauses -> 
workshare
+   barrier.  */
+int a;
+int wsections (void) {
+  #pragma omp sections firstprivate(a) lastprivate(a)
+  { foo (a); }
+  return a;
+}
+
+/* parallel with a copyin variable passed by reference (an aggregate, so
+   use_pointer_for_field is true) -> copyin_by_ref -> parallel barrier.  */
+int tp[64];
+#pragma omp threadprivate (tp)
+void pcopyin (void) {
+  #pragma omp parallel copyin(tp)
+  body ();
+}
+
+/* UDR whose initializer references omp_orig, used on a (non-task) parallel
+   construct -> reduction_omp_orig_ref -> parallel barrier.  */
+struct S { int s; };
+void combine (struct S *out, struct S *in);
+struct S init_from_orig (struct S *orig);
+void use (struct S *);
+
+#pragma omp declare reduction (+: struct S: combine (&omp_out, &omp_in)) \
+       initializer (omp_priv = init_from_orig (&omp_orig))
+
+void preduction_orig (struct S s) {
+  #pragma omp parallel reduction (+: s)
+  use (&s);
+}
+
+/* Same omp_orig UDR on a teams construct -> parallel barrier.  */
+void treduction_orig (struct S s) {
+  #pragma omp teams reduction (+: s)
+  use (&s);
+}
+
+/* Same omp_orig UDR on a scope construct -> workshare barrier.  */
+struct S gs;
+void sreduction_orig (void) {
+  #pragma omp parallel
+  #pragma omp scope reduction (+: gs)
+  use (&gs);
+}
+
+/* OMP single construct (without nowait) -> workshare barrier.  */
+void wsingle (void) {
+  #pragma omp single
+  body ();
+}
+
+/* OMP scope construct (without nowait) -> workshare barrier.  */
+void wscope (void) {
+  #pragma omp scope
+  body ();
+}
+
+/* GOMP_BARRIER_IMPLICIT_PARALLEL (0): pcopyin, preduction_orig,
+   treduction_orig.  */
+/* { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(0\\)" 3 "ompexp" } } 
*/
+/* GOMP_BARRIER_IMPLICIT_WORKSHARE (1): wfor (x2), wfor_scan (x2), wsections,
+   sreduction_orig, wsingle, wscope.  */
+/* { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(1\\)" 8 "ompexp" } } 
*/
diff --git a/gcc/testsuite/g++.dg/gomp/barrier-1.C 
b/gcc/testsuite/g++.dg/gomp/barrier-1.C
index 55f3035193ec..a601d85669f5 100644
--- a/gcc/testsuite/g++.dg/gomp/barrier-1.C
+++ b/gcc/testsuite/g++.dg/gomp/barrier-1.C
@@ -14,4 +14,4 @@ void f2(bool p)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "GOMP_barrier" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(2\\)" 2 "gimple" } } 
*/
diff --git a/gcc/testsuite/g++.dg/gomp/tpl-barrier-1.C 
b/gcc/testsuite/g++.dg/gomp/tpl-barrier-1.C
index b45cb1ee5cca..f198cddb5568 100644
--- a/gcc/testsuite/g++.dg/gomp/tpl-barrier-1.C
+++ b/gcc/testsuite/g++.dg/gomp/tpl-barrier-1.C
@@ -21,4 +21,4 @@ void f3 ()
   f2<0> (true);
 }
 
-// { dg-final { scan-tree-dump-times "GOMP_barrier" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "GOMP_barrier_ext" 2 "gimple" } }
diff --git a/gcc/testsuite/gcc.dg/gomp/barrier-1.c 
b/gcc/testsuite/gcc.dg/gomp/barrier-1.c
index 42c70e91163b..be874d38503b 100644
--- a/gcc/testsuite/gcc.dg/gomp/barrier-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/barrier-1.c
@@ -14,4 +14,4 @@ void f2(_Bool p)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "GOMP_barrier" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(2\\)" 2 "gimple" } } 
*/
diff --git 
a/gcc/testsuite/gfortran.dg/gomp/lastprivate-allocatable-barrier-1.f90 
b/gcc/testsuite/gfortran.dg/gomp/lastprivate-allocatable-barrier-1.f90
new file mode 100644
index 000000000000..48499f6a4c8b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/lastprivate-allocatable-barrier-1.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-omplower" }
+
+! A lastprivate allocatable (without a corresponding firstprivate) needs an
+! outer-variable reference (gfc_omp_private_outer_ref is true), which makes
+! lower_rec_input_clauses emit the implicit barrier.  The barrier kind
+! depends on the construct the clause ends up on:
+!   - combined "parallel do"     -> GOMP_BARRIER_IMPLICIT_PARALLEL  (0)
+!   - "do" enclosed in a "parallel" -> GOMP_BARRIER_IMPLICIT_WORKSHARE (1)
+
+subroutine parallel_case
+  integer, allocatable :: a(:)
+  integer :: i
+  !$omp parallel do lastprivate(a)
+  do i = 1, 1
+     a = [i]
+  end do
+end subroutine parallel_case
+
+subroutine workshare_case
+  integer, allocatable :: a(:)
+  integer :: i
+  !$omp parallel
+  !$omp do lastprivate(a)
+  do i = 1, 1
+     a = [i]
+  end do
+  !$omp end do
+  !$omp end parallel
+end subroutine workshare_case
+
+! { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(0\\)" 1 "omplower" } }
+! { dg-final { scan-tree-dump-times "GOMP_barrier_ext \\(1\\)" 1 "omplower" } }
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index def838a949d4..32bdedc9c4a8 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -435,4 +435,10 @@ enum gomp_map_kind
 /* Identifiers of device-specific target arguments.  */
 #define GOMP_TARGET_ARG_HSA_KERNEL_ATTRIBUTES  (1 << 8)
 
+/* GOMP_barrier{,_cancel}_ext argument.
+   TODO turn this into an enum?  */
+#define GOMP_BARRIER_IMPLICIT_PARALLEL 0
+#define GOMP_BARRIER_IMPLICIT_WORKSHARE 1
+#define GOMP_BARRIER_EXPLICIT 2
+
 #endif
diff --git a/libgomp/barrier.c b/libgomp/barrier.c
index 3a6037e43552..d11fd710b193 100644
--- a/libgomp/barrier.c
+++ b/libgomp/barrier.c
@@ -27,6 +27,8 @@
 
 #include "libgomp.h"
 
+/* GOMP_barrier is no longer called by new code; it is only kept for
+   backward compatibility. New code uses GOMP_barrier_ext.  */
 
 void
 GOMP_barrier (void)
@@ -41,6 +43,22 @@ GOMP_barrier (void)
   gomp_team_barrier_wait (&team->barrier);
 }
 
+void
+GOMP_barrier_ext (int kind __attribute__ ((unused)))
+{
+  struct gomp_thread *thr = gomp_thread ();
+  struct gomp_team *team = thr->ts.team;
+
+  /* It is legal to have orphaned barriers.  */
+  if (team == NULL)
+    return;
+
+  gomp_team_barrier_wait (&team->barrier);
+}
+
+/* GOMP_barrier_cancel is no longer called by new code; it is only kept for
+   backward compatibility. New code uses GOMP_barrier_cancel_ext.  */
+
 bool
 GOMP_barrier_cancel (void)
 {
@@ -52,3 +70,15 @@ GOMP_barrier_cancel (void)
      never have an orphaned cancellable barrier.  */
   return gomp_team_barrier_wait_cancel (&team->barrier);
 }
+
+bool
+GOMP_barrier_cancel_ext (int kind __attribute__ ((unused)))
+{
+  struct gomp_thread *thr = gomp_thread ();
+  struct gomp_team *team = thr->ts.team;
+
+  /* The compiler transforms to barrier_cancel when it sees that the
+     barrier is within a construct that can cancel.  Thus we should
+     never have an orphaned cancellable barrier.  */
+  return gomp_team_barrier_wait_cancel (&team->barrier);
+}
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index 4aa518ecdae7..92ef5c298f4d 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -487,6 +487,8 @@ GOMP_6.0.2 {
        GOMP_has_masked_thread_num;
        GOMP_loop_static_worksharing;
        GOMP_distribute_static_worksharing;
+       GOMP_barrier_ext;
+       GOMP_barrier_cancel_ext;
 } GOMP_6.0.1;
 
 OACC_2.0 {
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 6dc1fd46fcea..89ed7b3462e3 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -41,7 +41,9 @@ extern void GOMP_atomic_end (void);
 /* barrier.c */
 
 extern void GOMP_barrier (void);
+extern void GOMP_barrier_ext (int);
 extern bool GOMP_barrier_cancel (void);
+extern bool GOMP_barrier_cancel_ext (int);
 
 /* critical.c */
 
diff --git a/libgomp/testsuite/libgomp.c/barrier-1.c 
b/libgomp/testsuite/libgomp.c/barrier-1.c
index 1f8d1f0d3f98..1fe678a0a093 100644
--- a/libgomp/testsuite/libgomp.c/barrier-1.c
+++ b/libgomp/testsuite/libgomp.c/barrier-1.c
@@ -5,7 +5,7 @@
 #include <unistd.h>
 #include <assert.h>
 #include "libgomp_g.h"
-
+#include <gomp-constants.h>
 
 struct timeval stamps[3][3];
 
@@ -17,7 +17,7 @@ static void function(void *dummy)
   if (iam == 0)
     usleep (10);
 
-  GOMP_barrier ();
+  GOMP_barrier_ext (GOMP_BARRIER_EXPLICIT);
 
   if (iam == 0)
     {
@@ -25,8 +25,8 @@ static void function(void *dummy)
       usleep (10);
     }
 
-  GOMP_barrier ();
-  
+  GOMP_barrier_ext (GOMP_BARRIER_EXPLICIT);
+
   gettimeofday (&stamps[iam][2], NULL);
 }

Reply via email to