xref: /freebsd-src/contrib/llvm-project/openmp/runtime/src/kmp_gsupport.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric /*
20b57cec5SDimitry Andric  * kmp_gsupport.cpp
30b57cec5SDimitry Andric  */
40b57cec5SDimitry Andric 
50b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "kmp.h"
140b57cec5SDimitry Andric #include "kmp_atomic.h"
155f757f3fSDimitry Andric #include "kmp_utils.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #if OMPT_SUPPORT
180b57cec5SDimitry Andric #include "ompt-specific.h"
190b57cec5SDimitry Andric #endif
200b57cec5SDimitry Andric 
21e8d8bef9SDimitry Andric enum {
22e8d8bef9SDimitry Andric   KMP_GOMP_TASK_UNTIED_FLAG = 1,
23e8d8bef9SDimitry Andric   KMP_GOMP_TASK_FINAL_FLAG = 2,
24e8d8bef9SDimitry Andric   KMP_GOMP_TASK_DEPENDS_FLAG = 8
25e8d8bef9SDimitry Andric };
26e8d8bef9SDimitry Andric 
27349cc55cSDimitry Andric enum {
28349cc55cSDimitry Andric   KMP_GOMP_DEPOBJ_IN = 1,
29349cc55cSDimitry Andric   KMP_GOMP_DEPOBJ_OUT = 2,
30349cc55cSDimitry Andric   KMP_GOMP_DEPOBJ_INOUT = 3,
31349cc55cSDimitry Andric   KMP_GOMP_DEPOBJ_MTXINOUTSET = 4
32349cc55cSDimitry Andric };
33349cc55cSDimitry Andric 
34e8d8bef9SDimitry Andric // This class helps convert gomp dependency info into
35e8d8bef9SDimitry Andric // kmp_depend_info_t structures
36e8d8bef9SDimitry Andric class kmp_gomp_depends_info_t {
37e8d8bef9SDimitry Andric   void **depend;
38e8d8bef9SDimitry Andric   kmp_int32 num_deps;
39349cc55cSDimitry Andric   size_t num_out, num_mutexinout, num_in, num_depobj;
40e8d8bef9SDimitry Andric   size_t offset;
41e8d8bef9SDimitry Andric 
42e8d8bef9SDimitry Andric public:
43e8d8bef9SDimitry Andric   kmp_gomp_depends_info_t(void **depend) : depend(depend) {
44e8d8bef9SDimitry Andric     size_t ndeps = (kmp_intptr_t)depend[0];
45e8d8bef9SDimitry Andric     // GOMP taskdep structure:
46e8d8bef9SDimitry Andric     // if depend[0] != 0:
47e8d8bef9SDimitry Andric     // depend =  [ ndeps | nout | &out | ... | &out | &in | ... | &in ]
48e8d8bef9SDimitry Andric     //
49e8d8bef9SDimitry Andric     // if depend[0] == 0:
50e8d8bef9SDimitry Andric     // depend = [ 0 | ndeps | nout | nmtx | nin | &out | ... | &out | &mtx |
51e8d8bef9SDimitry Andric     //            ... | &mtx | &in   | ...  | &in  | &depobj | ... | &depobj ]
52e8d8bef9SDimitry Andric     if (ndeps) {
53e8d8bef9SDimitry Andric       num_out = (kmp_intptr_t)depend[1];
54e8d8bef9SDimitry Andric       num_in = ndeps - num_out;
55349cc55cSDimitry Andric       num_mutexinout = num_depobj = 0;
56e8d8bef9SDimitry Andric       offset = 2;
57e8d8bef9SDimitry Andric     } else {
58e8d8bef9SDimitry Andric       ndeps = (kmp_intptr_t)depend[1];
59e8d8bef9SDimitry Andric       num_out = (kmp_intptr_t)depend[2];
60e8d8bef9SDimitry Andric       num_mutexinout = (kmp_intptr_t)depend[3];
61e8d8bef9SDimitry Andric       num_in = (kmp_intptr_t)depend[4];
62349cc55cSDimitry Andric       num_depobj = ndeps - num_out - num_mutexinout - num_in;
63349cc55cSDimitry Andric       KMP_ASSERT(num_depobj <= ndeps);
64e8d8bef9SDimitry Andric       offset = 5;
65e8d8bef9SDimitry Andric     }
66e8d8bef9SDimitry Andric     num_deps = static_cast<kmp_int32>(ndeps);
67e8d8bef9SDimitry Andric   }
68e8d8bef9SDimitry Andric   kmp_int32 get_num_deps() const { return num_deps; }
69e8d8bef9SDimitry Andric   kmp_depend_info_t get_kmp_depend(size_t index) const {
70e8d8bef9SDimitry Andric     kmp_depend_info_t retval;
71e8d8bef9SDimitry Andric     memset(&retval, '\0', sizeof(retval));
72e8d8bef9SDimitry Andric     KMP_ASSERT(index < (size_t)num_deps);
73e8d8bef9SDimitry Andric     retval.len = 0;
74e8d8bef9SDimitry Andric     // Because inout and out are logically equivalent,
75e8d8bef9SDimitry Andric     // use inout and in dependency flags. GOMP does not provide a
76e8d8bef9SDimitry Andric     // way to distinguish if user specified out vs. inout.
77e8d8bef9SDimitry Andric     if (index < num_out) {
78e8d8bef9SDimitry Andric       retval.flags.in = 1;
79e8d8bef9SDimitry Andric       retval.flags.out = 1;
80349cc55cSDimitry Andric       retval.base_addr = (kmp_intptr_t)depend[offset + index];
81e8d8bef9SDimitry Andric     } else if (index >= num_out && index < (num_out + num_mutexinout)) {
82e8d8bef9SDimitry Andric       retval.flags.mtx = 1;
83349cc55cSDimitry Andric       retval.base_addr = (kmp_intptr_t)depend[offset + index];
84349cc55cSDimitry Andric     } else if (index >= (num_out + num_mutexinout) &&
85349cc55cSDimitry Andric                index < (num_out + num_mutexinout + num_in)) {
86e8d8bef9SDimitry Andric       retval.flags.in = 1;
87349cc55cSDimitry Andric       retval.base_addr = (kmp_intptr_t)depend[offset + index];
88349cc55cSDimitry Andric     } else {
89349cc55cSDimitry Andric       // depobj is a two element array (size of elements are size of pointer)
90349cc55cSDimitry Andric       // depobj[0] = base_addr
91349cc55cSDimitry Andric       // depobj[1] = type (in, out, inout, mutexinoutset, etc.)
92349cc55cSDimitry Andric       kmp_intptr_t *depobj = (kmp_intptr_t *)depend[offset + index];
93349cc55cSDimitry Andric       retval.base_addr = depobj[0];
94349cc55cSDimitry Andric       switch (depobj[1]) {
95349cc55cSDimitry Andric       case KMP_GOMP_DEPOBJ_IN:
96349cc55cSDimitry Andric         retval.flags.in = 1;
97349cc55cSDimitry Andric         break;
98349cc55cSDimitry Andric       case KMP_GOMP_DEPOBJ_OUT:
99349cc55cSDimitry Andric         retval.flags.out = 1;
100349cc55cSDimitry Andric         break;
101349cc55cSDimitry Andric       case KMP_GOMP_DEPOBJ_INOUT:
102349cc55cSDimitry Andric         retval.flags.in = 1;
103349cc55cSDimitry Andric         retval.flags.out = 1;
104349cc55cSDimitry Andric         break;
105349cc55cSDimitry Andric       case KMP_GOMP_DEPOBJ_MTXINOUTSET:
106349cc55cSDimitry Andric         retval.flags.mtx = 1;
107349cc55cSDimitry Andric         break;
108349cc55cSDimitry Andric       default:
109349cc55cSDimitry Andric         KMP_FATAL(GompFeatureNotSupported, "Unknown depobj type");
110349cc55cSDimitry Andric       }
111e8d8bef9SDimitry Andric     }
112e8d8bef9SDimitry Andric     return retval;
113e8d8bef9SDimitry Andric   }
114e8d8bef9SDimitry Andric };
115e8d8bef9SDimitry Andric 
1160b57cec5SDimitry Andric #ifdef __cplusplus
1170b57cec5SDimitry Andric extern "C" {
1180b57cec5SDimitry Andric #endif // __cplusplus
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric #define MKLOC(loc, routine)                                                    \
121489b1cf2SDimitry Andric   static ident_t loc = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"};
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric #include "kmp_ftn_os.h"
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER)(void) {
1260b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
1270b57cec5SDimitry Andric   MKLOC(loc, "GOMP_barrier");
1280b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_barrier: T#%d\n", gtid));
1290b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1300b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
1310b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
1320b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
1330b57cec5SDimitry Andric     ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1340b57cec5SDimitry Andric   }
135e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
1360b57cec5SDimitry Andric #endif
1370b57cec5SDimitry Andric   __kmpc_barrier(&loc, gtid);
1380b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1390b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
1400b57cec5SDimitry Andric     ompt_frame->enter_frame = ompt_data_none;
1410b57cec5SDimitry Andric   }
1420b57cec5SDimitry Andric #endif
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric // Mutual exclusion
1460b57cec5SDimitry Andric 
14774626c16SDimitry Andric // The symbol that icc/ifort generates for unnamed critical sections
1480b57cec5SDimitry Andric // - .gomp_critical_user_ - is defined using .comm in any objects reference it.
1490b57cec5SDimitry Andric // We can't reference it directly here in C code, as the symbol contains a ".".
1500b57cec5SDimitry Andric //
1510b57cec5SDimitry Andric // The RTL contains an assembly language definition of .gomp_critical_user_
1520b57cec5SDimitry Andric // with another symbol __kmp_unnamed_critical_addr initialized with it's
1530b57cec5SDimitry Andric // address.
1540b57cec5SDimitry Andric extern kmp_critical_name *__kmp_unnamed_critical_addr;
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_START)(void) {
1570b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
1580b57cec5SDimitry Andric   MKLOC(loc, "GOMP_critical_start");
1590b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_critical_start: T#%d\n", gtid));
1600b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1610b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
1620b57cec5SDimitry Andric #endif
1630b57cec5SDimitry Andric   __kmpc_critical(&loc, gtid, __kmp_unnamed_critical_addr);
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_END)(void) {
1670b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
1680b57cec5SDimitry Andric   MKLOC(loc, "GOMP_critical_end");
1690b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_critical_end: T#%d\n", gtid));
1700b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1710b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
1720b57cec5SDimitry Andric #endif
1730b57cec5SDimitry Andric   __kmpc_end_critical(&loc, gtid, __kmp_unnamed_critical_addr);
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_START)(void **pptr) {
1770b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
1780b57cec5SDimitry Andric   MKLOC(loc, "GOMP_critical_name_start");
1790b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_critical_name_start: T#%d\n", gtid));
1800b57cec5SDimitry Andric   __kmpc_critical(&loc, gtid, (kmp_critical_name *)pptr);
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_END)(void **pptr) {
1840b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
1850b57cec5SDimitry Andric   MKLOC(loc, "GOMP_critical_name_end");
1860b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_critical_name_end: T#%d\n", gtid));
1870b57cec5SDimitry Andric   __kmpc_end_critical(&loc, gtid, (kmp_critical_name *)pptr);
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric // The Gnu codegen tries to use locked operations to perform atomic updates
1910b57cec5SDimitry Andric // inline.  If it can't, then it calls GOMP_atomic_start() before performing
1920b57cec5SDimitry Andric // the update and GOMP_atomic_end() afterward, regardless of the data type.
1930b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_START)(void) {
1940b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
1950b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid));
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric #if OMPT_SUPPORT
1980b57cec5SDimitry Andric   __ompt_thread_assign_wait_id(0);
1990b57cec5SDimitry Andric #endif
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_END)(void) {
2050b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
2060b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_atomic_end: T#%d\n", gtid));
2070b57cec5SDimitry Andric   __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric int KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_START)(void) {
2110b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
2120b57cec5SDimitry Andric   MKLOC(loc, "GOMP_single_start");
2130b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_single_start: T#%d\n", gtid));
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_parallel))
2160b57cec5SDimitry Andric     __kmp_parallel_initialize();
2170b57cec5SDimitry Andric   __kmp_resume_if_soft_paused();
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // 3rd parameter == FALSE prevents kmp_enter_single from pushing a
2200b57cec5SDimitry Andric   // workshare when USE_CHECKS is defined.  We need to avoid the push,
2210b57cec5SDimitry Andric   // as there is no corresponding GOMP_single_end() call.
2220b57cec5SDimitry Andric   kmp_int32 rc = __kmp_enter_single(gtid, &loc, FALSE);
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2250b57cec5SDimitry Andric   kmp_info_t *this_thr = __kmp_threads[gtid];
2260b57cec5SDimitry Andric   kmp_team_t *team = this_thr->th.th_team;
2270b57cec5SDimitry Andric   int tid = __kmp_tid_from_gtid(gtid);
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
2300b57cec5SDimitry Andric     if (rc) {
2310b57cec5SDimitry Andric       if (ompt_enabled.ompt_callback_work) {
2320b57cec5SDimitry Andric         ompt_callbacks.ompt_callback(ompt_callback_work)(
2330b57cec5SDimitry Andric             ompt_work_single_executor, ompt_scope_begin,
2340b57cec5SDimitry Andric             &(team->t.ompt_team_info.parallel_data),
2350b57cec5SDimitry Andric             &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
2360b57cec5SDimitry Andric             1, OMPT_GET_RETURN_ADDRESS(0));
2370b57cec5SDimitry Andric       }
2380b57cec5SDimitry Andric     } else {
2390b57cec5SDimitry Andric       if (ompt_enabled.ompt_callback_work) {
2400b57cec5SDimitry Andric         ompt_callbacks.ompt_callback(ompt_callback_work)(
2410b57cec5SDimitry Andric             ompt_work_single_other, ompt_scope_begin,
2420b57cec5SDimitry Andric             &(team->t.ompt_team_info.parallel_data),
2430b57cec5SDimitry Andric             &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
2440b57cec5SDimitry Andric             1, OMPT_GET_RETURN_ADDRESS(0));
2450b57cec5SDimitry Andric         ompt_callbacks.ompt_callback(ompt_callback_work)(
2460b57cec5SDimitry Andric             ompt_work_single_other, ompt_scope_end,
2470b57cec5SDimitry Andric             &(team->t.ompt_team_info.parallel_data),
2480b57cec5SDimitry Andric             &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
2490b57cec5SDimitry Andric             1, OMPT_GET_RETURN_ADDRESS(0));
2500b57cec5SDimitry Andric       }
2510b57cec5SDimitry Andric     }
2520b57cec5SDimitry Andric   }
2530b57cec5SDimitry Andric #endif
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   return rc;
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_START)(void) {
2590b57cec5SDimitry Andric   void *retval;
2600b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
2610b57cec5SDimitry Andric   MKLOC(loc, "GOMP_single_copy_start");
2620b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_single_copy_start: T#%d\n", gtid));
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_parallel))
2650b57cec5SDimitry Andric     __kmp_parallel_initialize();
2660b57cec5SDimitry Andric   __kmp_resume_if_soft_paused();
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   // If this is the first thread to enter, return NULL.  The generated code will
2690b57cec5SDimitry Andric   // then call GOMP_single_copy_end() for this thread only, with the
2700b57cec5SDimitry Andric   // copyprivate data pointer as an argument.
2710b57cec5SDimitry Andric   if (__kmp_enter_single(gtid, &loc, FALSE))
2720b57cec5SDimitry Andric     return NULL;
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric     // Wait for the first thread to set the copyprivate data pointer,
2750b57cec5SDimitry Andric     // and for all other threads to reach this point.
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2780b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
2790b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
2800b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
2810b57cec5SDimitry Andric     ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
2820b57cec5SDimitry Andric   }
283e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
2840b57cec5SDimitry Andric #endif
2850b57cec5SDimitry Andric   __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   // Retrieve the value of the copyprivate data point, and wait for all
2880b57cec5SDimitry Andric   // threads to do likewise, then return.
2890b57cec5SDimitry Andric   retval = __kmp_team_from_gtid(gtid)->t.t_copypriv_data;
290e8d8bef9SDimitry Andric   {
2910b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2920b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
2930b57cec5SDimitry Andric #endif
2940b57cec5SDimitry Andric     __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
295e8d8bef9SDimitry Andric   }
2960b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2970b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
2980b57cec5SDimitry Andric     ompt_frame->enter_frame = ompt_data_none;
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric #endif
3010b57cec5SDimitry Andric   return retval;
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_END)(void *data) {
3050b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
3060b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_single_copy_end: T#%d\n", gtid));
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   // Set the copyprivate data pointer fo the team, then hit the barrier so that
3090b57cec5SDimitry Andric   // the other threads will continue on and read it.  Hit another barrier before
3100b57cec5SDimitry Andric   // continuing, so that the know that the copyprivate data pointer has been
3110b57cec5SDimitry Andric   // propagated to all threads before trying to reuse the t_copypriv_data field.
3120b57cec5SDimitry Andric   __kmp_team_from_gtid(gtid)->t.t_copypriv_data = data;
3130b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
3140b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
3150b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
3160b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
3170b57cec5SDimitry Andric     ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
3180b57cec5SDimitry Andric   }
319e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
3200b57cec5SDimitry Andric #endif
3210b57cec5SDimitry Andric   __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
322e8d8bef9SDimitry Andric   {
3230b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
3240b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
3250b57cec5SDimitry Andric #endif
3260b57cec5SDimitry Andric     __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
327e8d8bef9SDimitry Andric   }
3280b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
3290b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
3300b57cec5SDimitry Andric     ompt_frame->enter_frame = ompt_data_none;
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric #endif
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_START)(void) {
3360b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
3370b57cec5SDimitry Andric   MKLOC(loc, "GOMP_ordered_start");
3380b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
3390b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
3400b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
3410b57cec5SDimitry Andric #endif
3420b57cec5SDimitry Andric   __kmpc_ordered(&loc, gtid);
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_END)(void) {
3460b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
3470b57cec5SDimitry Andric   MKLOC(loc, "GOMP_ordered_end");
3480b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
3490b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
3500b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
3510b57cec5SDimitry Andric #endif
3520b57cec5SDimitry Andric   __kmpc_end_ordered(&loc, gtid);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric // Dispatch macro defs
3560b57cec5SDimitry Andric //
3570b57cec5SDimitry Andric // They come in two flavors: 64-bit unsigned, and either 32-bit signed
3580b57cec5SDimitry Andric // (IA-32 architecture) or 64-bit signed (Intel(R) 64).
3590b57cec5SDimitry Andric 
3601db9f3b2SDimitry Andric #if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS || KMP_ARCH_WASM ||          \
361*0fca6ea1SDimitry Andric     KMP_ARCH_PPC || KMP_ARCH_AARCH64_32
3620b57cec5SDimitry Andric #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4
3630b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4
3640b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4
3650b57cec5SDimitry Andric #else
3660b57cec5SDimitry Andric #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_8
3670b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_8
3680b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_8
3690b57cec5SDimitry Andric #endif /* KMP_ARCH_X86 */
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric #define KMP_DISPATCH_INIT_ULL __kmp_aux_dispatch_init_8u
3720b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK_ULL __kmp_aux_dispatch_fini_chunk_8u
3730b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT_ULL __kmpc_dispatch_next_8u
3740b57cec5SDimitry Andric 
3755ffd83dbSDimitry Andric // The parallel construct
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric #ifndef KMP_DEBUG
3780b57cec5SDimitry Andric static
3790b57cec5SDimitry Andric #endif /* KMP_DEBUG */
3800b57cec5SDimitry Andric     void
3810b57cec5SDimitry Andric     __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *),
3820b57cec5SDimitry Andric                                  void *data) {
3830b57cec5SDimitry Andric #if OMPT_SUPPORT
3840b57cec5SDimitry Andric   kmp_info_t *thr;
3850b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
3860b57cec5SDimitry Andric   ompt_state_t enclosing_state;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
3890b57cec5SDimitry Andric     // get pointer to thread data structure
3900b57cec5SDimitry Andric     thr = __kmp_threads[*gtid];
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric     // save enclosing task state; set current state for task
3930b57cec5SDimitry Andric     enclosing_state = thr->th.ompt_thread_info.state;
3940b57cec5SDimitry Andric     thr->th.ompt_thread_info.state = ompt_state_work_parallel;
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric     // set task frame
3970b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
3980b57cec5SDimitry Andric     ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric #endif
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   task(data);
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric #if OMPT_SUPPORT
4050b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
4060b57cec5SDimitry Andric     // clear task frame
4070b57cec5SDimitry Andric     ompt_frame->exit_frame = ompt_data_none;
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric     // restore enclosing state
4100b57cec5SDimitry Andric     thr->th.ompt_thread_info.state = enclosing_state;
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric #endif
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric #ifndef KMP_DEBUG
4160b57cec5SDimitry Andric static
4170b57cec5SDimitry Andric #endif /* KMP_DEBUG */
4180b57cec5SDimitry Andric     void
4190b57cec5SDimitry Andric     __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr,
4200b57cec5SDimitry Andric                                           void (*task)(void *), void *data,
4210b57cec5SDimitry Andric                                           unsigned num_threads, ident_t *loc,
4220b57cec5SDimitry Andric                                           enum sched_type schedule, long start,
4230b57cec5SDimitry Andric                                           long end, long incr,
4240b57cec5SDimitry Andric                                           long chunk_size) {
4255ffd83dbSDimitry Andric   // Initialize the loop worksharing construct.
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   KMP_DISPATCH_INIT(loc, *gtid, schedule, start, end, incr, chunk_size,
4280b57cec5SDimitry Andric                     schedule != kmp_sch_static);
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric #if OMPT_SUPPORT
4310b57cec5SDimitry Andric   kmp_info_t *thr;
4320b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
4330b57cec5SDimitry Andric   ompt_state_t enclosing_state;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
4360b57cec5SDimitry Andric     thr = __kmp_threads[*gtid];
4370b57cec5SDimitry Andric     // save enclosing task state; set current state for task
4380b57cec5SDimitry Andric     enclosing_state = thr->th.ompt_thread_info.state;
4390b57cec5SDimitry Andric     thr->th.ompt_thread_info.state = ompt_state_work_parallel;
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric     // set task frame
4420b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
4430b57cec5SDimitry Andric     ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric #endif
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   // Now invoke the microtask.
4480b57cec5SDimitry Andric   task(data);
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric #if OMPT_SUPPORT
4510b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
4520b57cec5SDimitry Andric     // clear task frame
4530b57cec5SDimitry Andric     ompt_frame->exit_frame = ompt_data_none;
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric     // reset enclosing state
4560b57cec5SDimitry Andric     thr->th.ompt_thread_info.state = enclosing_state;
4570b57cec5SDimitry Andric   }
4580b57cec5SDimitry Andric #endif
4590b57cec5SDimitry Andric }
4600b57cec5SDimitry Andric 
461e8d8bef9SDimitry Andric static void __kmp_GOMP_fork_call(ident_t *loc, int gtid, unsigned num_threads,
462e8d8bef9SDimitry Andric                                  unsigned flags, void (*unwrapped_task)(void *),
4630b57cec5SDimitry Andric                                  microtask_t wrapper, int argc, ...) {
4640b57cec5SDimitry Andric   int rc;
4650b57cec5SDimitry Andric   kmp_info_t *thr = __kmp_threads[gtid];
4660b57cec5SDimitry Andric   kmp_team_t *team = thr->th.th_team;
4670b57cec5SDimitry Andric   int tid = __kmp_tid_from_gtid(gtid);
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   va_list ap;
4700b57cec5SDimitry Andric   va_start(ap, argc);
4710b57cec5SDimitry Andric 
472e8d8bef9SDimitry Andric   if (num_threads != 0)
473e8d8bef9SDimitry Andric     __kmp_push_num_threads(loc, gtid, num_threads);
474e8d8bef9SDimitry Andric   if (flags != 0)
475e8d8bef9SDimitry Andric     __kmp_push_proc_bind(loc, gtid, (kmp_proc_bind_t)flags);
4760b57cec5SDimitry Andric   rc = __kmp_fork_call(loc, gtid, fork_context_gnu, argc, wrapper,
47716794618SDimitry Andric                        __kmp_invoke_task_func, kmp_va_addr_of(ap));
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   va_end(ap);
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   if (rc) {
4820b57cec5SDimitry Andric     __kmp_run_before_invoked_task(gtid, tid, thr, team);
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric #if OMPT_SUPPORT
4860b57cec5SDimitry Andric   int ompt_team_size;
4870b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
4880b57cec5SDimitry Andric     ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
4890b57cec5SDimitry Andric     ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric     // implicit task callback
4920b57cec5SDimitry Andric     if (ompt_enabled.ompt_callback_implicit_task) {
4930b57cec5SDimitry Andric       ompt_team_size = __kmp_team_from_gtid(gtid)->t.t_nproc;
4940b57cec5SDimitry Andric       ompt_callbacks.ompt_callback(ompt_callback_implicit_task)(
4950b57cec5SDimitry Andric           ompt_scope_begin, &(team_info->parallel_data),
496fe6060f1SDimitry Andric           &(task_info->task_data), ompt_team_size, __kmp_tid_from_gtid(gtid),
497fe6060f1SDimitry Andric           ompt_task_implicit); // TODO: Can this be ompt_task_initial?
4980b57cec5SDimitry Andric       task_info->thread_num = __kmp_tid_from_gtid(gtid);
4990b57cec5SDimitry Andric     }
5000b57cec5SDimitry Andric     thr->th.ompt_thread_info.state = ompt_state_work_parallel;
5010b57cec5SDimitry Andric   }
5020b57cec5SDimitry Andric #endif
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *),
5060b57cec5SDimitry Andric                                                        void *data,
5070b57cec5SDimitry Andric                                                        unsigned num_threads) {
5080b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric #if OMPT_SUPPORT
5110b57cec5SDimitry Andric   ompt_frame_t *parent_frame, *frame;
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
5140b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL);
5150b57cec5SDimitry Andric     parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
5160b57cec5SDimitry Andric   }
517e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
5180b57cec5SDimitry Andric #endif
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   MKLOC(loc, "GOMP_parallel_start");
5210b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_start: T#%d\n", gtid));
522e8d8bef9SDimitry Andric   __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task,
5230b57cec5SDimitry Andric                        (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task,
5240b57cec5SDimitry Andric                        data);
5250b57cec5SDimitry Andric #if OMPT_SUPPORT
5260b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
5270b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &frame, NULL, NULL);
5280b57cec5SDimitry Andric     frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
5290b57cec5SDimitry Andric   }
5300b57cec5SDimitry Andric #endif
531fe6060f1SDimitry Andric #if OMPD_SUPPORT
532fe6060f1SDimitry Andric   if (ompd_state & OMPD_ENABLE_BP)
533fe6060f1SDimitry Andric     ompd_bp_parallel_begin();
534fe6060f1SDimitry Andric #endif
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(void) {
5380b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
5390b57cec5SDimitry Andric   kmp_info_t *thr;
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric   thr = __kmp_threads[gtid];
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   MKLOC(loc, "GOMP_parallel_end");
5440b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_end: T#%d\n", gtid));
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   if (!thr->th.th_team->t.t_serialized) {
5470b57cec5SDimitry Andric     __kmp_run_after_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr,
5480b57cec5SDimitry Andric                                  thr->th.th_team);
549e8d8bef9SDimitry Andric   }
5500b57cec5SDimitry Andric #if OMPT_SUPPORT
5510b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
5520b57cec5SDimitry Andric     // Implicit task is finished here, in the barrier we might schedule
5530b57cec5SDimitry Andric     // deferred tasks,
5540b57cec5SDimitry Andric     // these don't see the implicit task on the stack
5550b57cec5SDimitry Andric     OMPT_CUR_TASK_INFO(thr)->frame.exit_frame = ompt_data_none;
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric #endif
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   __kmp_join_call(&loc, gtid
5600b57cec5SDimitry Andric #if OMPT_SUPPORT
5610b57cec5SDimitry Andric                   ,
5620b57cec5SDimitry Andric                   fork_context_gnu
5630b57cec5SDimitry Andric #endif
5640b57cec5SDimitry Andric   );
565fe6060f1SDimitry Andric #if OMPD_SUPPORT
566fe6060f1SDimitry Andric   if (ompd_state & OMPD_ENABLE_BP)
567fe6060f1SDimitry Andric     ompd_bp_parallel_end();
568fe6060f1SDimitry Andric #endif
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric // Loop worksharing constructs
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric // The Gnu codegen passes in an exclusive upper bound for the overall range,
5740b57cec5SDimitry Andric // but the libguide dispatch code expects an inclusive upper bound, hence the
5750b57cec5SDimitry Andric // "end - incr" 5th argument to KMP_DISPATCH_INIT (and the " ub - str" 11th
5760b57cec5SDimitry Andric // argument to __kmp_GOMP_fork_call).
5770b57cec5SDimitry Andric //
5780b57cec5SDimitry Andric // Conversely, KMP_DISPATCH_NEXT returns and inclusive upper bound in *p_ub,
579480093f4SDimitry Andric // but the Gnu codegen expects an exclusive upper bound, so the adjustment
580480093f4SDimitry Andric // "*p_ub += stride" compensates for the discrepancy.
5810b57cec5SDimitry Andric //
5820b57cec5SDimitry Andric // Correction: the gnu codegen always adjusts the upper bound by +-1, not the
5830b57cec5SDimitry Andric // stride value.  We adjust the dispatch parameters accordingly (by +-1), but
5840b57cec5SDimitry Andric // we still adjust p_ub by the actual stride value.
5850b57cec5SDimitry Andric //
5860b57cec5SDimitry Andric // The "runtime" versions do not take a chunk_sz parameter.
5870b57cec5SDimitry Andric //
5880b57cec5SDimitry Andric // The profile lib cannot support construct checking of unordered loops that
5890b57cec5SDimitry Andric // are predetermined by the compiler to be statically scheduled, as the gcc
5900b57cec5SDimitry Andric // codegen will not always emit calls to GOMP_loop_static_next() to get the
5910b57cec5SDimitry Andric // next iteration.  Instead, it emits inline code to call omp_get_thread_num()
5920b57cec5SDimitry Andric // num and calculate the iteration space using the result.  It doesn't do this
5930b57cec5SDimitry Andric // with ordered static loop, so they can be checked.
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric #if OMPT_SUPPORT
5960b57cec5SDimitry Andric #define IF_OMPT_SUPPORT(code) code
5970b57cec5SDimitry Andric #else
5980b57cec5SDimitry Andric #define IF_OMPT_SUPPORT(code)
5990b57cec5SDimitry Andric #endif
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric #define LOOP_START(func, schedule)                                             \
6020b57cec5SDimitry Andric   int func(long lb, long ub, long str, long chunk_sz, long *p_lb,              \
6030b57cec5SDimitry Andric            long *p_ub) {                                                       \
6040b57cec5SDimitry Andric     int status;                                                                \
6050b57cec5SDimitry Andric     long stride;                                                               \
6060b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
6070b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
6080b57cec5SDimitry Andric     KA_TRACE(                                                                  \
6090b57cec5SDimitry Andric         20,                                                                    \
6100b57cec5SDimitry Andric         (KMP_STR(                                                              \
6110b57cec5SDimitry Andric              func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n",  \
6120b57cec5SDimitry Andric          gtid, lb, ub, str, chunk_sz));                                        \
6130b57cec5SDimitry Andric                                                                                \
6140b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
615e8d8bef9SDimitry Andric       {                                                                        \
6160b57cec5SDimitry Andric         IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                      \
6170b57cec5SDimitry Andric         KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                          \
6180b57cec5SDimitry Andric                           (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,      \
6190b57cec5SDimitry Andric                           (schedule) != kmp_sch_static);                       \
620e8d8bef9SDimitry Andric       }                                                                        \
621e8d8bef9SDimitry Andric       {                                                                        \
6220b57cec5SDimitry Andric         IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                      \
6230b57cec5SDimitry Andric         status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb,          \
6240b57cec5SDimitry Andric                                    (kmp_int *)p_ub, (kmp_int *)&stride);       \
625e8d8bef9SDimitry Andric       }                                                                        \
6260b57cec5SDimitry Andric       if (status) {                                                            \
6270b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
6280b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
6290b57cec5SDimitry Andric       }                                                                        \
6300b57cec5SDimitry Andric     } else {                                                                   \
6310b57cec5SDimitry Andric       status = 0;                                                              \
6320b57cec5SDimitry Andric     }                                                                          \
6330b57cec5SDimitry Andric                                                                                \
6340b57cec5SDimitry Andric     KA_TRACE(                                                                  \
6350b57cec5SDimitry Andric         20,                                                                    \
6360b57cec5SDimitry Andric         (KMP_STR(                                                              \
6370b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n",    \
6380b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
6390b57cec5SDimitry Andric     return status;                                                             \
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric #define LOOP_RUNTIME_START(func, schedule)                                     \
6430b57cec5SDimitry Andric   int func(long lb, long ub, long str, long *p_lb, long *p_ub) {               \
6440b57cec5SDimitry Andric     int status;                                                                \
6450b57cec5SDimitry Andric     long stride;                                                               \
6460b57cec5SDimitry Andric     long chunk_sz = 0;                                                         \
6470b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
6480b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
6490b57cec5SDimitry Andric     KA_TRACE(                                                                  \
6500b57cec5SDimitry Andric         20,                                                                    \
6510b57cec5SDimitry Andric         (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \
6520b57cec5SDimitry Andric          gtid, lb, ub, str, chunk_sz));                                        \
6530b57cec5SDimitry Andric                                                                                \
6540b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
655e8d8bef9SDimitry Andric       {                                                                        \
6560b57cec5SDimitry Andric         IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                      \
6570b57cec5SDimitry Andric         KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                          \
658e8d8bef9SDimitry Andric                           (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,      \
659e8d8bef9SDimitry Andric                           TRUE);                                               \
660e8d8bef9SDimitry Andric       }                                                                        \
661e8d8bef9SDimitry Andric       {                                                                        \
6620b57cec5SDimitry Andric         IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                      \
6630b57cec5SDimitry Andric         status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb,          \
6640b57cec5SDimitry Andric                                    (kmp_int *)p_ub, (kmp_int *)&stride);       \
665e8d8bef9SDimitry Andric       }                                                                        \
6660b57cec5SDimitry Andric       if (status) {                                                            \
6670b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
6680b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
6690b57cec5SDimitry Andric       }                                                                        \
6700b57cec5SDimitry Andric     } else {                                                                   \
6710b57cec5SDimitry Andric       status = 0;                                                              \
6720b57cec5SDimitry Andric     }                                                                          \
6730b57cec5SDimitry Andric                                                                                \
6740b57cec5SDimitry Andric     KA_TRACE(                                                                  \
6750b57cec5SDimitry Andric         20,                                                                    \
6760b57cec5SDimitry Andric         (KMP_STR(                                                              \
6770b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n",    \
6780b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
6790b57cec5SDimitry Andric     return status;                                                             \
6800b57cec5SDimitry Andric   }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric #define KMP_DOACROSS_FINI(status, gtid)                                        \
6830b57cec5SDimitry Andric   if (!status && __kmp_threads[gtid]->th.th_dispatch->th_doacross_flags) {     \
6840b57cec5SDimitry Andric     __kmpc_doacross_fini(NULL, gtid);                                          \
6850b57cec5SDimitry Andric   }
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric #define LOOP_NEXT(func, fini_code)                                             \
6880b57cec5SDimitry Andric   int func(long *p_lb, long *p_ub) {                                           \
6890b57cec5SDimitry Andric     int status;                                                                \
6900b57cec5SDimitry Andric     long stride;                                                               \
6910b57cec5SDimitry Andric     int gtid = __kmp_get_gtid();                                               \
6920b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
6930b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid));                            \
6940b57cec5SDimitry Andric                                                                                \
6950b57cec5SDimitry Andric     IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                          \
6960b57cec5SDimitry Andric     fini_code status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb,    \
6970b57cec5SDimitry Andric                                          (kmp_int *)p_ub, (kmp_int *)&stride); \
6980b57cec5SDimitry Andric     if (status) {                                                              \
6990b57cec5SDimitry Andric       *p_ub += (stride > 0) ? 1 : -1;                                          \
7000b57cec5SDimitry Andric     }                                                                          \
7010b57cec5SDimitry Andric     KMP_DOACROSS_FINI(status, gtid)                                            \
7020b57cec5SDimitry Andric                                                                                \
7030b57cec5SDimitry Andric     KA_TRACE(                                                                  \
7040b57cec5SDimitry Andric         20,                                                                    \
7050b57cec5SDimitry Andric         (KMP_STR(func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, stride 0x%lx, " \
7060b57cec5SDimitry Andric                        "returning %d\n",                                       \
7070b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, stride, status));                                 \
7080b57cec5SDimitry Andric     return status;                                                             \
7090b57cec5SDimitry Andric   }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START), kmp_sch_static)
7120b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT), {})
7130b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START),
7140b57cec5SDimitry Andric            kmp_sch_dynamic_chunked)
715489b1cf2SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START),
716489b1cf2SDimitry Andric            kmp_sch_dynamic_chunked)
7170b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT), {})
718489b1cf2SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT), {})
7190b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START),
7200b57cec5SDimitry Andric            kmp_sch_guided_chunked)
721489b1cf2SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START),
722489b1cf2SDimitry Andric            kmp_sch_guided_chunked)
7230b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT), {})
724489b1cf2SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT), {})
7250b57cec5SDimitry Andric LOOP_RUNTIME_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START),
7260b57cec5SDimitry Andric                    kmp_sch_runtime)
7270b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT), {})
7285ffd83dbSDimitry Andric LOOP_RUNTIME_START(
7295ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START),
7305ffd83dbSDimitry Andric     kmp_sch_runtime)
7315ffd83dbSDimitry Andric LOOP_RUNTIME_START(
7325ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START),
7335ffd83dbSDimitry Andric     kmp_sch_runtime)
7345ffd83dbSDimitry Andric LOOP_NEXT(
7355ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT), {})
7365ffd83dbSDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT), {})
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START),
7390b57cec5SDimitry Andric            kmp_ord_static)
7400b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT),
7410b57cec5SDimitry Andric           { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
7420b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START),
7430b57cec5SDimitry Andric            kmp_ord_dynamic_chunked)
7440b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT),
7450b57cec5SDimitry Andric           { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
7460b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START),
7470b57cec5SDimitry Andric            kmp_ord_guided_chunked)
7480b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT),
7490b57cec5SDimitry Andric           { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
7500b57cec5SDimitry Andric LOOP_RUNTIME_START(
7510b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START),
7520b57cec5SDimitry Andric     kmp_ord_runtime)
7530b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT),
7540b57cec5SDimitry Andric           { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric #define LOOP_DOACROSS_START(func, schedule)                                    \
7570b57cec5SDimitry Andric   bool func(unsigned ncounts, long *counts, long chunk_sz, long *p_lb,         \
7580b57cec5SDimitry Andric             long *p_ub) {                                                      \
7590b57cec5SDimitry Andric     int status;                                                                \
7600b57cec5SDimitry Andric     long stride, lb, ub, str;                                                  \
7610b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
7620b57cec5SDimitry Andric     struct kmp_dim *dims =                                                     \
7630b57cec5SDimitry Andric         (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts);    \
7640b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
7650b57cec5SDimitry Andric     for (unsigned i = 0; i < ncounts; ++i) {                                   \
7660b57cec5SDimitry Andric       dims[i].lo = 0;                                                          \
7670b57cec5SDimitry Andric       dims[i].up = counts[i] - 1;                                              \
7680b57cec5SDimitry Andric       dims[i].st = 1;                                                          \
7690b57cec5SDimitry Andric     }                                                                          \
7700b57cec5SDimitry Andric     __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims);                      \
7710b57cec5SDimitry Andric     lb = 0;                                                                    \
7720b57cec5SDimitry Andric     ub = counts[0];                                                            \
7730b57cec5SDimitry Andric     str = 1;                                                                   \
7740b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d, ncounts %u, lb 0x%lx, ub 0x%lx, str " \
7750b57cec5SDimitry Andric                                 "0x%lx, chunk_sz "                             \
7760b57cec5SDimitry Andric                                 "0x%lx\n",                                     \
7770b57cec5SDimitry Andric                   gtid, ncounts, lb, ub, str, chunk_sz));                      \
7780b57cec5SDimitry Andric                                                                                \
7790b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
7800b57cec5SDimitry Andric       KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                            \
7810b57cec5SDimitry Andric                         (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,        \
7820b57cec5SDimitry Andric                         (schedule) != kmp_sch_static);                         \
7830b57cec5SDimitry Andric       status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb,            \
7840b57cec5SDimitry Andric                                  (kmp_int *)p_ub, (kmp_int *)&stride);         \
7850b57cec5SDimitry Andric       if (status) {                                                            \
7860b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
7870b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
7880b57cec5SDimitry Andric       }                                                                        \
7890b57cec5SDimitry Andric     } else {                                                                   \
7900b57cec5SDimitry Andric       status = 0;                                                              \
7910b57cec5SDimitry Andric     }                                                                          \
7920b57cec5SDimitry Andric     KMP_DOACROSS_FINI(status, gtid);                                           \
7930b57cec5SDimitry Andric                                                                                \
7940b57cec5SDimitry Andric     KA_TRACE(                                                                  \
7950b57cec5SDimitry Andric         20,                                                                    \
7960b57cec5SDimitry Andric         (KMP_STR(                                                              \
7970b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n",    \
7980b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
7990b57cec5SDimitry Andric     __kmp_free(dims);                                                          \
8000b57cec5SDimitry Andric     return status;                                                             \
8010b57cec5SDimitry Andric   }
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric #define LOOP_DOACROSS_RUNTIME_START(func, schedule)                            \
8040b57cec5SDimitry Andric   int func(unsigned ncounts, long *counts, long *p_lb, long *p_ub) {           \
8050b57cec5SDimitry Andric     int status;                                                                \
8060b57cec5SDimitry Andric     long stride, lb, ub, str;                                                  \
8070b57cec5SDimitry Andric     long chunk_sz = 0;                                                         \
8080b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
8090b57cec5SDimitry Andric     struct kmp_dim *dims =                                                     \
8100b57cec5SDimitry Andric         (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts);    \
8110b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
8120b57cec5SDimitry Andric     for (unsigned i = 0; i < ncounts; ++i) {                                   \
8130b57cec5SDimitry Andric       dims[i].lo = 0;                                                          \
8140b57cec5SDimitry Andric       dims[i].up = counts[i] - 1;                                              \
8150b57cec5SDimitry Andric       dims[i].st = 1;                                                          \
8160b57cec5SDimitry Andric     }                                                                          \
8170b57cec5SDimitry Andric     __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims);                      \
8180b57cec5SDimitry Andric     lb = 0;                                                                    \
8190b57cec5SDimitry Andric     ub = counts[0];                                                            \
8200b57cec5SDimitry Andric     str = 1;                                                                   \
8210b57cec5SDimitry Andric     KA_TRACE(                                                                  \
8220b57cec5SDimitry Andric         20,                                                                    \
8230b57cec5SDimitry Andric         (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \
8240b57cec5SDimitry Andric          gtid, lb, ub, str, chunk_sz));                                        \
8250b57cec5SDimitry Andric                                                                                \
8260b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
8270b57cec5SDimitry Andric       KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                            \
8280b57cec5SDimitry Andric                         (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, TRUE); \
8290b57cec5SDimitry Andric       status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb,            \
8300b57cec5SDimitry Andric                                  (kmp_int *)p_ub, (kmp_int *)&stride);         \
8310b57cec5SDimitry Andric       if (status) {                                                            \
8320b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
8330b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
8340b57cec5SDimitry Andric       }                                                                        \
8350b57cec5SDimitry Andric     } else {                                                                   \
8360b57cec5SDimitry Andric       status = 0;                                                              \
8370b57cec5SDimitry Andric     }                                                                          \
8380b57cec5SDimitry Andric     KMP_DOACROSS_FINI(status, gtid);                                           \
8390b57cec5SDimitry Andric                                                                                \
8400b57cec5SDimitry Andric     KA_TRACE(                                                                  \
8410b57cec5SDimitry Andric         20,                                                                    \
8420b57cec5SDimitry Andric         (KMP_STR(                                                              \
8430b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n",    \
8440b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
8450b57cec5SDimitry Andric     __kmp_free(dims);                                                          \
8460b57cec5SDimitry Andric     return status;                                                             \
8470b57cec5SDimitry Andric   }
8480b57cec5SDimitry Andric 
8490b57cec5SDimitry Andric LOOP_DOACROSS_START(
8500b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START),
8510b57cec5SDimitry Andric     kmp_sch_static)
8520b57cec5SDimitry Andric LOOP_DOACROSS_START(
8530b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START),
8540b57cec5SDimitry Andric     kmp_sch_dynamic_chunked)
8550b57cec5SDimitry Andric LOOP_DOACROSS_START(
8560b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START),
8570b57cec5SDimitry Andric     kmp_sch_guided_chunked)
8580b57cec5SDimitry Andric LOOP_DOACROSS_RUNTIME_START(
8590b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START),
8600b57cec5SDimitry Andric     kmp_sch_runtime)
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END)(void) {
8630b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
8640b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_loop_end: T#%d\n", gtid))
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
8670b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
8680b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
8690b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
8700b57cec5SDimitry Andric     ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
8710b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
8720b57cec5SDimitry Andric   }
8730b57cec5SDimitry Andric #endif
8740b57cec5SDimitry Andric   __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
8750b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
8760b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
8770b57cec5SDimitry Andric     ompt_frame->enter_frame = ompt_data_none;
8780b57cec5SDimitry Andric   }
8790b57cec5SDimitry Andric #endif
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_loop_end exit: T#%d\n", gtid))
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_NOWAIT)(void) {
8850b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_loop_end_nowait: T#%d\n", __kmp_get_gtid()))
8860b57cec5SDimitry Andric }
8870b57cec5SDimitry Andric 
8880b57cec5SDimitry Andric // Unsigned long long loop worksharing constructs
8890b57cec5SDimitry Andric //
8900b57cec5SDimitry Andric // These are new with gcc 4.4
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric #define LOOP_START_ULL(func, schedule)                                         \
8930b57cec5SDimitry Andric   int func(int up, unsigned long long lb, unsigned long long ub,               \
8940b57cec5SDimitry Andric            unsigned long long str, unsigned long long chunk_sz,                \
8950b57cec5SDimitry Andric            unsigned long long *p_lb, unsigned long long *p_ub) {               \
8960b57cec5SDimitry Andric     int status;                                                                \
8970b57cec5SDimitry Andric     long long str2 = up ? ((long long)str) : -((long long)str);                \
8980b57cec5SDimitry Andric     long long stride;                                                          \
8990b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
9000b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
9010b57cec5SDimitry Andric                                                                                \
9020b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str "    \
9030b57cec5SDimitry Andric                                 "0x%llx, chunk_sz 0x%llx\n",                   \
9040b57cec5SDimitry Andric                   gtid, up, lb, ub, str, chunk_sz));                           \
9050b57cec5SDimitry Andric                                                                                \
9060b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
9070b57cec5SDimitry Andric       KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb,                        \
9080b57cec5SDimitry Andric                             (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz,  \
9090b57cec5SDimitry Andric                             (schedule) != kmp_sch_static);                     \
9100b57cec5SDimitry Andric       status =                                                                 \
9110b57cec5SDimitry Andric           KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb,          \
9120b57cec5SDimitry Andric                                 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride);     \
9130b57cec5SDimitry Andric       if (status) {                                                            \
9140b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str2);                                      \
9150b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
9160b57cec5SDimitry Andric       }                                                                        \
9170b57cec5SDimitry Andric     } else {                                                                   \
9180b57cec5SDimitry Andric       status = 0;                                                              \
9190b57cec5SDimitry Andric     }                                                                          \
9200b57cec5SDimitry Andric                                                                                \
9210b57cec5SDimitry Andric     KA_TRACE(                                                                  \
9220b57cec5SDimitry Andric         20,                                                                    \
9230b57cec5SDimitry Andric         (KMP_STR(                                                              \
9240b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n",  \
9250b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
9260b57cec5SDimitry Andric     return status;                                                             \
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric #define LOOP_RUNTIME_START_ULL(func, schedule)                                 \
9300b57cec5SDimitry Andric   int func(int up, unsigned long long lb, unsigned long long ub,               \
9310b57cec5SDimitry Andric            unsigned long long str, unsigned long long *p_lb,                   \
9320b57cec5SDimitry Andric            unsigned long long *p_ub) {                                         \
9330b57cec5SDimitry Andric     int status;                                                                \
9340b57cec5SDimitry Andric     long long str2 = up ? ((long long)str) : -((long long)str);                \
9350b57cec5SDimitry Andric     unsigned long long stride;                                                 \
9360b57cec5SDimitry Andric     unsigned long long chunk_sz = 0;                                           \
9370b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
9380b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
9390b57cec5SDimitry Andric                                                                                \
9400b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str "    \
9410b57cec5SDimitry Andric                                 "0x%llx, chunk_sz 0x%llx\n",                   \
9420b57cec5SDimitry Andric                   gtid, up, lb, ub, str, chunk_sz));                           \
9430b57cec5SDimitry Andric                                                                                \
9440b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
9450b57cec5SDimitry Andric       KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb,                        \
9460b57cec5SDimitry Andric                             (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz,  \
9470b57cec5SDimitry Andric                             TRUE);                                             \
9480b57cec5SDimitry Andric       status =                                                                 \
9490b57cec5SDimitry Andric           KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb,          \
9500b57cec5SDimitry Andric                                 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride);     \
9510b57cec5SDimitry Andric       if (status) {                                                            \
9520b57cec5SDimitry Andric         KMP_DEBUG_ASSERT((long long)stride == str2);                           \
9530b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
9540b57cec5SDimitry Andric       }                                                                        \
9550b57cec5SDimitry Andric     } else {                                                                   \
9560b57cec5SDimitry Andric       status = 0;                                                              \
9570b57cec5SDimitry Andric     }                                                                          \
9580b57cec5SDimitry Andric                                                                                \
9590b57cec5SDimitry Andric     KA_TRACE(                                                                  \
9600b57cec5SDimitry Andric         20,                                                                    \
9610b57cec5SDimitry Andric         (KMP_STR(                                                              \
9620b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n",  \
9630b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
9640b57cec5SDimitry Andric     return status;                                                             \
9650b57cec5SDimitry Andric   }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric #define LOOP_NEXT_ULL(func, fini_code)                                         \
9680b57cec5SDimitry Andric   int func(unsigned long long *p_lb, unsigned long long *p_ub) {               \
9690b57cec5SDimitry Andric     int status;                                                                \
9700b57cec5SDimitry Andric     long long stride;                                                          \
9710b57cec5SDimitry Andric     int gtid = __kmp_get_gtid();                                               \
9720b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
9730b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid));                            \
9740b57cec5SDimitry Andric                                                                                \
9750b57cec5SDimitry Andric     fini_code status =                                                         \
9760b57cec5SDimitry Andric         KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb,            \
9770b57cec5SDimitry Andric                               (kmp_uint64 *)p_ub, (kmp_int64 *)&stride);       \
9780b57cec5SDimitry Andric     if (status) {                                                              \
9790b57cec5SDimitry Andric       *p_ub += (stride > 0) ? 1 : -1;                                          \
9800b57cec5SDimitry Andric     }                                                                          \
9810b57cec5SDimitry Andric                                                                                \
9820b57cec5SDimitry Andric     KA_TRACE(                                                                  \
9830b57cec5SDimitry Andric         20,                                                                    \
9840b57cec5SDimitry Andric         (KMP_STR(                                                              \
9850b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, stride 0x%llx, "  \
9860b57cec5SDimitry Andric                    "returning %d\n",                                           \
9870b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, stride, status));                                 \
9880b57cec5SDimitry Andric     return status;                                                             \
9890b57cec5SDimitry Andric   }
9900b57cec5SDimitry Andric 
9910b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START),
9920b57cec5SDimitry Andric                kmp_sch_static)
9930b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT), {})
9940b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START),
9950b57cec5SDimitry Andric                kmp_sch_dynamic_chunked)
9960b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT), {})
9970b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START),
9980b57cec5SDimitry Andric                kmp_sch_guided_chunked)
9990b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT), {})
1000489b1cf2SDimitry Andric LOOP_START_ULL(
1001489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START),
1002489b1cf2SDimitry Andric     kmp_sch_dynamic_chunked)
1003489b1cf2SDimitry Andric LOOP_NEXT_ULL(
1004489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT), {})
1005489b1cf2SDimitry Andric LOOP_START_ULL(
1006489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START),
1007489b1cf2SDimitry Andric     kmp_sch_guided_chunked)
1008489b1cf2SDimitry Andric LOOP_NEXT_ULL(
1009489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT), {})
10100b57cec5SDimitry Andric LOOP_RUNTIME_START_ULL(
10110b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START), kmp_sch_runtime)
10120b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT), {})
10135ffd83dbSDimitry Andric LOOP_RUNTIME_START_ULL(
10145ffd83dbSDimitry Andric     KMP_EXPAND_NAME(
10155ffd83dbSDimitry Andric         KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START),
10165ffd83dbSDimitry Andric     kmp_sch_runtime)
10175ffd83dbSDimitry Andric LOOP_RUNTIME_START_ULL(
10185ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START),
10195ffd83dbSDimitry Andric     kmp_sch_runtime)
10205ffd83dbSDimitry Andric LOOP_NEXT_ULL(
10215ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT),
10225ffd83dbSDimitry Andric     {})
10235ffd83dbSDimitry Andric LOOP_NEXT_ULL(
10245ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT), {})
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START),
10270b57cec5SDimitry Andric                kmp_ord_static)
10280b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT),
10290b57cec5SDimitry Andric               { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
10300b57cec5SDimitry Andric LOOP_START_ULL(
10310b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START),
10320b57cec5SDimitry Andric     kmp_ord_dynamic_chunked)
10330b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT),
10340b57cec5SDimitry Andric               { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
10350b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START),
10360b57cec5SDimitry Andric                kmp_ord_guided_chunked)
10370b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT),
10380b57cec5SDimitry Andric               { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
10390b57cec5SDimitry Andric LOOP_RUNTIME_START_ULL(
10400b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START),
10410b57cec5SDimitry Andric     kmp_ord_runtime)
10420b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT),
10430b57cec5SDimitry Andric               { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric #define LOOP_DOACROSS_START_ULL(func, schedule)                                \
10460b57cec5SDimitry Andric   int func(unsigned ncounts, unsigned long long *counts,                       \
10470b57cec5SDimitry Andric            unsigned long long chunk_sz, unsigned long long *p_lb,              \
10480b57cec5SDimitry Andric            unsigned long long *p_ub) {                                         \
10490b57cec5SDimitry Andric     int status;                                                                \
10500b57cec5SDimitry Andric     long long stride, str, lb, ub;                                             \
10510b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
10520b57cec5SDimitry Andric     struct kmp_dim *dims =                                                     \
10530b57cec5SDimitry Andric         (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts);    \
10540b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
10550b57cec5SDimitry Andric     for (unsigned i = 0; i < ncounts; ++i) {                                   \
10560b57cec5SDimitry Andric       dims[i].lo = 0;                                                          \
10570b57cec5SDimitry Andric       dims[i].up = counts[i] - 1;                                              \
10580b57cec5SDimitry Andric       dims[i].st = 1;                                                          \
10590b57cec5SDimitry Andric     }                                                                          \
10600b57cec5SDimitry Andric     __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims);                      \
10610b57cec5SDimitry Andric     lb = 0;                                                                    \
10620b57cec5SDimitry Andric     ub = counts[0];                                                            \
10630b57cec5SDimitry Andric     str = 1;                                                                   \
10640b57cec5SDimitry Andric                                                                                \
10650b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str "           \
10660b57cec5SDimitry Andric                                 "0x%llx, chunk_sz 0x%llx\n",                   \
10670b57cec5SDimitry Andric                   gtid, lb, ub, str, chunk_sz));                               \
10680b57cec5SDimitry Andric                                                                                \
10690b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
10700b57cec5SDimitry Andric       KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb,                        \
10710b57cec5SDimitry Andric                             (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,    \
10720b57cec5SDimitry Andric                             (schedule) != kmp_sch_static);                     \
10730b57cec5SDimitry Andric       status =                                                                 \
10740b57cec5SDimitry Andric           KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb,          \
10750b57cec5SDimitry Andric                                 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride);     \
10760b57cec5SDimitry Andric       if (status) {                                                            \
10770b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
10780b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
10790b57cec5SDimitry Andric       }                                                                        \
10800b57cec5SDimitry Andric     } else {                                                                   \
10810b57cec5SDimitry Andric       status = 0;                                                              \
10820b57cec5SDimitry Andric     }                                                                          \
10830b57cec5SDimitry Andric     KMP_DOACROSS_FINI(status, gtid);                                           \
10840b57cec5SDimitry Andric                                                                                \
10850b57cec5SDimitry Andric     KA_TRACE(                                                                  \
10860b57cec5SDimitry Andric         20,                                                                    \
10870b57cec5SDimitry Andric         (KMP_STR(                                                              \
10880b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n",  \
10890b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
10900b57cec5SDimitry Andric     __kmp_free(dims);                                                          \
10910b57cec5SDimitry Andric     return status;                                                             \
10920b57cec5SDimitry Andric   }
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric #define LOOP_DOACROSS_RUNTIME_START_ULL(func, schedule)                        \
10950b57cec5SDimitry Andric   int func(unsigned ncounts, unsigned long long *counts,                       \
10960b57cec5SDimitry Andric            unsigned long long *p_lb, unsigned long long *p_ub) {               \
10970b57cec5SDimitry Andric     int status;                                                                \
10980b57cec5SDimitry Andric     unsigned long long stride, str, lb, ub;                                    \
10990b57cec5SDimitry Andric     unsigned long long chunk_sz = 0;                                           \
11000b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
11010b57cec5SDimitry Andric     struct kmp_dim *dims =                                                     \
11020b57cec5SDimitry Andric         (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts);    \
11030b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
11040b57cec5SDimitry Andric     for (unsigned i = 0; i < ncounts; ++i) {                                   \
11050b57cec5SDimitry Andric       dims[i].lo = 0;                                                          \
11060b57cec5SDimitry Andric       dims[i].up = counts[i] - 1;                                              \
11070b57cec5SDimitry Andric       dims[i].st = 1;                                                          \
11080b57cec5SDimitry Andric     }                                                                          \
11090b57cec5SDimitry Andric     __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims);                      \
11100b57cec5SDimitry Andric     lb = 0;                                                                    \
11110b57cec5SDimitry Andric     ub = counts[0];                                                            \
11120b57cec5SDimitry Andric     str = 1;                                                                   \
11130b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str "           \
11140b57cec5SDimitry Andric                                 "0x%llx, chunk_sz 0x%llx\n",                   \
11150b57cec5SDimitry Andric                   gtid, lb, ub, str, chunk_sz));                               \
11160b57cec5SDimitry Andric                                                                                \
11170b57cec5SDimitry Andric     if ((str > 0) ? (lb < ub) : (lb > ub)) {                                   \
11180b57cec5SDimitry Andric       KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb,                        \
11190b57cec5SDimitry Andric                             (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,    \
11200b57cec5SDimitry Andric                             TRUE);                                             \
11210b57cec5SDimitry Andric       status =                                                                 \
11220b57cec5SDimitry Andric           KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb,          \
11230b57cec5SDimitry Andric                                 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride);     \
11240b57cec5SDimitry Andric       if (status) {                                                            \
11250b57cec5SDimitry Andric         KMP_DEBUG_ASSERT(stride == str);                                       \
11260b57cec5SDimitry Andric         *p_ub += (str > 0) ? 1 : -1;                                           \
11270b57cec5SDimitry Andric       }                                                                        \
11280b57cec5SDimitry Andric     } else {                                                                   \
11290b57cec5SDimitry Andric       status = 0;                                                              \
11300b57cec5SDimitry Andric     }                                                                          \
11310b57cec5SDimitry Andric     KMP_DOACROSS_FINI(status, gtid);                                           \
11320b57cec5SDimitry Andric                                                                                \
11330b57cec5SDimitry Andric     KA_TRACE(                                                                  \
11340b57cec5SDimitry Andric         20,                                                                    \
11350b57cec5SDimitry Andric         (KMP_STR(                                                              \
11360b57cec5SDimitry Andric              func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n",  \
11370b57cec5SDimitry Andric          gtid, *p_lb, *p_ub, status));                                         \
11380b57cec5SDimitry Andric     __kmp_free(dims);                                                          \
11390b57cec5SDimitry Andric     return status;                                                             \
11400b57cec5SDimitry Andric   }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL(
11430b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START),
11440b57cec5SDimitry Andric     kmp_sch_static)
11450b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL(
11460b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START),
11470b57cec5SDimitry Andric     kmp_sch_dynamic_chunked)
11480b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL(
11490b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START),
11500b57cec5SDimitry Andric     kmp_sch_guided_chunked)
11510b57cec5SDimitry Andric LOOP_DOACROSS_RUNTIME_START_ULL(
11520b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START),
11530b57cec5SDimitry Andric     kmp_sch_runtime)
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric // Combined parallel / loop worksharing constructs
11560b57cec5SDimitry Andric //
11570b57cec5SDimitry Andric // There are no ull versions (yet).
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric #define PARALLEL_LOOP_START(func, schedule, ompt_pre, ompt_post)               \
11600b57cec5SDimitry Andric   void func(void (*task)(void *), void *data, unsigned num_threads, long lb,   \
11610b57cec5SDimitry Andric             long ub, long str, long chunk_sz) {                                \
11620b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
11630b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
11640b57cec5SDimitry Andric     KA_TRACE(                                                                  \
11650b57cec5SDimitry Andric         20,                                                                    \
11660b57cec5SDimitry Andric         (KMP_STR(                                                              \
11670b57cec5SDimitry Andric              func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n",  \
11680b57cec5SDimitry Andric          gtid, lb, ub, str, chunk_sz));                                        \
11690b57cec5SDimitry Andric                                                                                \
11700b57cec5SDimitry Andric     ompt_pre();                                                                \
11710b57cec5SDimitry Andric                                                                                \
1172e8d8bef9SDimitry Andric     __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task,                    \
11730b57cec5SDimitry Andric                          (microtask_t)__kmp_GOMP_parallel_microtask_wrapper,   \
11740b57cec5SDimitry Andric                          9, task, data, num_threads, &loc, (schedule), lb,     \
11750b57cec5SDimitry Andric                          (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz);      \
11760b57cec5SDimitry Andric     IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid));                          \
11770b57cec5SDimitry Andric                                                                                \
11780b57cec5SDimitry Andric     KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                              \
11790b57cec5SDimitry Andric                       (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,          \
11800b57cec5SDimitry Andric                       (schedule) != kmp_sch_static);                           \
11810b57cec5SDimitry Andric                                                                                \
11820b57cec5SDimitry Andric     ompt_post();                                                               \
11830b57cec5SDimitry Andric                                                                                \
11840b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid));                       \
11850b57cec5SDimitry Andric   }
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric #define OMPT_LOOP_PRE()                                                        \
11900b57cec5SDimitry Andric   ompt_frame_t *parent_frame;                                                  \
11910b57cec5SDimitry Andric   if (ompt_enabled.enabled) {                                                  \
11920b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL);   \
11930b57cec5SDimitry Andric     parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);                 \
11940b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);                                           \
11950b57cec5SDimitry Andric   }
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric #define OMPT_LOOP_POST()                                                       \
11980b57cec5SDimitry Andric   if (ompt_enabled.enabled) {                                                  \
11990b57cec5SDimitry Andric     parent_frame->enter_frame = ompt_data_none;                                \
12000b57cec5SDimitry Andric   }
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric #else
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric #define OMPT_LOOP_PRE()
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric #define OMPT_LOOP_POST()
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric #endif
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric PARALLEL_LOOP_START(
12110b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START),
12120b57cec5SDimitry Andric     kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST)
12130b57cec5SDimitry Andric PARALLEL_LOOP_START(
12140b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START),
12150b57cec5SDimitry Andric     kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
12160b57cec5SDimitry Andric PARALLEL_LOOP_START(
12170b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START),
12180b57cec5SDimitry Andric     kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
12190b57cec5SDimitry Andric PARALLEL_LOOP_START(
12200b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START),
12210b57cec5SDimitry Andric     kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric // Tasking constructs
12240b57cec5SDimitry Andric 
12250b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data,
12260b57cec5SDimitry Andric                                              void (*copy_func)(void *, void *),
12270b57cec5SDimitry Andric                                              long arg_size, long arg_align,
12280b57cec5SDimitry Andric                                              bool if_cond, unsigned gomp_flags,
12290b57cec5SDimitry Andric                                              void **depend) {
12300b57cec5SDimitry Andric   MKLOC(loc, "GOMP_task");
12310b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12320b57cec5SDimitry Andric   kmp_int32 flags = 0;
12330b57cec5SDimitry Andric   kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_task: T#%d\n", gtid));
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   // The low-order bit is the "untied" flag
1238e8d8bef9SDimitry Andric   if (!(gomp_flags & KMP_GOMP_TASK_UNTIED_FLAG)) {
1239349cc55cSDimitry Andric     input_flags->tiedness = TASK_TIED;
12400b57cec5SDimitry Andric   }
12410b57cec5SDimitry Andric   // The second low-order bit is the "final" flag
1242e8d8bef9SDimitry Andric   if (gomp_flags & KMP_GOMP_TASK_FINAL_FLAG) {
12430b57cec5SDimitry Andric     input_flags->final = 1;
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric   input_flags->native = 1;
12460b57cec5SDimitry Andric   // __kmp_task_alloc() sets up all other flags
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   if (!if_cond) {
12490b57cec5SDimitry Andric     arg_size = 0;
12500b57cec5SDimitry Andric   }
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric   kmp_task_t *task = __kmp_task_alloc(
12530b57cec5SDimitry Andric       &loc, gtid, input_flags, sizeof(kmp_task_t),
12540b57cec5SDimitry Andric       arg_size ? arg_size + arg_align - 1 : 0, (kmp_routine_entry_t)func);
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric   if (arg_size > 0) {
12570b57cec5SDimitry Andric     if (arg_align > 0) {
12580b57cec5SDimitry Andric       task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) /
12590b57cec5SDimitry Andric                                arg_align * arg_align);
12600b57cec5SDimitry Andric     }
12610b57cec5SDimitry Andric     // else error??
12620b57cec5SDimitry Andric 
12630b57cec5SDimitry Andric     if (copy_func) {
12640b57cec5SDimitry Andric       (*copy_func)(task->shareds, data);
12650b57cec5SDimitry Andric     } else {
12660b57cec5SDimitry Andric       KMP_MEMCPY(task->shareds, data, arg_size);
12670b57cec5SDimitry Andric     }
12680b57cec5SDimitry Andric   }
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric #if OMPT_SUPPORT
12710b57cec5SDimitry Andric   kmp_taskdata_t *current_task;
12720b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
12730b57cec5SDimitry Andric     current_task = __kmp_threads[gtid]->th.th_current_task;
1274fe6060f1SDimitry Andric     current_task->ompt_task_info.frame.enter_frame.ptr =
1275fe6060f1SDimitry Andric         OMPT_GET_FRAME_ADDRESS(0);
12760b57cec5SDimitry Andric   }
1277e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12780b57cec5SDimitry Andric #endif
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric   if (if_cond) {
1281e8d8bef9SDimitry Andric     if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) {
12820b57cec5SDimitry Andric       KMP_ASSERT(depend);
1283e8d8bef9SDimitry Andric       kmp_gomp_depends_info_t gomp_depends(depend);
1284e8d8bef9SDimitry Andric       kmp_int32 ndeps = gomp_depends.get_num_deps();
12855f757f3fSDimitry Andric       SimpleVLA<kmp_depend_info_t> dep_list(ndeps);
1286e8d8bef9SDimitry Andric       for (kmp_int32 i = 0; i < ndeps; i++)
1287e8d8bef9SDimitry Andric         dep_list[i] = gomp_depends.get_kmp_depend(i);
1288e8d8bef9SDimitry Andric       kmp_int32 ndeps_cnv;
1289e8d8bef9SDimitry Andric       __kmp_type_convert(ndeps, &ndeps_cnv);
1290e8d8bef9SDimitry Andric       __kmpc_omp_task_with_deps(&loc, gtid, task, ndeps_cnv, dep_list, 0, NULL);
12910b57cec5SDimitry Andric     } else {
12920b57cec5SDimitry Andric       __kmpc_omp_task(&loc, gtid, task);
12930b57cec5SDimitry Andric     }
12940b57cec5SDimitry Andric   } else {
12950b57cec5SDimitry Andric #if OMPT_SUPPORT
12960b57cec5SDimitry Andric     ompt_thread_info_t oldInfo;
12970b57cec5SDimitry Andric     kmp_info_t *thread;
12980b57cec5SDimitry Andric     kmp_taskdata_t *taskdata;
12990b57cec5SDimitry Andric     if (ompt_enabled.enabled) {
13000b57cec5SDimitry Andric       // Store the threads states and restore them after the task
13010b57cec5SDimitry Andric       thread = __kmp_threads[gtid];
13020b57cec5SDimitry Andric       taskdata = KMP_TASK_TO_TASKDATA(task);
13030b57cec5SDimitry Andric       oldInfo = thread->th.ompt_thread_info;
13040b57cec5SDimitry Andric       thread->th.ompt_thread_info.wait_id = 0;
13050b57cec5SDimitry Andric       thread->th.ompt_thread_info.state = ompt_state_work_parallel;
13060b57cec5SDimitry Andric       taskdata->ompt_task_info.frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
13070b57cec5SDimitry Andric     }
1308e8d8bef9SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
13090b57cec5SDimitry Andric #endif
1310e8d8bef9SDimitry Andric     if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) {
1311e8d8bef9SDimitry Andric       KMP_ASSERT(depend);
1312e8d8bef9SDimitry Andric       kmp_gomp_depends_info_t gomp_depends(depend);
1313e8d8bef9SDimitry Andric       kmp_int32 ndeps = gomp_depends.get_num_deps();
13145f757f3fSDimitry Andric       SimpleVLA<kmp_depend_info_t> dep_list(ndeps);
1315e8d8bef9SDimitry Andric       for (kmp_int32 i = 0; i < ndeps; i++)
1316e8d8bef9SDimitry Andric         dep_list[i] = gomp_depends.get_kmp_depend(i);
1317e8d8bef9SDimitry Andric       __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL);
1318e8d8bef9SDimitry Andric     }
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric     __kmpc_omp_task_begin_if0(&loc, gtid, task);
13210b57cec5SDimitry Andric     func(data);
13220b57cec5SDimitry Andric     __kmpc_omp_task_complete_if0(&loc, gtid, task);
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric #if OMPT_SUPPORT
13250b57cec5SDimitry Andric     if (ompt_enabled.enabled) {
13260b57cec5SDimitry Andric       thread->th.ompt_thread_info = oldInfo;
13270b57cec5SDimitry Andric       taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
13280b57cec5SDimitry Andric     }
13290b57cec5SDimitry Andric #endif
13300b57cec5SDimitry Andric   }
13310b57cec5SDimitry Andric #if OMPT_SUPPORT
13320b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
13330b57cec5SDimitry Andric     current_task->ompt_task_info.frame.enter_frame = ompt_data_none;
13340b57cec5SDimitry Andric   }
13350b57cec5SDimitry Andric #endif
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_task exit: T#%d\n", gtid));
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT)(void) {
13410b57cec5SDimitry Andric   MKLOC(loc, "GOMP_taskwait");
13420b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric #if OMPT_SUPPORT
13450b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
13460b57cec5SDimitry Andric #endif
13470b57cec5SDimitry Andric 
13480b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_taskwait: T#%d\n", gtid));
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric   __kmpc_omp_taskwait(&loc, gtid);
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_taskwait exit: T#%d\n", gtid));
13530b57cec5SDimitry Andric }
13540b57cec5SDimitry Andric 
13550b57cec5SDimitry Andric // Sections worksharing constructs
13560b57cec5SDimitry Andric //
13570b57cec5SDimitry Andric // For the sections construct, we initialize a dynamically scheduled loop
13580b57cec5SDimitry Andric // worksharing construct with lb 1 and stride 1, and use the iteration #'s
13590b57cec5SDimitry Andric // that its returns as sections ids.
13600b57cec5SDimitry Andric //
13610b57cec5SDimitry Andric // There are no special entry points for ordered sections, so we always use
13620b57cec5SDimitry Andric // the dynamically scheduled workshare, even if the sections aren't ordered.
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(unsigned count) {
13650b57cec5SDimitry Andric   int status;
13660b57cec5SDimitry Andric   kmp_int lb, ub, stride;
13670b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
13680b57cec5SDimitry Andric   MKLOC(loc, "GOMP_sections_start");
13690b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_start: T#%d\n", gtid));
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
13740b57cec5SDimitry Andric   if (status) {
13750b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(stride == 1);
13760b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(lb > 0);
13770b57cec5SDimitry Andric     KMP_ASSERT(lb == ub);
13780b57cec5SDimitry Andric   } else {
13790b57cec5SDimitry Andric     lb = 0;
13800b57cec5SDimitry Andric   }
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_start exit: T#%d returning %u\n", gtid,
13830b57cec5SDimitry Andric                 (unsigned)lb));
13840b57cec5SDimitry Andric   return (unsigned)lb;
13850b57cec5SDimitry Andric }
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_NEXT)(void) {
13880b57cec5SDimitry Andric   int status;
13890b57cec5SDimitry Andric   kmp_int lb, ub, stride;
13900b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
13910b57cec5SDimitry Andric   MKLOC(loc, "GOMP_sections_next");
13920b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_next: T#%d\n", gtid));
13930b57cec5SDimitry Andric 
13940b57cec5SDimitry Andric #if OMPT_SUPPORT
13950b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
13960b57cec5SDimitry Andric #endif
13970b57cec5SDimitry Andric 
13980b57cec5SDimitry Andric   status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
13990b57cec5SDimitry Andric   if (status) {
14000b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(stride == 1);
14010b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(lb > 0);
14020b57cec5SDimitry Andric     KMP_ASSERT(lb == ub);
14030b57cec5SDimitry Andric   } else {
14040b57cec5SDimitry Andric     lb = 0;
14050b57cec5SDimitry Andric   }
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   KA_TRACE(
14080b57cec5SDimitry Andric       20, ("GOMP_sections_next exit: T#%d returning %u\n", gtid, (unsigned)lb));
14090b57cec5SDimitry Andric   return (unsigned)lb;
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric 
14120b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(
14130b57cec5SDimitry Andric     void (*task)(void *), void *data, unsigned num_threads, unsigned count) {
14140b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric #if OMPT_SUPPORT
14170b57cec5SDimitry Andric   ompt_frame_t *parent_frame;
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14200b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL);
14210b57cec5SDimitry Andric     parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
14220b57cec5SDimitry Andric   }
1423e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
14240b57cec5SDimitry Andric #endif
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric   MKLOC(loc, "GOMP_parallel_sections_start");
14270b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_sections_start: T#%d\n", gtid));
14280b57cec5SDimitry Andric 
1429e8d8bef9SDimitry Andric   __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task,
14300b57cec5SDimitry Andric                        (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9,
14310b57cec5SDimitry Andric                        task, data, num_threads, &loc, kmp_nm_dynamic_chunked,
14320b57cec5SDimitry Andric                        (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1);
14330b57cec5SDimitry Andric 
14340b57cec5SDimitry Andric #if OMPT_SUPPORT
14350b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14360b57cec5SDimitry Andric     parent_frame->enter_frame = ompt_data_none;
14370b57cec5SDimitry Andric   }
14380b57cec5SDimitry Andric #endif
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric   KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_sections_start exit: T#%d\n", gtid));
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END)(void) {
14460b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
14470b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_end: T#%d\n", gtid))
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric #if OMPT_SUPPORT
14500b57cec5SDimitry Andric   ompt_frame_t *ompt_frame;
14510b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14520b57cec5SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
14530b57cec5SDimitry Andric     ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
14540b57cec5SDimitry Andric   }
1455e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
14560b57cec5SDimitry Andric #endif
14570b57cec5SDimitry Andric   __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
14580b57cec5SDimitry Andric #if OMPT_SUPPORT
14590b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14600b57cec5SDimitry Andric     ompt_frame->enter_frame = ompt_data_none;
14610b57cec5SDimitry Andric   }
14620b57cec5SDimitry Andric #endif
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_end exit: T#%d\n", gtid))
14650b57cec5SDimitry Andric }
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT)(void) {
14680b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_end_nowait: T#%d\n", __kmp_get_gtid()))
14690b57cec5SDimitry Andric }
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric // libgomp has an empty function for GOMP_taskyield as of 2013-10-10
14720b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKYIELD)(void) {
14730b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_taskyield: T#%d\n", __kmp_get_gtid()))
14740b57cec5SDimitry Andric   return;
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric 
14770b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL)(void (*task)(void *),
14780b57cec5SDimitry Andric                                                  void *data,
14790b57cec5SDimitry Andric                                                  unsigned num_threads,
14800b57cec5SDimitry Andric                                                  unsigned int flags) {
14810b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
14820b57cec5SDimitry Andric   MKLOC(loc, "GOMP_parallel");
14830b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel: T#%d\n", gtid));
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric #if OMPT_SUPPORT
14860b57cec5SDimitry Andric   ompt_task_info_t *parent_task_info, *task_info;
14870b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14880b57cec5SDimitry Andric     parent_task_info = __ompt_get_task_info_object(0);
14890b57cec5SDimitry Andric     parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1490e8d8bef9SDimitry Andric   }
14910b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
14920b57cec5SDimitry Andric #endif
1493e8d8bef9SDimitry Andric   __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
14940b57cec5SDimitry Andric                        (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task,
14950b57cec5SDimitry Andric                        data);
14960b57cec5SDimitry Andric #if OMPT_SUPPORT
14970b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
14980b57cec5SDimitry Andric     task_info = __ompt_get_task_info_object(0);
14990b57cec5SDimitry Andric     task_info->frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
15000b57cec5SDimitry Andric   }
15010b57cec5SDimitry Andric #endif
15020b57cec5SDimitry Andric   task(data);
1503e8d8bef9SDimitry Andric   {
15040b57cec5SDimitry Andric #if OMPT_SUPPORT
15050b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
15060b57cec5SDimitry Andric #endif
15070b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
1508e8d8bef9SDimitry Andric   }
15090b57cec5SDimitry Andric #if OMPT_SUPPORT
15100b57cec5SDimitry Andric   if (ompt_enabled.enabled) {
15110b57cec5SDimitry Andric     task_info->frame.exit_frame = ompt_data_none;
15120b57cec5SDimitry Andric     parent_task_info->frame.enter_frame = ompt_data_none;
15130b57cec5SDimitry Andric   }
15140b57cec5SDimitry Andric #endif
15150b57cec5SDimitry Andric }
15160b57cec5SDimitry Andric 
15170b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS)(void (*task)(void *),
15180b57cec5SDimitry Andric                                                           void *data,
15190b57cec5SDimitry Andric                                                           unsigned num_threads,
15200b57cec5SDimitry Andric                                                           unsigned count,
15210b57cec5SDimitry Andric                                                           unsigned flags) {
15220b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
15230b57cec5SDimitry Andric   MKLOC(loc, "GOMP_parallel_sections");
15240b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_sections: T#%d\n", gtid));
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric #if OMPT_SUPPORT
1527349cc55cSDimitry Andric   ompt_frame_t *task_frame;
1528349cc55cSDimitry Andric   kmp_info_t *thr;
1529349cc55cSDimitry Andric   if (ompt_enabled.enabled) {
1530349cc55cSDimitry Andric     thr = __kmp_threads[gtid];
1531349cc55cSDimitry Andric     task_frame = &(thr->th.th_current_task->ompt_task_info.frame);
1532349cc55cSDimitry Andric     task_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1533349cc55cSDimitry Andric   }
15340b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
15350b57cec5SDimitry Andric #endif
15360b57cec5SDimitry Andric 
1537e8d8bef9SDimitry Andric   __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
15380b57cec5SDimitry Andric                        (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9,
15390b57cec5SDimitry Andric                        task, data, num_threads, &loc, kmp_nm_dynamic_chunked,
15400b57cec5SDimitry Andric                        (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1);
15410b57cec5SDimitry Andric 
1542e8d8bef9SDimitry Andric   {
15430b57cec5SDimitry Andric #if OMPT_SUPPORT
15440b57cec5SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
15450b57cec5SDimitry Andric #endif
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric     KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
1548e8d8bef9SDimitry Andric   }
1549349cc55cSDimitry Andric 
1550349cc55cSDimitry Andric #if OMPT_SUPPORT
1551349cc55cSDimitry Andric   ompt_frame_t *child_frame;
1552349cc55cSDimitry Andric   if (ompt_enabled.enabled) {
1553349cc55cSDimitry Andric     child_frame = &(thr->th.th_current_task->ompt_task_info.frame);
1554349cc55cSDimitry Andric     child_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
1555349cc55cSDimitry Andric   }
1556349cc55cSDimitry Andric #endif
1557349cc55cSDimitry Andric 
15580b57cec5SDimitry Andric   task(data);
1559349cc55cSDimitry Andric 
1560349cc55cSDimitry Andric #if OMPT_SUPPORT
1561349cc55cSDimitry Andric   if (ompt_enabled.enabled) {
1562349cc55cSDimitry Andric     child_frame->exit_frame = ompt_data_none;
1563349cc55cSDimitry Andric   }
1564349cc55cSDimitry Andric #endif
1565349cc55cSDimitry Andric 
15660b57cec5SDimitry Andric   KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
15670b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_sections exit: T#%d\n", gtid));
1568349cc55cSDimitry Andric 
1569349cc55cSDimitry Andric #if OMPT_SUPPORT
1570349cc55cSDimitry Andric   if (ompt_enabled.enabled) {
1571349cc55cSDimitry Andric     task_frame->enter_frame = ompt_data_none;
1572349cc55cSDimitry Andric   }
1573349cc55cSDimitry Andric #endif
15740b57cec5SDimitry Andric }
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric #define PARALLEL_LOOP(func, schedule, ompt_pre, ompt_post)                     \
15770b57cec5SDimitry Andric   void func(void (*task)(void *), void *data, unsigned num_threads, long lb,   \
15780b57cec5SDimitry Andric             long ub, long str, long chunk_sz, unsigned flags) {                \
15790b57cec5SDimitry Andric     int gtid = __kmp_entry_gtid();                                             \
15800b57cec5SDimitry Andric     MKLOC(loc, KMP_STR(func));                                                 \
15810b57cec5SDimitry Andric     KA_TRACE(                                                                  \
15820b57cec5SDimitry Andric         20,                                                                    \
15830b57cec5SDimitry Andric         (KMP_STR(                                                              \
15840b57cec5SDimitry Andric              func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n",  \
15850b57cec5SDimitry Andric          gtid, lb, ub, str, chunk_sz));                                        \
15860b57cec5SDimitry Andric                                                                                \
15870b57cec5SDimitry Andric     ompt_pre();                                                                \
1588e8d8bef9SDimitry Andric     IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                          \
1589e8d8bef9SDimitry Andric     __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,                 \
15900b57cec5SDimitry Andric                          (microtask_t)__kmp_GOMP_parallel_microtask_wrapper,   \
15910b57cec5SDimitry Andric                          9, task, data, num_threads, &loc, (schedule), lb,     \
15920b57cec5SDimitry Andric                          (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz);      \
15930b57cec5SDimitry Andric                                                                                \
1594e8d8bef9SDimitry Andric     {                                                                          \
15950b57cec5SDimitry Andric       IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);)                        \
15960b57cec5SDimitry Andric       KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb,                            \
15970b57cec5SDimitry Andric                         (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz,        \
15980b57cec5SDimitry Andric                         (schedule) != kmp_sch_static);                         \
1599e8d8bef9SDimitry Andric     }                                                                          \
16000b57cec5SDimitry Andric     task(data);                                                                \
16010b57cec5SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();                         \
16020b57cec5SDimitry Andric     ompt_post();                                                               \
16030b57cec5SDimitry Andric                                                                                \
16040b57cec5SDimitry Andric     KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid));                       \
16050b57cec5SDimitry Andric   }
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC),
16080b57cec5SDimitry Andric               kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16090b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC),
16100b57cec5SDimitry Andric               kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
1611489b1cf2SDimitry Andric PARALLEL_LOOP(
1612489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED),
1613489b1cf2SDimitry Andric     kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
1614489b1cf2SDimitry Andric PARALLEL_LOOP(
1615489b1cf2SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC),
1616489b1cf2SDimitry Andric     kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16170b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED),
16180b57cec5SDimitry Andric               kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16190b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME),
16200b57cec5SDimitry Andric               kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16215ffd83dbSDimitry Andric PARALLEL_LOOP(
16225ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME),
16235ffd83dbSDimitry Andric     kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16245ffd83dbSDimitry Andric PARALLEL_LOOP(
16255ffd83dbSDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME),
16265ffd83dbSDimitry Andric     kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
16270b57cec5SDimitry Andric 
16280b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_START)(void) {
16290b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
16300b57cec5SDimitry Andric   MKLOC(loc, "GOMP_taskgroup_start");
16310b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_taskgroup_start: T#%d\n", gtid));
16320b57cec5SDimitry Andric 
16330b57cec5SDimitry Andric #if OMPT_SUPPORT
16340b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
16350b57cec5SDimitry Andric #endif
16360b57cec5SDimitry Andric 
16370b57cec5SDimitry Andric   __kmpc_taskgroup(&loc, gtid);
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   return;
16400b57cec5SDimitry Andric }
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_END)(void) {
16430b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
16440b57cec5SDimitry Andric   MKLOC(loc, "GOMP_taskgroup_end");
16450b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_taskgroup_end: T#%d\n", gtid));
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric #if OMPT_SUPPORT
16480b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
16490b57cec5SDimitry Andric #endif
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric   __kmpc_end_taskgroup(&loc, gtid);
16520b57cec5SDimitry Andric 
16530b57cec5SDimitry Andric   return;
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric static kmp_int32 __kmp_gomp_to_omp_cancellation_kind(int gomp_kind) {
16570b57cec5SDimitry Andric   kmp_int32 cncl_kind = 0;
16580b57cec5SDimitry Andric   switch (gomp_kind) {
16590b57cec5SDimitry Andric   case 1:
16600b57cec5SDimitry Andric     cncl_kind = cancel_parallel;
16610b57cec5SDimitry Andric     break;
16620b57cec5SDimitry Andric   case 2:
16630b57cec5SDimitry Andric     cncl_kind = cancel_loop;
16640b57cec5SDimitry Andric     break;
16650b57cec5SDimitry Andric   case 4:
16660b57cec5SDimitry Andric     cncl_kind = cancel_sections;
16670b57cec5SDimitry Andric     break;
16680b57cec5SDimitry Andric   case 8:
16690b57cec5SDimitry Andric     cncl_kind = cancel_taskgroup;
16700b57cec5SDimitry Andric     break;
16710b57cec5SDimitry Andric   }
16720b57cec5SDimitry Andric   return cncl_kind;
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise
16760b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCELLATION_POINT)(int which) {
16770b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
16780b57cec5SDimitry Andric   MKLOC(loc, "GOMP_cancellation_point");
16790b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_cancellation_point: T#%d which:%d\n", gtid, which));
16800b57cec5SDimitry Andric   kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which);
16810b57cec5SDimitry Andric   return __kmpc_cancellationpoint(&loc, gtid, cncl_kind);
16820b57cec5SDimitry Andric }
16830b57cec5SDimitry Andric 
16840b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise
16850b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCEL)(int which, bool do_cancel) {
16860b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
16870b57cec5SDimitry Andric   MKLOC(loc, "GOMP_cancel");
16880b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_cancel: T#%d which:%d do_cancel:%d\n", gtid, which,
16890b57cec5SDimitry Andric                 (int)do_cancel));
16900b57cec5SDimitry Andric   kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which);
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric   if (do_cancel == FALSE) {
16930b57cec5SDimitry Andric     return __kmpc_cancellationpoint(&loc, gtid, cncl_kind);
16940b57cec5SDimitry Andric   } else {
16950b57cec5SDimitry Andric     return __kmpc_cancel(&loc, gtid, cncl_kind);
16960b57cec5SDimitry Andric   }
16970b57cec5SDimitry Andric }
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise
17000b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER_CANCEL)(void) {
17010b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
17020b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_barrier_cancel: T#%d\n", gtid));
17030b57cec5SDimitry Andric   return __kmp_barrier_gomp_cancel(gtid);
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise
17070b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL)(void) {
17080b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
17090b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_sections_end_cancel: T#%d\n", gtid));
17100b57cec5SDimitry Andric   return __kmp_barrier_gomp_cancel(gtid);
17110b57cec5SDimitry Andric }
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise
17140b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_CANCEL)(void) {
17150b57cec5SDimitry Andric   int gtid = __kmp_get_gtid();
17160b57cec5SDimitry Andric   KA_TRACE(20, ("GOMP_loop_end_cancel: T#%d\n", gtid));
17170b57cec5SDimitry Andric   return __kmp_barrier_gomp_cancel(gtid);
17180b57cec5SDimitry Andric }
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric // All target functions are empty as of 2014-05-29
17210b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET)(int device, void (*fn)(void *),
17220b57cec5SDimitry Andric                                                const void *openmp_target,
17230b57cec5SDimitry Andric                                                size_t mapnum, void **hostaddrs,
17240b57cec5SDimitry Andric                                                size_t *sizes,
17250b57cec5SDimitry Andric                                                unsigned char *kinds) {
17260b57cec5SDimitry Andric   return;
17270b57cec5SDimitry Andric }
17280b57cec5SDimitry Andric 
17290b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_DATA)(
17300b57cec5SDimitry Andric     int device, const void *openmp_target, size_t mapnum, void **hostaddrs,
17310b57cec5SDimitry Andric     size_t *sizes, unsigned char *kinds) {
17320b57cec5SDimitry Andric   return;
17330b57cec5SDimitry Andric }
17340b57cec5SDimitry Andric 
17350b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_END_DATA)(void) { return; }
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_UPDATE)(
17380b57cec5SDimitry Andric     int device, const void *openmp_target, size_t mapnum, void **hostaddrs,
17390b57cec5SDimitry Andric     size_t *sizes, unsigned char *kinds) {
17400b57cec5SDimitry Andric   return;
17410b57cec5SDimitry Andric }
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams,
17440b57cec5SDimitry Andric                                               unsigned int thread_limit) {
17450b57cec5SDimitry Andric   return;
17460b57cec5SDimitry Andric }
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric // Task duplication function which copies src to dest (both are
17490b57cec5SDimitry Andric // preallocated task structures)
17500b57cec5SDimitry Andric static void __kmp_gomp_task_dup(kmp_task_t *dest, kmp_task_t *src,
17510b57cec5SDimitry Andric                                 kmp_int32 last_private) {
17520b57cec5SDimitry Andric   kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(src);
17530b57cec5SDimitry Andric   if (taskdata->td_copy_func) {
17540b57cec5SDimitry Andric     (taskdata->td_copy_func)(dest->shareds, src->shareds);
17550b57cec5SDimitry Andric   }
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric 
1758fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(
1759fe6060f1SDimitry Andric     uintptr_t *);
1760fe6060f1SDimitry Andric 
17610b57cec5SDimitry Andric #ifdef __cplusplus
17620b57cec5SDimitry Andric } // extern "C"
17630b57cec5SDimitry Andric #endif
17640b57cec5SDimitry Andric 
17650b57cec5SDimitry Andric template <typename T>
17660b57cec5SDimitry Andric void __GOMP_taskloop(void (*func)(void *), void *data,
17670b57cec5SDimitry Andric                      void (*copy_func)(void *, void *), long arg_size,
17680b57cec5SDimitry Andric                      long arg_align, unsigned gomp_flags,
17690b57cec5SDimitry Andric                      unsigned long num_tasks, int priority, T start, T end,
17700b57cec5SDimitry Andric                      T step) {
17710b57cec5SDimitry Andric   typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
17720b57cec5SDimitry Andric   MKLOC(loc, "GOMP_taskloop");
17730b57cec5SDimitry Andric   int sched;
17740b57cec5SDimitry Andric   T *loop_bounds;
17750b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
17760b57cec5SDimitry Andric   kmp_int32 flags = 0;
17770b57cec5SDimitry Andric   int if_val = gomp_flags & (1u << 10);
17780b57cec5SDimitry Andric   int nogroup = gomp_flags & (1u << 11);
17790b57cec5SDimitry Andric   int up = gomp_flags & (1u << 8);
1780fe6060f1SDimitry Andric   int reductions = gomp_flags & (1u << 12);
17810b57cec5SDimitry Andric   p_task_dup_t task_dup = NULL;
17820b57cec5SDimitry Andric   kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
17830b57cec5SDimitry Andric #ifdef KMP_DEBUG
17840b57cec5SDimitry Andric   {
17850b57cec5SDimitry Andric     char *buff;
17860b57cec5SDimitry Andric     buff = __kmp_str_format(
17870b57cec5SDimitry Andric         "GOMP_taskloop: T#%%d: func:%%p data:%%p copy_func:%%p "
17880b57cec5SDimitry Andric         "arg_size:%%ld arg_align:%%ld gomp_flags:0x%%x num_tasks:%%lu "
17890b57cec5SDimitry Andric         "priority:%%d start:%%%s end:%%%s step:%%%s\n",
17900b57cec5SDimitry Andric         traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec);
17910b57cec5SDimitry Andric     KA_TRACE(20, (buff, gtid, func, data, copy_func, arg_size, arg_align,
17920b57cec5SDimitry Andric                   gomp_flags, num_tasks, priority, start, end, step));
17930b57cec5SDimitry Andric     __kmp_str_free(&buff);
17940b57cec5SDimitry Andric   }
17950b57cec5SDimitry Andric #endif
17960b57cec5SDimitry Andric   KMP_ASSERT((size_t)arg_size >= 2 * sizeof(T));
17970b57cec5SDimitry Andric   KMP_ASSERT(arg_align > 0);
17980b57cec5SDimitry Andric   // The low-order bit is the "untied" flag
17990b57cec5SDimitry Andric   if (!(gomp_flags & 1)) {
1800349cc55cSDimitry Andric     input_flags->tiedness = TASK_TIED;
18010b57cec5SDimitry Andric   }
18020b57cec5SDimitry Andric   // The second low-order bit is the "final" flag
18030b57cec5SDimitry Andric   if (gomp_flags & 2) {
18040b57cec5SDimitry Andric     input_flags->final = 1;
18050b57cec5SDimitry Andric   }
18060b57cec5SDimitry Andric   // Negative step flag
18070b57cec5SDimitry Andric   if (!up) {
18080b57cec5SDimitry Andric     // If step is flagged as negative, but isn't properly sign extended
18090b57cec5SDimitry Andric     // Then manually sign extend it.  Could be a short, int, char embedded
18100b57cec5SDimitry Andric     // in a long.  So cannot assume any cast.
18110b57cec5SDimitry Andric     if (step > 0) {
18120b57cec5SDimitry Andric       for (int i = sizeof(T) * CHAR_BIT - 1; i >= 0L; --i) {
18130b57cec5SDimitry Andric         // break at the first 1 bit
18140b57cec5SDimitry Andric         if (step & ((T)1 << i))
18150b57cec5SDimitry Andric           break;
18160b57cec5SDimitry Andric         step |= ((T)1 << i);
18170b57cec5SDimitry Andric       }
18180b57cec5SDimitry Andric     }
18190b57cec5SDimitry Andric   }
18200b57cec5SDimitry Andric   input_flags->native = 1;
18210b57cec5SDimitry Andric   // Figure out if none/grainsize/num_tasks clause specified
18220b57cec5SDimitry Andric   if (num_tasks > 0) {
18230b57cec5SDimitry Andric     if (gomp_flags & (1u << 9))
18240b57cec5SDimitry Andric       sched = 1; // grainsize specified
18250b57cec5SDimitry Andric     else
18260b57cec5SDimitry Andric       sched = 2; // num_tasks specified
18270b57cec5SDimitry Andric     // neither grainsize nor num_tasks specified
18280b57cec5SDimitry Andric   } else {
18290b57cec5SDimitry Andric     sched = 0;
18300b57cec5SDimitry Andric   }
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric   // __kmp_task_alloc() sets up all other flags
18330b57cec5SDimitry Andric   kmp_task_t *task =
18340b57cec5SDimitry Andric       __kmp_task_alloc(&loc, gtid, input_flags, sizeof(kmp_task_t),
18350b57cec5SDimitry Andric                        arg_size + arg_align - 1, (kmp_routine_entry_t)func);
18360b57cec5SDimitry Andric   kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
18370b57cec5SDimitry Andric   taskdata->td_copy_func = copy_func;
18380b57cec5SDimitry Andric   taskdata->td_size_loop_bounds = sizeof(T);
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   // re-align shareds if needed and setup firstprivate copy constructors
18410b57cec5SDimitry Andric   // through the task_dup mechanism
18420b57cec5SDimitry Andric   task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) /
18430b57cec5SDimitry Andric                            arg_align * arg_align);
18440b57cec5SDimitry Andric   if (copy_func) {
18450b57cec5SDimitry Andric     task_dup = __kmp_gomp_task_dup;
18460b57cec5SDimitry Andric   }
18470b57cec5SDimitry Andric   KMP_MEMCPY(task->shareds, data, arg_size);
18480b57cec5SDimitry Andric 
18490b57cec5SDimitry Andric   loop_bounds = (T *)task->shareds;
18500b57cec5SDimitry Andric   loop_bounds[0] = start;
18510b57cec5SDimitry Andric   loop_bounds[1] = end + (up ? -1 : 1);
1852fe6060f1SDimitry Andric 
1853fe6060f1SDimitry Andric   if (!nogroup) {
1854fe6060f1SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1855fe6060f1SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
1856fe6060f1SDimitry Andric #endif
1857fe6060f1SDimitry Andric     __kmpc_taskgroup(&loc, gtid);
1858fe6060f1SDimitry Andric     if (reductions) {
1859fe6060f1SDimitry Andric       // The data pointer points to lb, ub, then reduction data
1860fe6060f1SDimitry Andric       struct data_t {
1861fe6060f1SDimitry Andric         T a, b;
1862fe6060f1SDimitry Andric         uintptr_t *d;
1863fe6060f1SDimitry Andric       };
1864fe6060f1SDimitry Andric       uintptr_t *d = ((data_t *)data)->d;
1865fe6060f1SDimitry Andric       KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(d);
1866fe6060f1SDimitry Andric     }
1867fe6060f1SDimitry Andric   }
18680b57cec5SDimitry Andric   __kmpc_taskloop(&loc, gtid, task, if_val, (kmp_uint64 *)&(loop_bounds[0]),
1869fe6060f1SDimitry Andric                   (kmp_uint64 *)&(loop_bounds[1]), (kmp_int64)step, 1, sched,
1870fe6060f1SDimitry Andric                   (kmp_uint64)num_tasks, (void *)task_dup);
1871fe6060f1SDimitry Andric   if (!nogroup) {
1872fe6060f1SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
1873fe6060f1SDimitry Andric     OMPT_STORE_RETURN_ADDRESS(gtid);
1874fe6060f1SDimitry Andric #endif
1875fe6060f1SDimitry Andric     __kmpc_end_taskgroup(&loc, gtid);
1876fe6060f1SDimitry Andric   }
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric // 4 byte version of GOMP_doacross_post
18800b57cec5SDimitry Andric // This verison needs to create a temporary array which converts 4 byte
1881480093f4SDimitry Andric // integers into 8 byte integers
18820b57cec5SDimitry Andric template <typename T, bool need_conversion = (sizeof(long) == 4)>
18830b57cec5SDimitry Andric void __kmp_GOMP_doacross_post(T *count);
18840b57cec5SDimitry Andric 
18850b57cec5SDimitry Andric template <> void __kmp_GOMP_doacross_post<long, true>(long *count) {
18860b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
18870b57cec5SDimitry Andric   kmp_info_t *th = __kmp_threads[gtid];
18880b57cec5SDimitry Andric   MKLOC(loc, "GOMP_doacross_post");
18890b57cec5SDimitry Andric   kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0];
1890e8d8bef9SDimitry Andric   kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc(
1891e8d8bef9SDimitry Andric       th, (size_t)(sizeof(kmp_int64) * num_dims));
18920b57cec5SDimitry Andric   for (kmp_int64 i = 0; i < num_dims; ++i) {
18930b57cec5SDimitry Andric     vec[i] = (kmp_int64)count[i];
18940b57cec5SDimitry Andric   }
18950b57cec5SDimitry Andric   __kmpc_doacross_post(&loc, gtid, vec);
18960b57cec5SDimitry Andric   __kmp_thread_free(th, vec);
18970b57cec5SDimitry Andric }
18980b57cec5SDimitry Andric 
18990b57cec5SDimitry Andric // 8 byte versions of GOMP_doacross_post
19000b57cec5SDimitry Andric // This version can just pass in the count array directly instead of creating
19010b57cec5SDimitry Andric // a temporary array
19020b57cec5SDimitry Andric template <> void __kmp_GOMP_doacross_post<long, false>(long *count) {
19030b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
19040b57cec5SDimitry Andric   MKLOC(loc, "GOMP_doacross_post");
19050b57cec5SDimitry Andric   __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count));
19060b57cec5SDimitry Andric }
19070b57cec5SDimitry Andric 
19080b57cec5SDimitry Andric template <typename T> void __kmp_GOMP_doacross_wait(T first, va_list args) {
19090b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
19100b57cec5SDimitry Andric   kmp_info_t *th = __kmp_threads[gtid];
19110b57cec5SDimitry Andric   MKLOC(loc, "GOMP_doacross_wait");
19120b57cec5SDimitry Andric   kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0];
1913e8d8bef9SDimitry Andric   kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc(
1914e8d8bef9SDimitry Andric       th, (size_t)(sizeof(kmp_int64) * num_dims));
19150b57cec5SDimitry Andric   vec[0] = (kmp_int64)first;
19160b57cec5SDimitry Andric   for (kmp_int64 i = 1; i < num_dims; ++i) {
19170b57cec5SDimitry Andric     T item = va_arg(args, T);
19180b57cec5SDimitry Andric     vec[i] = (kmp_int64)item;
19190b57cec5SDimitry Andric   }
19200b57cec5SDimitry Andric   __kmpc_doacross_wait(&loc, gtid, vec);
19210b57cec5SDimitry Andric   __kmp_thread_free(th, vec);
19220b57cec5SDimitry Andric   return;
19230b57cec5SDimitry Andric }
19240b57cec5SDimitry Andric 
19250b57cec5SDimitry Andric #ifdef __cplusplus
19260b57cec5SDimitry Andric extern "C" {
19270b57cec5SDimitry Andric #endif // __cplusplus
19280b57cec5SDimitry Andric 
19290b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP)(
19300b57cec5SDimitry Andric     void (*func)(void *), void *data, void (*copy_func)(void *, void *),
19310b57cec5SDimitry Andric     long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
19320b57cec5SDimitry Andric     int priority, long start, long end, long step) {
19330b57cec5SDimitry Andric   __GOMP_taskloop<long>(func, data, copy_func, arg_size, arg_align, gomp_flags,
19340b57cec5SDimitry Andric                         num_tasks, priority, start, end, step);
19350b57cec5SDimitry Andric }
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP_ULL)(
19380b57cec5SDimitry Andric     void (*func)(void *), void *data, void (*copy_func)(void *, void *),
19390b57cec5SDimitry Andric     long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
19400b57cec5SDimitry Andric     int priority, unsigned long long start, unsigned long long end,
19410b57cec5SDimitry Andric     unsigned long long step) {
19420b57cec5SDimitry Andric   __GOMP_taskloop<unsigned long long>(func, data, copy_func, arg_size,
19430b57cec5SDimitry Andric                                       arg_align, gomp_flags, num_tasks,
19440b57cec5SDimitry Andric                                       priority, start, end, step);
19450b57cec5SDimitry Andric }
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_POST)(long *count) {
19480b57cec5SDimitry Andric   __kmp_GOMP_doacross_post(count);
19490b57cec5SDimitry Andric }
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_WAIT)(long first, ...) {
19520b57cec5SDimitry Andric   va_list args;
19530b57cec5SDimitry Andric   va_start(args, first);
19540b57cec5SDimitry Andric   __kmp_GOMP_doacross_wait<long>(first, args);
19550b57cec5SDimitry Andric   va_end(args);
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric 
19580b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_POST)(
19590b57cec5SDimitry Andric     unsigned long long *count) {
19600b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
19610b57cec5SDimitry Andric   MKLOC(loc, "GOMP_doacross_ull_post");
19620b57cec5SDimitry Andric   __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count));
19630b57cec5SDimitry Andric }
19640b57cec5SDimitry Andric 
19650b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT)(
19660b57cec5SDimitry Andric     unsigned long long first, ...) {
19670b57cec5SDimitry Andric   va_list args;
19680b57cec5SDimitry Andric   va_start(args, first);
19690b57cec5SDimitry Andric   __kmp_GOMP_doacross_wait<unsigned long long>(first, args);
19700b57cec5SDimitry Andric   va_end(args);
19710b57cec5SDimitry Andric }
19720b57cec5SDimitry Andric 
1973fe6060f1SDimitry Andric // fn: the function each primary thread of new team will call
1974e8d8bef9SDimitry Andric // data: argument to fn
1975e8d8bef9SDimitry Andric // num_teams, thread_limit: max bounds on respective ICV
1976e8d8bef9SDimitry Andric // flags: unused
1977e8d8bef9SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS_REG)(void (*fn)(void *),
1978e8d8bef9SDimitry Andric                                                   void *data,
1979e8d8bef9SDimitry Andric                                                   unsigned num_teams,
1980e8d8bef9SDimitry Andric                                                   unsigned thread_limit,
1981e8d8bef9SDimitry Andric                                                   unsigned flags) {
1982e8d8bef9SDimitry Andric   MKLOC(loc, "GOMP_teams_reg");
1983e8d8bef9SDimitry Andric   int gtid = __kmp_entry_gtid();
1984e8d8bef9SDimitry Andric   KA_TRACE(20, ("GOMP_teams_reg: T#%d num_teams=%u thread_limit=%u flag=%u\n",
1985e8d8bef9SDimitry Andric                 gtid, num_teams, thread_limit, flags));
1986e8d8bef9SDimitry Andric   __kmpc_push_num_teams(&loc, gtid, num_teams, thread_limit);
1987e8d8bef9SDimitry Andric   __kmpc_fork_teams(&loc, 2, (microtask_t)__kmp_GOMP_microtask_wrapper, fn,
1988e8d8bef9SDimitry Andric                     data);
1989e8d8bef9SDimitry Andric   KA_TRACE(20, ("GOMP_teams_reg exit: T#%d\n", gtid));
1990e8d8bef9SDimitry Andric }
1991e8d8bef9SDimitry Andric 
1992e8d8bef9SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT_DEPEND)(void **depend) {
1993e8d8bef9SDimitry Andric   MKLOC(loc, "GOMP_taskwait_depend");
1994e8d8bef9SDimitry Andric   int gtid = __kmp_entry_gtid();
1995e8d8bef9SDimitry Andric   KA_TRACE(20, ("GOMP_taskwait_depend: T#%d\n", gtid));
1996e8d8bef9SDimitry Andric   kmp_gomp_depends_info_t gomp_depends(depend);
1997e8d8bef9SDimitry Andric   kmp_int32 ndeps = gomp_depends.get_num_deps();
19985f757f3fSDimitry Andric   SimpleVLA<kmp_depend_info_t> dep_list(ndeps);
1999e8d8bef9SDimitry Andric   for (kmp_int32 i = 0; i < ndeps; i++)
2000e8d8bef9SDimitry Andric     dep_list[i] = gomp_depends.get_kmp_depend(i);
2001e8d8bef9SDimitry Andric #if OMPT_SUPPORT
2002e8d8bef9SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
2003e8d8bef9SDimitry Andric #endif
2004e8d8bef9SDimitry Andric   __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL);
2005e8d8bef9SDimitry Andric   KA_TRACE(20, ("GOMP_taskwait_depend exit: T#%d\n", gtid));
2006e8d8bef9SDimitry Andric }
2007e8d8bef9SDimitry Andric 
2008fe6060f1SDimitry Andric static inline void
2009fe6060f1SDimitry Andric __kmp_GOMP_taskgroup_reduction_register(uintptr_t *data, kmp_taskgroup_t *tg,
2010fe6060f1SDimitry Andric                                         int nthreads,
2011fe6060f1SDimitry Andric                                         uintptr_t *allocated = nullptr) {
2012fe6060f1SDimitry Andric   KMP_ASSERT(data);
2013fe6060f1SDimitry Andric   KMP_ASSERT(nthreads > 0);
2014fe6060f1SDimitry Andric   // Have private copy pointers point to previously allocated
2015fe6060f1SDimitry Andric   // reduction data or allocate new data here
2016fe6060f1SDimitry Andric   if (allocated) {
2017fe6060f1SDimitry Andric     data[2] = allocated[2];
2018fe6060f1SDimitry Andric     data[6] = allocated[6];
2019fe6060f1SDimitry Andric   } else {
2020fe6060f1SDimitry Andric     data[2] = (uintptr_t)__kmp_allocate(nthreads * data[1]);
2021fe6060f1SDimitry Andric     data[6] = data[2] + (nthreads * data[1]);
2022fe6060f1SDimitry Andric   }
2023fe6060f1SDimitry Andric   if (tg)
2024fe6060f1SDimitry Andric     tg->gomp_data = data;
2025fe6060f1SDimitry Andric }
2026fe6060f1SDimitry Andric 
2027fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(
2028fe6060f1SDimitry Andric     uintptr_t *data) {
2029fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2030fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_taskgroup_reduction_register: T#%d\n", gtid));
2031fe6060f1SDimitry Andric   kmp_info_t *thread = __kmp_threads[gtid];
2032fe6060f1SDimitry Andric   kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
2033fe6060f1SDimitry Andric   int nthreads = thread->th.th_team_nproc;
2034fe6060f1SDimitry Andric   __kmp_GOMP_taskgroup_reduction_register(data, tg, nthreads);
2035fe6060f1SDimitry Andric }
2036fe6060f1SDimitry Andric 
2037fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER)(
2038fe6060f1SDimitry Andric     uintptr_t *data) {
2039fe6060f1SDimitry Andric   KA_TRACE(20,
2040fe6060f1SDimitry Andric            ("GOMP_taskgroup_reduction_unregister: T#%d\n", __kmp_get_gtid()));
2041fe6060f1SDimitry Andric   KMP_ASSERT(data && data[2]);
2042fe6060f1SDimitry Andric   __kmp_free((void *)data[2]);
2043fe6060f1SDimitry Andric }
2044fe6060f1SDimitry Andric 
2045fe6060f1SDimitry Andric // Search through reduction data and set ptrs[] elements
2046fe6060f1SDimitry Andric // to proper privatized copy address
2047fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP)(size_t cnt,
2048fe6060f1SDimitry Andric                                                              size_t cntorig,
2049fe6060f1SDimitry Andric                                                              void **ptrs) {
2050fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2051fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_task_reduction_remap: T#%d\n", gtid));
2052fe6060f1SDimitry Andric   kmp_info_t *thread = __kmp_threads[gtid];
2053fe6060f1SDimitry Andric   kmp_int32 tid = __kmp_get_tid();
2054fe6060f1SDimitry Andric   for (size_t i = 0; i < cnt; ++i) {
2055fe6060f1SDimitry Andric     uintptr_t address = (uintptr_t)ptrs[i];
2056fe6060f1SDimitry Andric     void *propagated_address = NULL;
2057fe6060f1SDimitry Andric     void *mapped_address = NULL;
2058fe6060f1SDimitry Andric     // Check taskgroups reduce data
2059fe6060f1SDimitry Andric     kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
2060fe6060f1SDimitry Andric     while (tg) {
2061fe6060f1SDimitry Andric       uintptr_t *gomp_data = tg->gomp_data;
2062fe6060f1SDimitry Andric       if (!gomp_data) {
2063fe6060f1SDimitry Andric         tg = tg->parent;
2064fe6060f1SDimitry Andric         continue;
2065fe6060f1SDimitry Andric       }
2066fe6060f1SDimitry Andric       // Check the shared addresses list
2067fe6060f1SDimitry Andric       size_t num_vars = (size_t)gomp_data[0];
2068fe6060f1SDimitry Andric       uintptr_t per_thread_size = gomp_data[1];
2069fe6060f1SDimitry Andric       uintptr_t reduce_data = gomp_data[2];
2070fe6060f1SDimitry Andric       uintptr_t end_reduce_data = gomp_data[6];
2071fe6060f1SDimitry Andric       for (size_t j = 0; j < num_vars; ++j) {
2072fe6060f1SDimitry Andric         uintptr_t *entry = gomp_data + 7 + 3 * j;
2073fe6060f1SDimitry Andric         if (entry[0] == address) {
2074fe6060f1SDimitry Andric           uintptr_t offset = entry[1];
2075fe6060f1SDimitry Andric           mapped_address =
2076fe6060f1SDimitry Andric               (void *)(reduce_data + tid * per_thread_size + offset);
2077fe6060f1SDimitry Andric           if (i < cntorig)
2078fe6060f1SDimitry Andric             propagated_address = (void *)entry[0];
2079fe6060f1SDimitry Andric           break;
2080fe6060f1SDimitry Andric         }
2081fe6060f1SDimitry Andric       }
2082fe6060f1SDimitry Andric       if (mapped_address)
2083fe6060f1SDimitry Andric         break;
2084fe6060f1SDimitry Andric       // Check if address is within privatized copies range
2085fe6060f1SDimitry Andric       if (!mapped_address && address >= reduce_data &&
2086fe6060f1SDimitry Andric           address < end_reduce_data) {
2087fe6060f1SDimitry Andric         uintptr_t offset = (address - reduce_data) % per_thread_size;
2088fe6060f1SDimitry Andric         mapped_address = (void *)(reduce_data + tid * per_thread_size + offset);
2089fe6060f1SDimitry Andric         if (i < cntorig) {
2090fe6060f1SDimitry Andric           for (size_t j = 0; j < num_vars; ++j) {
2091fe6060f1SDimitry Andric             uintptr_t *entry = gomp_data + 7 + 3 * j;
2092fe6060f1SDimitry Andric             if (entry[1] == offset) {
2093fe6060f1SDimitry Andric               propagated_address = (void *)entry[0];
2094fe6060f1SDimitry Andric               break;
2095fe6060f1SDimitry Andric             }
2096fe6060f1SDimitry Andric           }
2097fe6060f1SDimitry Andric         }
2098fe6060f1SDimitry Andric       }
2099fe6060f1SDimitry Andric       if (mapped_address)
2100fe6060f1SDimitry Andric         break;
2101fe6060f1SDimitry Andric       tg = tg->parent;
2102fe6060f1SDimitry Andric     }
2103fe6060f1SDimitry Andric     KMP_ASSERT(mapped_address);
2104fe6060f1SDimitry Andric     ptrs[i] = mapped_address;
2105fe6060f1SDimitry Andric     if (i < cntorig) {
2106fe6060f1SDimitry Andric       KMP_ASSERT(propagated_address);
2107fe6060f1SDimitry Andric       ptrs[cnt + i] = propagated_address;
2108fe6060f1SDimitry Andric     }
2109fe6060f1SDimitry Andric   }
2110fe6060f1SDimitry Andric }
2111fe6060f1SDimitry Andric 
2112fe6060f1SDimitry Andric static void __kmp_GOMP_init_reductions(int gtid, uintptr_t *data, int is_ws) {
2113fe6060f1SDimitry Andric   kmp_info_t *thr = __kmp_threads[gtid];
2114fe6060f1SDimitry Andric   kmp_team_t *team = thr->th.th_team;
2115fe6060f1SDimitry Andric   // First start a taskgroup
2116fe6060f1SDimitry Andric   __kmpc_taskgroup(NULL, gtid);
2117fe6060f1SDimitry Andric   // Then setup reduction data
2118fe6060f1SDimitry Andric   void *reduce_data = KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[is_ws]);
2119fe6060f1SDimitry Andric   if (reduce_data == NULL &&
2120fe6060f1SDimitry Andric       __kmp_atomic_compare_store(&team->t.t_tg_reduce_data[is_ws], reduce_data,
2121fe6060f1SDimitry Andric                                  (void *)1)) {
2122fe6060f1SDimitry Andric     // Single thread enters this block to initialize common reduction data
2123fe6060f1SDimitry Andric     KMP_DEBUG_ASSERT(reduce_data == NULL);
2124fe6060f1SDimitry Andric     __kmp_GOMP_taskgroup_reduction_register(data, NULL, thr->th.th_team_nproc);
2125fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[is_ws], 0);
2126fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[is_ws], (void *)data);
2127fe6060f1SDimitry Andric   } else {
2128fe6060f1SDimitry Andric     // Wait for task reduction initialization
2129fe6060f1SDimitry Andric     while ((reduce_data = KMP_ATOMIC_LD_ACQ(
2130fe6060f1SDimitry Andric                 &team->t.t_tg_reduce_data[is_ws])) == (void *)1) {
2131fe6060f1SDimitry Andric       KMP_CPU_PAUSE();
2132fe6060f1SDimitry Andric     }
2133fe6060f1SDimitry Andric     KMP_DEBUG_ASSERT(reduce_data > (void *)1); // should be valid pointer here
2134fe6060f1SDimitry Andric   }
2135fe6060f1SDimitry Andric   // For worksharing constructs, each thread has its own reduction structure.
2136fe6060f1SDimitry Andric   // Have each reduction structure point to same privatized copies of vars.
2137fe6060f1SDimitry Andric   // For parallel, each thread points to same reduction structure and privatized
2138fe6060f1SDimitry Andric   // copies of vars
2139fe6060f1SDimitry Andric   if (is_ws) {
2140fe6060f1SDimitry Andric     __kmp_GOMP_taskgroup_reduction_register(
2141fe6060f1SDimitry Andric         data, NULL, thr->th.th_team_nproc,
2142fe6060f1SDimitry Andric         (uintptr_t *)KMP_ATOMIC_LD_ACQ(&team->t.t_tg_reduce_data[is_ws]));
2143fe6060f1SDimitry Andric   }
2144fe6060f1SDimitry Andric   kmp_taskgroup_t *tg = thr->th.th_current_task->td_taskgroup;
2145fe6060f1SDimitry Andric   tg->gomp_data = data;
2146fe6060f1SDimitry Andric }
2147fe6060f1SDimitry Andric 
2148fe6060f1SDimitry Andric static unsigned
2149fe6060f1SDimitry Andric __kmp_GOMP_par_reductions_microtask_wrapper(int *gtid, int *npr,
2150fe6060f1SDimitry Andric                                             void (*task)(void *), void *data) {
2151fe6060f1SDimitry Andric   kmp_info_t *thr = __kmp_threads[*gtid];
2152fe6060f1SDimitry Andric   kmp_team_t *team = thr->th.th_team;
2153fe6060f1SDimitry Andric   uintptr_t *reduce_data = *(uintptr_t **)data;
2154fe6060f1SDimitry Andric   __kmp_GOMP_init_reductions(*gtid, reduce_data, 0);
2155fe6060f1SDimitry Andric 
2156fe6060f1SDimitry Andric #if OMPT_SUPPORT
2157fe6060f1SDimitry Andric   ompt_frame_t *ompt_frame;
2158fe6060f1SDimitry Andric   ompt_state_t enclosing_state;
2159fe6060f1SDimitry Andric 
2160fe6060f1SDimitry Andric   if (ompt_enabled.enabled) {
2161fe6060f1SDimitry Andric     // save enclosing task state; set current state for task
2162fe6060f1SDimitry Andric     enclosing_state = thr->th.ompt_thread_info.state;
2163fe6060f1SDimitry Andric     thr->th.ompt_thread_info.state = ompt_state_work_parallel;
2164fe6060f1SDimitry Andric 
2165fe6060f1SDimitry Andric     // set task frame
2166fe6060f1SDimitry Andric     __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
2167fe6060f1SDimitry Andric     ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
2168fe6060f1SDimitry Andric   }
2169fe6060f1SDimitry Andric #endif
2170fe6060f1SDimitry Andric 
2171fe6060f1SDimitry Andric   task(data);
2172fe6060f1SDimitry Andric 
2173fe6060f1SDimitry Andric #if OMPT_SUPPORT
2174fe6060f1SDimitry Andric   if (ompt_enabled.enabled) {
2175fe6060f1SDimitry Andric     // clear task frame
2176fe6060f1SDimitry Andric     ompt_frame->exit_frame = ompt_data_none;
2177fe6060f1SDimitry Andric 
2178fe6060f1SDimitry Andric     // restore enclosing state
2179fe6060f1SDimitry Andric     thr->th.ompt_thread_info.state = enclosing_state;
2180fe6060f1SDimitry Andric   }
2181fe6060f1SDimitry Andric #endif
2182fe6060f1SDimitry Andric   __kmpc_end_taskgroup(NULL, *gtid);
2183fe6060f1SDimitry Andric   // if last thread out, then reset the team's reduce data
2184fe6060f1SDimitry Andric   // the GOMP_taskgroup_reduction_unregister() function will deallocate
2185fe6060f1SDimitry Andric   // private copies after reduction calculations take place.
2186fe6060f1SDimitry Andric   int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[0]);
2187fe6060f1SDimitry Andric   if (count == thr->th.th_team_nproc - 1) {
2188fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[0], NULL);
2189fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[0], 0);
2190fe6060f1SDimitry Andric   }
2191fe6060f1SDimitry Andric   return (unsigned)thr->th.th_team_nproc;
2192fe6060f1SDimitry Andric }
2193fe6060f1SDimitry Andric 
2194fe6060f1SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS)(
2195fe6060f1SDimitry Andric     void (*task)(void *), void *data, unsigned num_threads,
2196fe6060f1SDimitry Andric     unsigned int flags) {
2197fe6060f1SDimitry Andric   MKLOC(loc, "GOMP_parallel_reductions");
2198fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2199fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_reductions: T#%d\n", gtid));
2200fe6060f1SDimitry Andric   __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
2201fe6060f1SDimitry Andric                        (microtask_t)__kmp_GOMP_par_reductions_microtask_wrapper,
2202fe6060f1SDimitry Andric                        2, task, data);
2203fe6060f1SDimitry Andric   unsigned retval =
2204fe6060f1SDimitry Andric       __kmp_GOMP_par_reductions_microtask_wrapper(&gtid, NULL, task, data);
2205fe6060f1SDimitry Andric   KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
2206fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_parallel_reductions exit: T#%d\n", gtid));
2207fe6060f1SDimitry Andric   return retval;
2208fe6060f1SDimitry Andric }
2209fe6060f1SDimitry Andric 
2210fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_START)(
2211fe6060f1SDimitry Andric     long start, long end, long incr, long sched, long chunk_size, long *istart,
2212fe6060f1SDimitry Andric     long *iend, uintptr_t *reductions, void **mem) {
2213fe6060f1SDimitry Andric   int status = 0;
2214fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2215fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_loop_start: T#%d, reductions: %p\n", gtid, reductions));
2216fe6060f1SDimitry Andric   if (reductions)
2217fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2218fe6060f1SDimitry Andric   if (mem)
2219fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2220fe6060f1SDimitry Andric   if (istart == NULL)
2221fe6060f1SDimitry Andric     return true;
2222fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2223fe6060f1SDimitry Andric   long monotonic = sched & MONOTONIC_FLAG;
2224fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2225fe6060f1SDimitry Andric   if (sched == 0) {
2226fe6060f1SDimitry Andric     if (monotonic)
2227fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START)(
2228fe6060f1SDimitry Andric           start, end, incr, istart, iend);
2229fe6060f1SDimitry Andric     else
2230fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(
2231fe6060f1SDimitry Andric           KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START)(
2232fe6060f1SDimitry Andric           start, end, incr, istart, iend);
2233fe6060f1SDimitry Andric   } else if (sched == 1) {
2234fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START)(
2235fe6060f1SDimitry Andric         start, end, incr, chunk_size, istart, iend);
2236fe6060f1SDimitry Andric   } else if (sched == 2) {
2237fe6060f1SDimitry Andric     if (monotonic)
2238fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START)(
2239fe6060f1SDimitry Andric           start, end, incr, chunk_size, istart, iend);
2240fe6060f1SDimitry Andric     else
2241fe6060f1SDimitry Andric       status =
2242fe6060f1SDimitry Andric           KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START)(
2243fe6060f1SDimitry Andric               start, end, incr, chunk_size, istart, iend);
2244fe6060f1SDimitry Andric   } else if (sched == 3) {
2245fe6060f1SDimitry Andric     if (monotonic)
2246fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START)(
2247fe6060f1SDimitry Andric           start, end, incr, chunk_size, istart, iend);
2248fe6060f1SDimitry Andric     else
2249fe6060f1SDimitry Andric       status =
2250fe6060f1SDimitry Andric           KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START)(
2251fe6060f1SDimitry Andric               start, end, incr, chunk_size, istart, iend);
2252fe6060f1SDimitry Andric   } else if (sched == 4) {
2253fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START)(
2254fe6060f1SDimitry Andric         start, end, incr, istart, iend);
2255fe6060f1SDimitry Andric   } else {
2256fe6060f1SDimitry Andric     KMP_ASSERT(0);
2257fe6060f1SDimitry Andric   }
2258fe6060f1SDimitry Andric   return status;
2259fe6060f1SDimitry Andric }
2260fe6060f1SDimitry Andric 
2261fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_START)(
2262fe6060f1SDimitry Andric     bool up, unsigned long long start, unsigned long long end,
2263fe6060f1SDimitry Andric     unsigned long long incr, long sched, unsigned long long chunk_size,
2264fe6060f1SDimitry Andric     unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions,
2265fe6060f1SDimitry Andric     void **mem) {
2266fe6060f1SDimitry Andric   int status = 0;
2267fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2268fe6060f1SDimitry Andric   KA_TRACE(20,
2269fe6060f1SDimitry Andric            ("GOMP_loop_ull_start: T#%d, reductions: %p\n", gtid, reductions));
2270fe6060f1SDimitry Andric   if (reductions)
2271fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2272fe6060f1SDimitry Andric   if (mem)
2273fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2274fe6060f1SDimitry Andric   if (istart == NULL)
2275fe6060f1SDimitry Andric     return true;
2276fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2277fe6060f1SDimitry Andric   long monotonic = sched & MONOTONIC_FLAG;
2278fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2279fe6060f1SDimitry Andric   if (sched == 0) {
2280fe6060f1SDimitry Andric     if (monotonic)
2281fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START)(
2282fe6060f1SDimitry Andric           up, start, end, incr, istart, iend);
2283fe6060f1SDimitry Andric     else
2284fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(
2285fe6060f1SDimitry Andric           KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START)(
2286fe6060f1SDimitry Andric           up, start, end, incr, istart, iend);
2287fe6060f1SDimitry Andric   } else if (sched == 1) {
2288fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START)(
2289fe6060f1SDimitry Andric         up, start, end, incr, chunk_size, istart, iend);
2290fe6060f1SDimitry Andric   } else if (sched == 2) {
2291fe6060f1SDimitry Andric     if (monotonic)
2292fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START)(
2293fe6060f1SDimitry Andric           up, start, end, incr, chunk_size, istart, iend);
2294fe6060f1SDimitry Andric     else
2295fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(
2296fe6060f1SDimitry Andric           KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START)(
2297fe6060f1SDimitry Andric           up, start, end, incr, chunk_size, istart, iend);
2298fe6060f1SDimitry Andric   } else if (sched == 3) {
2299fe6060f1SDimitry Andric     if (monotonic)
2300fe6060f1SDimitry Andric       status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START)(
2301fe6060f1SDimitry Andric           up, start, end, incr, chunk_size, istart, iend);
2302fe6060f1SDimitry Andric     else
2303fe6060f1SDimitry Andric       status =
2304fe6060f1SDimitry Andric           KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START)(
2305fe6060f1SDimitry Andric               up, start, end, incr, chunk_size, istart, iend);
2306fe6060f1SDimitry Andric   } else if (sched == 4) {
2307fe6060f1SDimitry Andric     status =
2308fe6060f1SDimitry Andric         KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START)(
2309fe6060f1SDimitry Andric             up, start, end, incr, istart, iend);
2310fe6060f1SDimitry Andric   } else {
2311fe6060f1SDimitry Andric     KMP_ASSERT(0);
2312fe6060f1SDimitry Andric   }
2313fe6060f1SDimitry Andric   return status;
2314fe6060f1SDimitry Andric }
2315fe6060f1SDimitry Andric 
2316fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_START)(
2317fe6060f1SDimitry Andric     unsigned ncounts, long *counts, long sched, long chunk_size, long *istart,
2318fe6060f1SDimitry Andric     long *iend, uintptr_t *reductions, void **mem) {
2319fe6060f1SDimitry Andric   int status = 0;
2320fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2321fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_loop_doacross_start: T#%d, reductions: %p\n", gtid,
2322fe6060f1SDimitry Andric                 reductions));
2323fe6060f1SDimitry Andric   if (reductions)
2324fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2325fe6060f1SDimitry Andric   if (mem)
2326fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2327fe6060f1SDimitry Andric   if (istart == NULL)
2328fe6060f1SDimitry Andric     return true;
2329fe6060f1SDimitry Andric   // Ignore any monotonic flag
2330fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2331fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2332fe6060f1SDimitry Andric   if (sched == 0) {
2333fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START)(
2334fe6060f1SDimitry Andric         ncounts, counts, istart, iend);
2335fe6060f1SDimitry Andric   } else if (sched == 1) {
2336fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START)(
2337fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2338fe6060f1SDimitry Andric   } else if (sched == 2) {
2339fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START)(
2340fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2341fe6060f1SDimitry Andric   } else if (sched == 3) {
2342fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START)(
2343fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2344fe6060f1SDimitry Andric   } else {
2345fe6060f1SDimitry Andric     KMP_ASSERT(0);
2346fe6060f1SDimitry Andric   }
2347fe6060f1SDimitry Andric   return status;
2348fe6060f1SDimitry Andric }
2349fe6060f1SDimitry Andric 
2350fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START)(
2351fe6060f1SDimitry Andric     unsigned ncounts, unsigned long long *counts, long sched,
2352fe6060f1SDimitry Andric     unsigned long long chunk_size, unsigned long long *istart,
2353fe6060f1SDimitry Andric     unsigned long long *iend, uintptr_t *reductions, void **mem) {
2354fe6060f1SDimitry Andric   int status = 0;
2355fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2356fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_loop_ull_doacross_start: T#%d, reductions: %p\n", gtid,
2357fe6060f1SDimitry Andric                 reductions));
2358fe6060f1SDimitry Andric   if (reductions)
2359fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2360fe6060f1SDimitry Andric   if (mem)
2361fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2362fe6060f1SDimitry Andric   if (istart == NULL)
2363fe6060f1SDimitry Andric     return true;
2364fe6060f1SDimitry Andric   // Ignore any monotonic flag
2365fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2366fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2367fe6060f1SDimitry Andric   if (sched == 0) {
2368fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START)(
2369fe6060f1SDimitry Andric         ncounts, counts, istart, iend);
2370fe6060f1SDimitry Andric   } else if (sched == 1) {
2371fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START)(
2372fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2373fe6060f1SDimitry Andric   } else if (sched == 2) {
2374fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START)(
2375fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2376fe6060f1SDimitry Andric   } else if (sched == 3) {
2377fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START)(
2378fe6060f1SDimitry Andric         ncounts, counts, chunk_size, istart, iend);
2379fe6060f1SDimitry Andric   } else {
2380fe6060f1SDimitry Andric     KMP_ASSERT(0);
2381fe6060f1SDimitry Andric   }
2382fe6060f1SDimitry Andric   return status;
2383fe6060f1SDimitry Andric }
2384fe6060f1SDimitry Andric 
2385fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_START)(
2386fe6060f1SDimitry Andric     long start, long end, long incr, long sched, long chunk_size, long *istart,
2387fe6060f1SDimitry Andric     long *iend, uintptr_t *reductions, void **mem) {
2388fe6060f1SDimitry Andric   int status = 0;
2389fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2390fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_loop_ordered_start: T#%d, reductions: %p\n", gtid,
2391fe6060f1SDimitry Andric                 reductions));
2392fe6060f1SDimitry Andric   if (reductions)
2393fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2394fe6060f1SDimitry Andric   if (mem)
2395fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2396fe6060f1SDimitry Andric   if (istart == NULL)
2397fe6060f1SDimitry Andric     return true;
2398fe6060f1SDimitry Andric   // Ignore any monotonic flag
2399fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2400fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2401fe6060f1SDimitry Andric   if (sched == 0) {
2402fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START)(
2403fe6060f1SDimitry Andric         start, end, incr, istart, iend);
2404fe6060f1SDimitry Andric   } else if (sched == 1) {
2405fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START)(
2406fe6060f1SDimitry Andric         start, end, incr, chunk_size, istart, iend);
2407fe6060f1SDimitry Andric   } else if (sched == 2) {
2408fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START)(
2409fe6060f1SDimitry Andric         start, end, incr, chunk_size, istart, iend);
2410fe6060f1SDimitry Andric   } else if (sched == 3) {
2411fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START)(
2412fe6060f1SDimitry Andric         start, end, incr, chunk_size, istart, iend);
2413fe6060f1SDimitry Andric   } else {
2414fe6060f1SDimitry Andric     KMP_ASSERT(0);
2415fe6060f1SDimitry Andric   }
2416fe6060f1SDimitry Andric   return status;
2417fe6060f1SDimitry Andric }
2418fe6060f1SDimitry Andric 
2419fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START)(
2420fe6060f1SDimitry Andric     bool up, unsigned long long start, unsigned long long end,
2421fe6060f1SDimitry Andric     unsigned long long incr, long sched, unsigned long long chunk_size,
2422fe6060f1SDimitry Andric     unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions,
2423fe6060f1SDimitry Andric     void **mem) {
2424fe6060f1SDimitry Andric   int status = 0;
2425fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2426fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_loop_ull_ordered_start: T#%d, reductions: %p\n", gtid,
2427fe6060f1SDimitry Andric                 reductions));
2428fe6060f1SDimitry Andric   if (reductions)
2429fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2430fe6060f1SDimitry Andric   if (mem)
2431fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2432fe6060f1SDimitry Andric   if (istart == NULL)
2433fe6060f1SDimitry Andric     return true;
2434fe6060f1SDimitry Andric   // Ignore any monotonic flag
2435fe6060f1SDimitry Andric   const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
2436fe6060f1SDimitry Andric   sched &= ~MONOTONIC_FLAG;
2437fe6060f1SDimitry Andric   if (sched == 0) {
2438fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START)(
2439fe6060f1SDimitry Andric         up, start, end, incr, istart, iend);
2440fe6060f1SDimitry Andric   } else if (sched == 1) {
2441fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START)(
2442fe6060f1SDimitry Andric         up, start, end, incr, chunk_size, istart, iend);
2443fe6060f1SDimitry Andric   } else if (sched == 2) {
2444fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START)(
2445fe6060f1SDimitry Andric         up, start, end, incr, chunk_size, istart, iend);
2446fe6060f1SDimitry Andric   } else if (sched == 3) {
2447fe6060f1SDimitry Andric     status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START)(
2448fe6060f1SDimitry Andric         up, start, end, incr, chunk_size, istart, iend);
2449fe6060f1SDimitry Andric   } else {
2450fe6060f1SDimitry Andric     KMP_ASSERT(0);
2451fe6060f1SDimitry Andric   }
2452fe6060f1SDimitry Andric   return status;
2453fe6060f1SDimitry Andric }
2454fe6060f1SDimitry Andric 
2455fe6060f1SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS2_START)(
2456fe6060f1SDimitry Andric     unsigned count, uintptr_t *reductions, void **mem) {
2457fe6060f1SDimitry Andric   int gtid = __kmp_entry_gtid();
2458fe6060f1SDimitry Andric   KA_TRACE(20,
2459fe6060f1SDimitry Andric            ("GOMP_sections2_start: T#%d, reductions: %p\n", gtid, reductions));
2460fe6060f1SDimitry Andric   if (reductions)
2461fe6060f1SDimitry Andric     __kmp_GOMP_init_reductions(gtid, reductions, 1);
2462fe6060f1SDimitry Andric   if (mem)
2463fe6060f1SDimitry Andric     KMP_FATAL(GompFeatureNotSupported, "scan");
2464fe6060f1SDimitry Andric   return KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(count);
2465fe6060f1SDimitry Andric }
2466fe6060f1SDimitry Andric 
2467fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER)(
2468fe6060f1SDimitry Andric     bool cancelled) {
2469fe6060f1SDimitry Andric   int gtid = __kmp_get_gtid();
2470fe6060f1SDimitry Andric   MKLOC(loc, "GOMP_workshare_task_reduction_unregister");
2471fe6060f1SDimitry Andric   KA_TRACE(20, ("GOMP_workshare_task_reduction_unregister: T#%d\n", gtid));
2472fe6060f1SDimitry Andric   kmp_info_t *thr = __kmp_threads[gtid];
2473fe6060f1SDimitry Andric   kmp_team_t *team = thr->th.th_team;
2474fe6060f1SDimitry Andric   __kmpc_end_taskgroup(NULL, gtid);
2475fe6060f1SDimitry Andric   // If last thread out of workshare, then reset the team's reduce data
2476fe6060f1SDimitry Andric   // the GOMP_taskgroup_reduction_unregister() function will deallocate
2477fe6060f1SDimitry Andric   // private copies after reduction calculations take place.
2478fe6060f1SDimitry Andric   int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[1]);
2479fe6060f1SDimitry Andric   if (count == thr->th.th_team_nproc - 1) {
2480fe6060f1SDimitry Andric     KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER)
2481fe6060f1SDimitry Andric     ((uintptr_t *)KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[1]));
2482fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[1], NULL);
2483fe6060f1SDimitry Andric     KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[1], 0);
2484fe6060f1SDimitry Andric   }
2485fe6060f1SDimitry Andric   if (!cancelled) {
2486fe6060f1SDimitry Andric     __kmpc_barrier(&loc, gtid);
2487fe6060f1SDimitry Andric   }
2488fe6060f1SDimitry Andric }
2489fe6060f1SDimitry Andric 
2490349cc55cSDimitry Andric // allocator construct
2491349cc55cSDimitry Andric void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ALLOC)(size_t alignment, size_t size,
2492349cc55cSDimitry Andric                                                uintptr_t allocator) {
2493349cc55cSDimitry Andric   int gtid = __kmp_entry_gtid();
2494349cc55cSDimitry Andric   KA_TRACE(20, ("GOMP_alloc: T#%d\n", gtid));
2495349cc55cSDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2496349cc55cSDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
2497349cc55cSDimitry Andric #endif
2498349cc55cSDimitry Andric   return __kmp_alloc(gtid, alignment, size, (omp_allocator_handle_t)allocator);
2499349cc55cSDimitry Andric }
2500349cc55cSDimitry Andric 
2501349cc55cSDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_FREE)(void *ptr, uintptr_t allocator) {
2502349cc55cSDimitry Andric   int gtid = __kmp_entry_gtid();
2503349cc55cSDimitry Andric   KA_TRACE(20, ("GOMP_free: T#%d\n", gtid));
2504349cc55cSDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
2505349cc55cSDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
2506349cc55cSDimitry Andric #endif
2507349cc55cSDimitry Andric   return ___kmpc_free(gtid, ptr, (omp_allocator_handle_t)allocator);
2508349cc55cSDimitry Andric }
2509349cc55cSDimitry Andric 
25100b57cec5SDimitry Andric /* The following sections of code create aliases for the GOMP_* functions, then
25110b57cec5SDimitry Andric    create versioned symbols using the assembler directive .symver. This is only
25120b57cec5SDimitry Andric    pertinent for ELF .so library. The KMP_VERSION_SYMBOL macro is defined in
25130b57cec5SDimitry Andric    kmp_os.h  */
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric #ifdef KMP_USE_VERSION_SYMBOLS
25160b57cec5SDimitry Andric // GOMP_1.0 versioned symbols
25170b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_END, 10, "GOMP_1.0");
25180b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_START, 10, "GOMP_1.0");
25190b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER, 10, "GOMP_1.0");
25200b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_END, 10, "GOMP_1.0");
25210b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10, "GOMP_1.0");
25220b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10, "GOMP_1.0");
25230b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_START, 10, "GOMP_1.0");
25240b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10, "GOMP_1.0");
25250b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10, "GOMP_1.0");
25260b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END, 10, "GOMP_1.0");
25270b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10, "GOMP_1.0");
25280b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10, "GOMP_1.0");
25290b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10, "GOMP_1.0");
25300b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10, "GOMP_1.0");
25310b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10,
25320b57cec5SDimitry Andric                    "GOMP_1.0");
25330b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10, "GOMP_1.0");
25340b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10, "GOMP_1.0");
25350b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10, "GOMP_1.0");
25360b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10,
25370b57cec5SDimitry Andric                    "GOMP_1.0");
25380b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10, "GOMP_1.0");
25390b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10, "GOMP_1.0");
25400b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10, "GOMP_1.0");
25410b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10, "GOMP_1.0");
25420b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10, "GOMP_1.0");
25430b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10, "GOMP_1.0");
25440b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_END, 10, "GOMP_1.0");
25450b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_START, 10, "GOMP_1.0");
25460b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_END, 10, "GOMP_1.0");
25470b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10,
25480b57cec5SDimitry Andric                    "GOMP_1.0");
25490b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10,
25500b57cec5SDimitry Andric                    "GOMP_1.0");
25510b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10,
25520b57cec5SDimitry Andric                    "GOMP_1.0");
25530b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10,
25540b57cec5SDimitry Andric                    "GOMP_1.0");
25550b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10, "GOMP_1.0");
25560b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_START, 10, "GOMP_1.0");
25570b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END, 10, "GOMP_1.0");
25580b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10, "GOMP_1.0");
25590b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10, "GOMP_1.0");
25600b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_START, 10, "GOMP_1.0");
25610b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10, "GOMP_1.0");
25620b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10, "GOMP_1.0");
25630b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_START, 10, "GOMP_1.0");
25640b57cec5SDimitry Andric 
25650b57cec5SDimitry Andric // GOMP_2.0 versioned symbols
25660b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK, 20, "GOMP_2.0");
25670b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT, 20, "GOMP_2.0");
25680b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20, "GOMP_2.0");
25690b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20, "GOMP_2.0");
25700b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20, "GOMP_2.0");
25710b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20, "GOMP_2.0");
25720b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20,
25730b57cec5SDimitry Andric                    "GOMP_2.0");
25740b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20,
25750b57cec5SDimitry Andric                    "GOMP_2.0");
25760b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20,
25770b57cec5SDimitry Andric                    "GOMP_2.0");
25780b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20,
25790b57cec5SDimitry Andric                    "GOMP_2.0");
25800b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20,
25810b57cec5SDimitry Andric                    "GOMP_2.0");
25820b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20,
25830b57cec5SDimitry Andric                    "GOMP_2.0");
25840b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20,
25850b57cec5SDimitry Andric                    "GOMP_2.0");
25860b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20,
25870b57cec5SDimitry Andric                    "GOMP_2.0");
25880b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20, "GOMP_2.0");
25890b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20, "GOMP_2.0");
25900b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20, "GOMP_2.0");
25910b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20, "GOMP_2.0");
25920b57cec5SDimitry Andric 
25930b57cec5SDimitry Andric // GOMP_3.0 versioned symbols
25940b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKYIELD, 30, "GOMP_3.0");
25950b57cec5SDimitry Andric 
25960b57cec5SDimitry Andric // GOMP_4.0 versioned symbols
25970b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL, 40, "GOMP_4.0");
25980b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40, "GOMP_4.0");
25990b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40, "GOMP_4.0");
26000b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40, "GOMP_4.0");
26010b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40, "GOMP_4.0");
26020b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40, "GOMP_4.0");
26030b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_START, 40, "GOMP_4.0");
26040b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_END, 40, "GOMP_4.0");
26050b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40, "GOMP_4.0");
26060b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCEL, 40, "GOMP_4.0");
26070b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40, "GOMP_4.0");
26080b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40, "GOMP_4.0");
26090b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40, "GOMP_4.0");
26100b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET, 40, "GOMP_4.0");
26110b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_DATA, 40, "GOMP_4.0");
26120b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_END_DATA, 40, "GOMP_4.0");
26130b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0");
26140b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0");
26150b57cec5SDimitry Andric 
26160b57cec5SDimitry Andric // GOMP_4.5 versioned symbols
26170b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP, 45, "GOMP_4.5");
26180b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP_ULL, 45, "GOMP_4.5");
26190b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_POST, 45, "GOMP_4.5");
26200b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_WAIT, 45, "GOMP_4.5");
26210b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START, 45,
26220b57cec5SDimitry Andric                    "GOMP_4.5");
26230b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START, 45,
26240b57cec5SDimitry Andric                    "GOMP_4.5");
26250b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START, 45,
26260b57cec5SDimitry Andric                    "GOMP_4.5");
26270b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START, 45,
26280b57cec5SDimitry Andric                    "GOMP_4.5");
26290b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_POST, 45, "GOMP_4.5");
26300b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT, 45, "GOMP_4.5");
26310b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START, 45,
26320b57cec5SDimitry Andric                    "GOMP_4.5");
26330b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START, 45,
26340b57cec5SDimitry Andric                    "GOMP_4.5");
26350b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START, 45,
26360b57cec5SDimitry Andric                    "GOMP_4.5");
26370b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START, 45,
26380b57cec5SDimitry Andric                    "GOMP_4.5");
2639489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START, 45,
2640489b1cf2SDimitry Andric                    "GOMP_4.5");
2641489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT, 45,
2642489b1cf2SDimitry Andric                    "GOMP_4.5");
2643489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START, 45,
2644489b1cf2SDimitry Andric                    "GOMP_4.5");
2645489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT, 45,
2646489b1cf2SDimitry Andric                    "GOMP_4.5");
2647489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START, 45,
2648489b1cf2SDimitry Andric                    "GOMP_4.5");
2649489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT, 45,
2650489b1cf2SDimitry Andric                    "GOMP_4.5");
2651489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START, 45,
2652489b1cf2SDimitry Andric                    "GOMP_4.5");
2653489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT, 45,
2654489b1cf2SDimitry Andric                    "GOMP_4.5");
2655489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC, 45,
2656489b1cf2SDimitry Andric                    "GOMP_4.5");
2657489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED, 45,
2658489b1cf2SDimitry Andric                    "GOMP_4.5");
26590b57cec5SDimitry Andric 
26605ffd83dbSDimitry Andric // GOMP_5.0 versioned symbols
26615ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT, 50,
26625ffd83dbSDimitry Andric                    "GOMP_5.0");
26635ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START, 50,
26645ffd83dbSDimitry Andric                    "GOMP_5.0");
26655ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT, 50,
26665ffd83dbSDimitry Andric                    "GOMP_5.0");
26675ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START, 50,
26685ffd83dbSDimitry Andric                    "GOMP_5.0");
26695ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
26705ffd83dbSDimitry Andric                    50, "GOMP_5.0");
26715ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
26725ffd83dbSDimitry Andric                    50, "GOMP_5.0");
26735ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT, 50,
26745ffd83dbSDimitry Andric                    "GOMP_5.0");
26755ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START, 50,
26765ffd83dbSDimitry Andric                    "GOMP_5.0");
26775ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME, 50,
26785ffd83dbSDimitry Andric                    "GOMP_5.0");
26795ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME,
26805ffd83dbSDimitry Andric                    50, "GOMP_5.0");
2681e8d8bef9SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS_REG, 50, "GOMP_5.0");
2682e8d8bef9SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT_DEPEND, 50, "GOMP_5.0");
2683fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER, 50,
2684fe6060f1SDimitry Andric                    "GOMP_5.0");
2685fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER, 50,
2686fe6060f1SDimitry Andric                    "GOMP_5.0");
2687fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP, 50, "GOMP_5.0");
2688fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS, 50, "GOMP_5.0");
2689fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_START, 50, "GOMP_5.0");
2690fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_START, 50, "GOMP_5.0");
2691fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_START, 50, "GOMP_5.0");
2692fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START, 50, "GOMP_5.0");
2693fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_START, 50, "GOMP_5.0");
2694fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START, 50, "GOMP_5.0");
2695fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS2_START, 50, "GOMP_5.0");
2696fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER, 50,
2697fe6060f1SDimitry Andric                    "GOMP_5.0");
2698349cc55cSDimitry Andric 
2699349cc55cSDimitry Andric // GOMP_5.0.1 versioned symbols
2700349cc55cSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ALLOC, 501, "GOMP_5.0.1");
2701349cc55cSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_FREE, 501, "GOMP_5.0.1");
27020b57cec5SDimitry Andric #endif // KMP_USE_VERSION_SYMBOLS
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric #ifdef __cplusplus
27050b57cec5SDimitry Andric } // extern "C"
27060b57cec5SDimitry Andric #endif // __cplusplus
2707