1*8feb0f0bSmrg /* Copyright (C) 2005-2020 Free Software Foundation, Inc.
21debfc3dSmrg Contributed by Richard Henderson <rth@redhat.com>.
31debfc3dSmrg
41debfc3dSmrg This file is part of the GNU Offloading and Multi Processing Library
51debfc3dSmrg (libgomp).
61debfc3dSmrg
71debfc3dSmrg Libgomp is free software; you can redistribute it and/or modify it
81debfc3dSmrg under the terms of the GNU General Public License as published by
91debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg any later version.
111debfc3dSmrg
121debfc3dSmrg Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
141debfc3dSmrg FOR A PARTICULAR PURPOSE. See the GNU General Public License for
151debfc3dSmrg more details.
161debfc3dSmrg
171debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
181debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
191debfc3dSmrg 3.1, as published by the Free Software Foundation.
201debfc3dSmrg
211debfc3dSmrg You should have received a copy of the GNU General Public License and
221debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
231debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
241debfc3dSmrg <http://www.gnu.org/licenses/>. */
251debfc3dSmrg
261debfc3dSmrg /* This file handles the LOOP (FOR/DO) construct. */
271debfc3dSmrg
281debfc3dSmrg #include <limits.h>
291debfc3dSmrg #include <stdlib.h>
30c0a68be4Smrg #include <string.h>
311debfc3dSmrg #include "libgomp.h"
321debfc3dSmrg
33c0a68be4Smrg ialias (GOMP_loop_ull_runtime_next)
34c0a68be4Smrg ialias_redirect (GOMP_taskgroup_reduction_register)
35c0a68be4Smrg
361debfc3dSmrg typedef unsigned long long gomp_ull;
371debfc3dSmrg
381debfc3dSmrg /* Initialize the given work share construct from the given arguments. */
391debfc3dSmrg
401debfc3dSmrg static inline void
gomp_loop_ull_init(struct gomp_work_share * ws,bool up,gomp_ull start,gomp_ull end,gomp_ull incr,enum gomp_schedule_type sched,gomp_ull chunk_size)411debfc3dSmrg gomp_loop_ull_init (struct gomp_work_share *ws, bool up, gomp_ull start,
421debfc3dSmrg gomp_ull end, gomp_ull incr, enum gomp_schedule_type sched,
431debfc3dSmrg gomp_ull chunk_size)
441debfc3dSmrg {
451debfc3dSmrg ws->sched = sched;
461debfc3dSmrg ws->chunk_size_ull = chunk_size;
471debfc3dSmrg /* Canonicalize loops that have zero iterations to ->next == ->end. */
481debfc3dSmrg ws->end_ull = ((up && start > end) || (!up && start < end))
491debfc3dSmrg ? start : end;
501debfc3dSmrg ws->incr_ull = incr;
511debfc3dSmrg ws->next_ull = start;
521debfc3dSmrg ws->mode = 0;
531debfc3dSmrg if (sched == GFS_DYNAMIC)
541debfc3dSmrg {
551debfc3dSmrg ws->chunk_size_ull *= incr;
561debfc3dSmrg
571debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
581debfc3dSmrg {
591debfc3dSmrg /* For dynamic scheduling prepare things to make each iteration
601debfc3dSmrg faster. */
611debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
621debfc3dSmrg struct gomp_team *team = thr->ts.team;
631debfc3dSmrg long nthreads = team ? team->nthreads : 1;
641debfc3dSmrg
651debfc3dSmrg if (__builtin_expect (up, 1))
661debfc3dSmrg {
671debfc3dSmrg /* Cheap overflow protection. */
681debfc3dSmrg if (__builtin_expect ((nthreads | ws->chunk_size_ull)
691debfc3dSmrg < 1ULL << (sizeof (gomp_ull)
701debfc3dSmrg * __CHAR_BIT__ / 2 - 1), 1))
711debfc3dSmrg ws->mode = ws->end_ull < (__LONG_LONG_MAX__ * 2ULL + 1
721debfc3dSmrg - (nthreads + 1) * ws->chunk_size_ull);
731debfc3dSmrg }
741debfc3dSmrg /* Cheap overflow protection. */
751debfc3dSmrg else if (__builtin_expect ((nthreads | -ws->chunk_size_ull)
761debfc3dSmrg < 1ULL << (sizeof (gomp_ull)
771debfc3dSmrg * __CHAR_BIT__ / 2 - 1), 1))
781debfc3dSmrg ws->mode = ws->end_ull > ((nthreads + 1) * -ws->chunk_size_ull
791debfc3dSmrg - (__LONG_LONG_MAX__ * 2ULL + 1));
801debfc3dSmrg }
811debfc3dSmrg #endif
821debfc3dSmrg }
831debfc3dSmrg if (!up)
841debfc3dSmrg ws->mode |= 2;
851debfc3dSmrg }
861debfc3dSmrg
871debfc3dSmrg /* The *_start routines are called when first encountering a loop construct
881debfc3dSmrg that is not bound directly to a parallel construct. The first thread
891debfc3dSmrg that arrives will create the work-share construct; subsequent threads
901debfc3dSmrg will see the construct exists and allocate work from it.
911debfc3dSmrg
921debfc3dSmrg START, END, INCR are the bounds of the loop; due to the restrictions of
931debfc3dSmrg OpenMP, these values must be the same in every thread. This is not
941debfc3dSmrg verified (nor is it entirely verifiable, since START is not necessarily
951debfc3dSmrg retained intact in the work-share data structure). CHUNK_SIZE is the
961debfc3dSmrg scheduling parameter; again this must be identical in all threads.
971debfc3dSmrg
981debfc3dSmrg Returns true if there's any work for this thread to perform. If so,
991debfc3dSmrg *ISTART and *IEND are filled with the bounds of the iteration block
1001debfc3dSmrg allocated to this thread. Returns false if all work was assigned to
1011debfc3dSmrg other threads prior to this thread's arrival. */
1021debfc3dSmrg
1031debfc3dSmrg static bool
gomp_loop_ull_static_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)1041debfc3dSmrg gomp_loop_ull_static_start (bool up, gomp_ull start, gomp_ull end,
1051debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
1061debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
1071debfc3dSmrg {
1081debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
1091debfc3dSmrg
1101debfc3dSmrg thr->ts.static_trip = 0;
111c0a68be4Smrg if (gomp_work_share_start (0))
1121debfc3dSmrg {
1131debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
1141debfc3dSmrg GFS_STATIC, chunk_size);
1151debfc3dSmrg gomp_work_share_init_done ();
1161debfc3dSmrg }
1171debfc3dSmrg
1181debfc3dSmrg return !gomp_iter_ull_static_next (istart, iend);
1191debfc3dSmrg }
1201debfc3dSmrg
1211debfc3dSmrg static bool
gomp_loop_ull_dynamic_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)1221debfc3dSmrg gomp_loop_ull_dynamic_start (bool up, gomp_ull start, gomp_ull end,
1231debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
1241debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
1251debfc3dSmrg {
1261debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
1271debfc3dSmrg bool ret;
1281debfc3dSmrg
129c0a68be4Smrg if (gomp_work_share_start (0))
1301debfc3dSmrg {
1311debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
1321debfc3dSmrg GFS_DYNAMIC, chunk_size);
1331debfc3dSmrg gomp_work_share_init_done ();
1341debfc3dSmrg }
1351debfc3dSmrg
1361debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
1371debfc3dSmrg ret = gomp_iter_ull_dynamic_next (istart, iend);
1381debfc3dSmrg #else
1391debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
1401debfc3dSmrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
1411debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
1421debfc3dSmrg #endif
1431debfc3dSmrg
1441debfc3dSmrg return ret;
1451debfc3dSmrg }
1461debfc3dSmrg
1471debfc3dSmrg static bool
gomp_loop_ull_guided_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)1481debfc3dSmrg gomp_loop_ull_guided_start (bool up, gomp_ull start, gomp_ull end,
1491debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
1501debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
1511debfc3dSmrg {
1521debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
1531debfc3dSmrg bool ret;
1541debfc3dSmrg
155c0a68be4Smrg if (gomp_work_share_start (0))
1561debfc3dSmrg {
1571debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
1581debfc3dSmrg GFS_GUIDED, chunk_size);
1591debfc3dSmrg gomp_work_share_init_done ();
1601debfc3dSmrg }
1611debfc3dSmrg
1621debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
1631debfc3dSmrg ret = gomp_iter_ull_guided_next (istart, iend);
1641debfc3dSmrg #else
1651debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
1661debfc3dSmrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
1671debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
1681debfc3dSmrg #endif
1691debfc3dSmrg
1701debfc3dSmrg return ret;
1711debfc3dSmrg }
1721debfc3dSmrg
1731debfc3dSmrg bool
GOMP_loop_ull_runtime_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull * istart,gomp_ull * iend)1741debfc3dSmrg GOMP_loop_ull_runtime_start (bool up, gomp_ull start, gomp_ull end,
1751debfc3dSmrg gomp_ull incr, gomp_ull *istart, gomp_ull *iend)
1761debfc3dSmrg {
1771debfc3dSmrg struct gomp_task_icv *icv = gomp_icv (false);
178c0a68be4Smrg switch (icv->run_sched_var & ~GFS_MONOTONIC)
1791debfc3dSmrg {
1801debfc3dSmrg case GFS_STATIC:
1811debfc3dSmrg return gomp_loop_ull_static_start (up, start, end, incr,
1821debfc3dSmrg icv->run_sched_chunk_size,
1831debfc3dSmrg istart, iend);
1841debfc3dSmrg case GFS_DYNAMIC:
1851debfc3dSmrg return gomp_loop_ull_dynamic_start (up, start, end, incr,
1861debfc3dSmrg icv->run_sched_chunk_size,
1871debfc3dSmrg istart, iend);
1881debfc3dSmrg case GFS_GUIDED:
1891debfc3dSmrg return gomp_loop_ull_guided_start (up, start, end, incr,
1901debfc3dSmrg icv->run_sched_chunk_size,
1911debfc3dSmrg istart, iend);
1921debfc3dSmrg case GFS_AUTO:
1931debfc3dSmrg /* For now map to schedule(static), later on we could play with feedback
1941debfc3dSmrg driven choice. */
1951debfc3dSmrg return gomp_loop_ull_static_start (up, start, end, incr,
1961debfc3dSmrg 0, istart, iend);
1971debfc3dSmrg default:
1981debfc3dSmrg abort ();
1991debfc3dSmrg }
2001debfc3dSmrg }
2011debfc3dSmrg
202c0a68be4Smrg static long
gomp_adjust_sched(long sched,gomp_ull * chunk_size)203c0a68be4Smrg gomp_adjust_sched (long sched, gomp_ull *chunk_size)
204c0a68be4Smrg {
205c0a68be4Smrg sched &= ~GFS_MONOTONIC;
206c0a68be4Smrg switch (sched)
207c0a68be4Smrg {
208c0a68be4Smrg case GFS_STATIC:
209c0a68be4Smrg case GFS_DYNAMIC:
210c0a68be4Smrg case GFS_GUIDED:
211c0a68be4Smrg return sched;
212c0a68be4Smrg /* GFS_RUNTIME is used for runtime schedule without monotonic
213c0a68be4Smrg or nonmonotonic modifiers on the clause.
214c0a68be4Smrg GFS_RUNTIME|GFS_MONOTONIC for runtime schedule with monotonic
215c0a68be4Smrg modifier. */
216c0a68be4Smrg case GFS_RUNTIME:
217c0a68be4Smrg /* GFS_AUTO is used for runtime schedule with nonmonotonic
218c0a68be4Smrg modifier. */
219c0a68be4Smrg case GFS_AUTO:
220c0a68be4Smrg {
221c0a68be4Smrg struct gomp_task_icv *icv = gomp_icv (false);
222c0a68be4Smrg sched = icv->run_sched_var & ~GFS_MONOTONIC;
223c0a68be4Smrg switch (sched)
224c0a68be4Smrg {
225c0a68be4Smrg case GFS_STATIC:
226c0a68be4Smrg case GFS_DYNAMIC:
227c0a68be4Smrg case GFS_GUIDED:
228c0a68be4Smrg *chunk_size = icv->run_sched_chunk_size;
229c0a68be4Smrg break;
230c0a68be4Smrg case GFS_AUTO:
231c0a68be4Smrg sched = GFS_STATIC;
232c0a68be4Smrg *chunk_size = 0;
233c0a68be4Smrg break;
234c0a68be4Smrg default:
235c0a68be4Smrg abort ();
236c0a68be4Smrg }
237c0a68be4Smrg return sched;
238c0a68be4Smrg }
239c0a68be4Smrg default:
240c0a68be4Smrg abort ();
241c0a68be4Smrg }
242c0a68be4Smrg }
243c0a68be4Smrg
244c0a68be4Smrg bool
GOMP_loop_ull_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,long sched,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend,uintptr_t * reductions,void ** mem)245c0a68be4Smrg GOMP_loop_ull_start (bool up, gomp_ull start, gomp_ull end,
246c0a68be4Smrg gomp_ull incr, long sched, gomp_ull chunk_size,
247c0a68be4Smrg gomp_ull *istart, gomp_ull *iend,
248c0a68be4Smrg uintptr_t *reductions, void **mem)
249c0a68be4Smrg {
250c0a68be4Smrg struct gomp_thread *thr = gomp_thread ();
251c0a68be4Smrg
252c0a68be4Smrg thr->ts.static_trip = 0;
253c0a68be4Smrg if (reductions)
254c0a68be4Smrg gomp_workshare_taskgroup_start ();
255c0a68be4Smrg if (gomp_work_share_start (0))
256c0a68be4Smrg {
257c0a68be4Smrg sched = gomp_adjust_sched (sched, &chunk_size);
258c0a68be4Smrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
259c0a68be4Smrg sched, chunk_size);
260c0a68be4Smrg if (reductions)
261c0a68be4Smrg {
262c0a68be4Smrg GOMP_taskgroup_reduction_register (reductions);
263c0a68be4Smrg thr->task->taskgroup->workshare = true;
264c0a68be4Smrg thr->ts.work_share->task_reductions = reductions;
265c0a68be4Smrg }
266c0a68be4Smrg if (mem)
267c0a68be4Smrg {
268c0a68be4Smrg uintptr_t size = (uintptr_t) *mem;
269c0a68be4Smrg #define INLINE_ORDERED_TEAM_IDS_OFF \
270c0a68be4Smrg ((offsetof (struct gomp_work_share, inline_ordered_team_ids) \
271c0a68be4Smrg + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
272c0a68be4Smrg if (size > (sizeof (struct gomp_work_share)
273c0a68be4Smrg - INLINE_ORDERED_TEAM_IDS_OFF))
274c0a68be4Smrg *mem
275c0a68be4Smrg = (void *) (thr->ts.work_share->ordered_team_ids
276c0a68be4Smrg = gomp_malloc_cleared (size));
277c0a68be4Smrg else
278c0a68be4Smrg *mem = memset (((char *) thr->ts.work_share)
279c0a68be4Smrg + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
280c0a68be4Smrg }
281c0a68be4Smrg gomp_work_share_init_done ();
282c0a68be4Smrg }
283c0a68be4Smrg else
284c0a68be4Smrg {
285c0a68be4Smrg if (reductions)
286c0a68be4Smrg {
287c0a68be4Smrg uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
288c0a68be4Smrg gomp_workshare_task_reduction_register (reductions,
289c0a68be4Smrg first_reductions);
290c0a68be4Smrg }
291c0a68be4Smrg if (mem)
292c0a68be4Smrg {
293c0a68be4Smrg if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
294c0a68be4Smrg & (__alignof__ (long long) - 1)) == 0)
295c0a68be4Smrg *mem = (void *) thr->ts.work_share->ordered_team_ids;
296c0a68be4Smrg else
297c0a68be4Smrg {
298c0a68be4Smrg uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
299c0a68be4Smrg p += __alignof__ (long long) - 1;
300c0a68be4Smrg p &= ~(__alignof__ (long long) - 1);
301c0a68be4Smrg *mem = (void *) p;
302c0a68be4Smrg }
303c0a68be4Smrg }
304c0a68be4Smrg }
305c0a68be4Smrg
306c0a68be4Smrg return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
307c0a68be4Smrg }
308c0a68be4Smrg
3091debfc3dSmrg /* The *_ordered_*_start routines are similar. The only difference is that
3101debfc3dSmrg this work-share construct is initialized to expect an ORDERED section. */
3111debfc3dSmrg
3121debfc3dSmrg static bool
gomp_loop_ull_ordered_static_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)3131debfc3dSmrg gomp_loop_ull_ordered_static_start (bool up, gomp_ull start, gomp_ull end,
3141debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
3151debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
3161debfc3dSmrg {
3171debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
3181debfc3dSmrg
3191debfc3dSmrg thr->ts.static_trip = 0;
320c0a68be4Smrg if (gomp_work_share_start (1))
3211debfc3dSmrg {
3221debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
3231debfc3dSmrg GFS_STATIC, chunk_size);
3241debfc3dSmrg gomp_ordered_static_init ();
3251debfc3dSmrg gomp_work_share_init_done ();
3261debfc3dSmrg }
3271debfc3dSmrg
3281debfc3dSmrg return !gomp_iter_ull_static_next (istart, iend);
3291debfc3dSmrg }
3301debfc3dSmrg
3311debfc3dSmrg static bool
gomp_loop_ull_ordered_dynamic_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)3321debfc3dSmrg gomp_loop_ull_ordered_dynamic_start (bool up, gomp_ull start, gomp_ull end,
3331debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
3341debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
3351debfc3dSmrg {
3361debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
3371debfc3dSmrg bool ret;
3381debfc3dSmrg
339c0a68be4Smrg if (gomp_work_share_start (1))
3401debfc3dSmrg {
3411debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
3421debfc3dSmrg GFS_DYNAMIC, chunk_size);
3431debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
3441debfc3dSmrg gomp_work_share_init_done ();
3451debfc3dSmrg }
3461debfc3dSmrg else
3471debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
3481debfc3dSmrg
3491debfc3dSmrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
3501debfc3dSmrg if (ret)
3511debfc3dSmrg gomp_ordered_first ();
3521debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
3531debfc3dSmrg
3541debfc3dSmrg return ret;
3551debfc3dSmrg }
3561debfc3dSmrg
3571debfc3dSmrg static bool
gomp_loop_ull_ordered_guided_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)3581debfc3dSmrg gomp_loop_ull_ordered_guided_start (bool up, gomp_ull start, gomp_ull end,
3591debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
3601debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
3611debfc3dSmrg {
3621debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
3631debfc3dSmrg bool ret;
3641debfc3dSmrg
365c0a68be4Smrg if (gomp_work_share_start (1))
3661debfc3dSmrg {
3671debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
3681debfc3dSmrg GFS_GUIDED, chunk_size);
3691debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
3701debfc3dSmrg gomp_work_share_init_done ();
3711debfc3dSmrg }
3721debfc3dSmrg else
3731debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
3741debfc3dSmrg
3751debfc3dSmrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
3761debfc3dSmrg if (ret)
3771debfc3dSmrg gomp_ordered_first ();
3781debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
3791debfc3dSmrg
3801debfc3dSmrg return ret;
3811debfc3dSmrg }
3821debfc3dSmrg
3831debfc3dSmrg bool
GOMP_loop_ull_ordered_runtime_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull * istart,gomp_ull * iend)3841debfc3dSmrg GOMP_loop_ull_ordered_runtime_start (bool up, gomp_ull start, gomp_ull end,
3851debfc3dSmrg gomp_ull incr, gomp_ull *istart,
3861debfc3dSmrg gomp_ull *iend)
3871debfc3dSmrg {
3881debfc3dSmrg struct gomp_task_icv *icv = gomp_icv (false);
389c0a68be4Smrg switch (icv->run_sched_var & ~GFS_MONOTONIC)
3901debfc3dSmrg {
3911debfc3dSmrg case GFS_STATIC:
3921debfc3dSmrg return gomp_loop_ull_ordered_static_start (up, start, end, incr,
3931debfc3dSmrg icv->run_sched_chunk_size,
3941debfc3dSmrg istart, iend);
3951debfc3dSmrg case GFS_DYNAMIC:
3961debfc3dSmrg return gomp_loop_ull_ordered_dynamic_start (up, start, end, incr,
3971debfc3dSmrg icv->run_sched_chunk_size,
3981debfc3dSmrg istart, iend);
3991debfc3dSmrg case GFS_GUIDED:
4001debfc3dSmrg return gomp_loop_ull_ordered_guided_start (up, start, end, incr,
4011debfc3dSmrg icv->run_sched_chunk_size,
4021debfc3dSmrg istart, iend);
4031debfc3dSmrg case GFS_AUTO:
4041debfc3dSmrg /* For now map to schedule(static), later on we could play with feedback
4051debfc3dSmrg driven choice. */
4061debfc3dSmrg return gomp_loop_ull_ordered_static_start (up, start, end, incr,
4071debfc3dSmrg 0, istart, iend);
4081debfc3dSmrg default:
4091debfc3dSmrg abort ();
4101debfc3dSmrg }
4111debfc3dSmrg }
4121debfc3dSmrg
413c0a68be4Smrg bool
GOMP_loop_ull_ordered_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,long sched,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend,uintptr_t * reductions,void ** mem)414c0a68be4Smrg GOMP_loop_ull_ordered_start (bool up, gomp_ull start, gomp_ull end,
415c0a68be4Smrg gomp_ull incr, long sched, gomp_ull chunk_size,
416c0a68be4Smrg gomp_ull *istart, gomp_ull *iend,
417c0a68be4Smrg uintptr_t *reductions, void **mem)
418c0a68be4Smrg {
419c0a68be4Smrg struct gomp_thread *thr = gomp_thread ();
420c0a68be4Smrg size_t ordered = 1;
421c0a68be4Smrg bool ret;
422c0a68be4Smrg
423c0a68be4Smrg thr->ts.static_trip = 0;
424c0a68be4Smrg if (reductions)
425c0a68be4Smrg gomp_workshare_taskgroup_start ();
426c0a68be4Smrg if (mem)
427c0a68be4Smrg ordered += (uintptr_t) *mem;
428c0a68be4Smrg if (gomp_work_share_start (ordered))
429c0a68be4Smrg {
430c0a68be4Smrg sched = gomp_adjust_sched (sched, &chunk_size);
431c0a68be4Smrg gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
432c0a68be4Smrg sched, chunk_size);
433c0a68be4Smrg if (reductions)
434c0a68be4Smrg {
435c0a68be4Smrg GOMP_taskgroup_reduction_register (reductions);
436c0a68be4Smrg thr->task->taskgroup->workshare = true;
437c0a68be4Smrg thr->ts.work_share->task_reductions = reductions;
438c0a68be4Smrg }
439c0a68be4Smrg if (sched == GFS_STATIC)
440c0a68be4Smrg gomp_ordered_static_init ();
441c0a68be4Smrg else
442c0a68be4Smrg gomp_mutex_lock (&thr->ts.work_share->lock);
443c0a68be4Smrg gomp_work_share_init_done ();
444c0a68be4Smrg }
445c0a68be4Smrg else
446c0a68be4Smrg {
447c0a68be4Smrg if (reductions)
448c0a68be4Smrg {
449c0a68be4Smrg uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
450c0a68be4Smrg gomp_workshare_task_reduction_register (reductions,
451c0a68be4Smrg first_reductions);
452c0a68be4Smrg }
453c0a68be4Smrg sched = thr->ts.work_share->sched;
454c0a68be4Smrg if (sched != GFS_STATIC)
455c0a68be4Smrg gomp_mutex_lock (&thr->ts.work_share->lock);
456c0a68be4Smrg }
457c0a68be4Smrg
458c0a68be4Smrg if (mem)
459c0a68be4Smrg {
460c0a68be4Smrg uintptr_t p
461c0a68be4Smrg = (uintptr_t) (thr->ts.work_share->ordered_team_ids
462c0a68be4Smrg + (thr->ts.team ? thr->ts.team->nthreads : 1));
463c0a68be4Smrg p += __alignof__ (long long) - 1;
464c0a68be4Smrg p &= ~(__alignof__ (long long) - 1);
465c0a68be4Smrg *mem = (void *) p;
466c0a68be4Smrg }
467c0a68be4Smrg
468c0a68be4Smrg switch (sched)
469c0a68be4Smrg {
470c0a68be4Smrg case GFS_STATIC:
471c0a68be4Smrg case GFS_AUTO:
472c0a68be4Smrg return !gomp_iter_ull_static_next (istart, iend);
473c0a68be4Smrg case GFS_DYNAMIC:
474c0a68be4Smrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
475c0a68be4Smrg break;
476c0a68be4Smrg case GFS_GUIDED:
477c0a68be4Smrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
478c0a68be4Smrg break;
479c0a68be4Smrg default:
480c0a68be4Smrg abort ();
481c0a68be4Smrg }
482c0a68be4Smrg
483c0a68be4Smrg if (ret)
484c0a68be4Smrg gomp_ordered_first ();
485c0a68be4Smrg gomp_mutex_unlock (&thr->ts.work_share->lock);
486c0a68be4Smrg return ret;
487c0a68be4Smrg }
488c0a68be4Smrg
4891debfc3dSmrg /* The *_doacross_*_start routines are similar. The only difference is that
4901debfc3dSmrg this work-share construct is initialized to expect an ORDERED(N) - DOACROSS
4911debfc3dSmrg section, and the worksharing loop iterates always from 0 to COUNTS[0] - 1
4921debfc3dSmrg and other COUNTS array elements tell the library number of iterations
4931debfc3dSmrg in the ordered inner loops. */
4941debfc3dSmrg
4951debfc3dSmrg static bool
gomp_loop_ull_doacross_static_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)4961debfc3dSmrg gomp_loop_ull_doacross_static_start (unsigned ncounts, gomp_ull *counts,
4971debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
4981debfc3dSmrg gomp_ull *iend)
4991debfc3dSmrg {
5001debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
5011debfc3dSmrg
5021debfc3dSmrg thr->ts.static_trip = 0;
503c0a68be4Smrg if (gomp_work_share_start (0))
5041debfc3dSmrg {
5051debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
5061debfc3dSmrg GFS_STATIC, chunk_size);
507c0a68be4Smrg gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
5081debfc3dSmrg gomp_work_share_init_done ();
5091debfc3dSmrg }
5101debfc3dSmrg
5111debfc3dSmrg return !gomp_iter_ull_static_next (istart, iend);
5121debfc3dSmrg }
5131debfc3dSmrg
5141debfc3dSmrg static bool
gomp_loop_ull_doacross_dynamic_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)5151debfc3dSmrg gomp_loop_ull_doacross_dynamic_start (unsigned ncounts, gomp_ull *counts,
5161debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
5171debfc3dSmrg gomp_ull *iend)
5181debfc3dSmrg {
5191debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
5201debfc3dSmrg bool ret;
5211debfc3dSmrg
522c0a68be4Smrg if (gomp_work_share_start (0))
5231debfc3dSmrg {
5241debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
5251debfc3dSmrg GFS_DYNAMIC, chunk_size);
526c0a68be4Smrg gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
5271debfc3dSmrg gomp_work_share_init_done ();
5281debfc3dSmrg }
5291debfc3dSmrg
5301debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
5311debfc3dSmrg ret = gomp_iter_ull_dynamic_next (istart, iend);
5321debfc3dSmrg #else
5331debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
5341debfc3dSmrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
5351debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
5361debfc3dSmrg #endif
5371debfc3dSmrg
5381debfc3dSmrg return ret;
5391debfc3dSmrg }
5401debfc3dSmrg
5411debfc3dSmrg static bool
gomp_loop_ull_doacross_guided_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)5421debfc3dSmrg gomp_loop_ull_doacross_guided_start (unsigned ncounts, gomp_ull *counts,
5431debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
5441debfc3dSmrg gomp_ull *iend)
5451debfc3dSmrg {
5461debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
5471debfc3dSmrg bool ret;
5481debfc3dSmrg
549c0a68be4Smrg if (gomp_work_share_start (0))
5501debfc3dSmrg {
5511debfc3dSmrg gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
5521debfc3dSmrg GFS_GUIDED, chunk_size);
553c0a68be4Smrg gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
5541debfc3dSmrg gomp_work_share_init_done ();
5551debfc3dSmrg }
5561debfc3dSmrg
5571debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
5581debfc3dSmrg ret = gomp_iter_ull_guided_next (istart, iend);
5591debfc3dSmrg #else
5601debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
5611debfc3dSmrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
5621debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
5631debfc3dSmrg #endif
5641debfc3dSmrg
5651debfc3dSmrg return ret;
5661debfc3dSmrg }
5671debfc3dSmrg
5681debfc3dSmrg bool
GOMP_loop_ull_doacross_runtime_start(unsigned ncounts,gomp_ull * counts,gomp_ull * istart,gomp_ull * iend)5691debfc3dSmrg GOMP_loop_ull_doacross_runtime_start (unsigned ncounts, gomp_ull *counts,
5701debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
5711debfc3dSmrg {
5721debfc3dSmrg struct gomp_task_icv *icv = gomp_icv (false);
573c0a68be4Smrg switch (icv->run_sched_var & ~GFS_MONOTONIC)
5741debfc3dSmrg {
5751debfc3dSmrg case GFS_STATIC:
5761debfc3dSmrg return gomp_loop_ull_doacross_static_start (ncounts, counts,
5771debfc3dSmrg icv->run_sched_chunk_size,
5781debfc3dSmrg istart, iend);
5791debfc3dSmrg case GFS_DYNAMIC:
5801debfc3dSmrg return gomp_loop_ull_doacross_dynamic_start (ncounts, counts,
5811debfc3dSmrg icv->run_sched_chunk_size,
5821debfc3dSmrg istart, iend);
5831debfc3dSmrg case GFS_GUIDED:
5841debfc3dSmrg return gomp_loop_ull_doacross_guided_start (ncounts, counts,
5851debfc3dSmrg icv->run_sched_chunk_size,
5861debfc3dSmrg istart, iend);
5871debfc3dSmrg case GFS_AUTO:
5881debfc3dSmrg /* For now map to schedule(static), later on we could play with feedback
5891debfc3dSmrg driven choice. */
5901debfc3dSmrg return gomp_loop_ull_doacross_static_start (ncounts, counts,
5911debfc3dSmrg 0, istart, iend);
5921debfc3dSmrg default:
5931debfc3dSmrg abort ();
5941debfc3dSmrg }
5951debfc3dSmrg }
5961debfc3dSmrg
597c0a68be4Smrg bool
GOMP_loop_ull_doacross_start(unsigned ncounts,gomp_ull * counts,long sched,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend,uintptr_t * reductions,void ** mem)598c0a68be4Smrg GOMP_loop_ull_doacross_start (unsigned ncounts, gomp_ull *counts,
599c0a68be4Smrg long sched, gomp_ull chunk_size,
600c0a68be4Smrg gomp_ull *istart, gomp_ull *iend,
601c0a68be4Smrg uintptr_t *reductions, void **mem)
602c0a68be4Smrg {
603c0a68be4Smrg struct gomp_thread *thr = gomp_thread ();
604c0a68be4Smrg
605c0a68be4Smrg thr->ts.static_trip = 0;
606c0a68be4Smrg if (reductions)
607c0a68be4Smrg gomp_workshare_taskgroup_start ();
608c0a68be4Smrg if (gomp_work_share_start (0))
609c0a68be4Smrg {
610c0a68be4Smrg size_t extra = 0;
611c0a68be4Smrg if (mem)
612c0a68be4Smrg extra = (uintptr_t) *mem;
613c0a68be4Smrg sched = gomp_adjust_sched (sched, &chunk_size);
614c0a68be4Smrg gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
615c0a68be4Smrg sched, chunk_size);
616c0a68be4Smrg gomp_doacross_ull_init (ncounts, counts, chunk_size, extra);
617c0a68be4Smrg if (reductions)
618c0a68be4Smrg {
619c0a68be4Smrg GOMP_taskgroup_reduction_register (reductions);
620c0a68be4Smrg thr->task->taskgroup->workshare = true;
621c0a68be4Smrg thr->ts.work_share->task_reductions = reductions;
622c0a68be4Smrg }
623c0a68be4Smrg gomp_work_share_init_done ();
624c0a68be4Smrg }
625c0a68be4Smrg else
626c0a68be4Smrg {
627c0a68be4Smrg if (reductions)
628c0a68be4Smrg {
629c0a68be4Smrg uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
630c0a68be4Smrg gomp_workshare_task_reduction_register (reductions,
631c0a68be4Smrg first_reductions);
632c0a68be4Smrg }
633c0a68be4Smrg sched = thr->ts.work_share->sched;
634c0a68be4Smrg }
635c0a68be4Smrg
636c0a68be4Smrg if (mem)
637c0a68be4Smrg *mem = thr->ts.work_share->doacross->extra;
638c0a68be4Smrg
639c0a68be4Smrg return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
640c0a68be4Smrg }
641c0a68be4Smrg
6421debfc3dSmrg /* The *_next routines are called when the thread completes processing of
6431debfc3dSmrg the iteration block currently assigned to it. If the work-share
6441debfc3dSmrg construct is bound directly to a parallel construct, then the iteration
6451debfc3dSmrg bounds may have been set up before the parallel. In which case, this
6461debfc3dSmrg may be the first iteration for the thread.
6471debfc3dSmrg
6481debfc3dSmrg Returns true if there is work remaining to be performed; *ISTART and
6491debfc3dSmrg *IEND are filled with a new iteration block. Returns false if all work
6501debfc3dSmrg has been assigned. */
6511debfc3dSmrg
6521debfc3dSmrg static bool
gomp_loop_ull_static_next(gomp_ull * istart,gomp_ull * iend)6531debfc3dSmrg gomp_loop_ull_static_next (gomp_ull *istart, gomp_ull *iend)
6541debfc3dSmrg {
6551debfc3dSmrg return !gomp_iter_ull_static_next (istart, iend);
6561debfc3dSmrg }
6571debfc3dSmrg
6581debfc3dSmrg static bool
gomp_loop_ull_dynamic_next(gomp_ull * istart,gomp_ull * iend)6591debfc3dSmrg gomp_loop_ull_dynamic_next (gomp_ull *istart, gomp_ull *iend)
6601debfc3dSmrg {
6611debfc3dSmrg bool ret;
6621debfc3dSmrg
6631debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
6641debfc3dSmrg ret = gomp_iter_ull_dynamic_next (istart, iend);
6651debfc3dSmrg #else
6661debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
6671debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
6681debfc3dSmrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
6691debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
6701debfc3dSmrg #endif
6711debfc3dSmrg
6721debfc3dSmrg return ret;
6731debfc3dSmrg }
6741debfc3dSmrg
6751debfc3dSmrg static bool
gomp_loop_ull_guided_next(gomp_ull * istart,gomp_ull * iend)6761debfc3dSmrg gomp_loop_ull_guided_next (gomp_ull *istart, gomp_ull *iend)
6771debfc3dSmrg {
6781debfc3dSmrg bool ret;
6791debfc3dSmrg
6801debfc3dSmrg #if defined HAVE_SYNC_BUILTINS && defined __LP64__
6811debfc3dSmrg ret = gomp_iter_ull_guided_next (istart, iend);
6821debfc3dSmrg #else
6831debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
6841debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
6851debfc3dSmrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
6861debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
6871debfc3dSmrg #endif
6881debfc3dSmrg
6891debfc3dSmrg return ret;
6901debfc3dSmrg }
6911debfc3dSmrg
6921debfc3dSmrg bool
GOMP_loop_ull_runtime_next(gomp_ull * istart,gomp_ull * iend)6931debfc3dSmrg GOMP_loop_ull_runtime_next (gomp_ull *istart, gomp_ull *iend)
6941debfc3dSmrg {
6951debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
6961debfc3dSmrg
6971debfc3dSmrg switch (thr->ts.work_share->sched)
6981debfc3dSmrg {
6991debfc3dSmrg case GFS_STATIC:
7001debfc3dSmrg case GFS_AUTO:
7011debfc3dSmrg return gomp_loop_ull_static_next (istart, iend);
7021debfc3dSmrg case GFS_DYNAMIC:
7031debfc3dSmrg return gomp_loop_ull_dynamic_next (istart, iend);
7041debfc3dSmrg case GFS_GUIDED:
7051debfc3dSmrg return gomp_loop_ull_guided_next (istart, iend);
7061debfc3dSmrg default:
7071debfc3dSmrg abort ();
7081debfc3dSmrg }
7091debfc3dSmrg }
7101debfc3dSmrg
7111debfc3dSmrg /* The *_ordered_*_next routines are called when the thread completes
7121debfc3dSmrg processing of the iteration block currently assigned to it.
7131debfc3dSmrg
7141debfc3dSmrg Returns true if there is work remaining to be performed; *ISTART and
7151debfc3dSmrg *IEND are filled with a new iteration block. Returns false if all work
7161debfc3dSmrg has been assigned. */
7171debfc3dSmrg
7181debfc3dSmrg static bool
gomp_loop_ull_ordered_static_next(gomp_ull * istart,gomp_ull * iend)7191debfc3dSmrg gomp_loop_ull_ordered_static_next (gomp_ull *istart, gomp_ull *iend)
7201debfc3dSmrg {
7211debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
7221debfc3dSmrg int test;
7231debfc3dSmrg
7241debfc3dSmrg gomp_ordered_sync ();
7251debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
7261debfc3dSmrg test = gomp_iter_ull_static_next (istart, iend);
7271debfc3dSmrg if (test >= 0)
7281debfc3dSmrg gomp_ordered_static_next ();
7291debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
7301debfc3dSmrg
7311debfc3dSmrg return test == 0;
7321debfc3dSmrg }
7331debfc3dSmrg
7341debfc3dSmrg static bool
gomp_loop_ull_ordered_dynamic_next(gomp_ull * istart,gomp_ull * iend)7351debfc3dSmrg gomp_loop_ull_ordered_dynamic_next (gomp_ull *istart, gomp_ull *iend)
7361debfc3dSmrg {
7371debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
7381debfc3dSmrg bool ret;
7391debfc3dSmrg
7401debfc3dSmrg gomp_ordered_sync ();
7411debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
7421debfc3dSmrg ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
7431debfc3dSmrg if (ret)
7441debfc3dSmrg gomp_ordered_next ();
7451debfc3dSmrg else
7461debfc3dSmrg gomp_ordered_last ();
7471debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
7481debfc3dSmrg
7491debfc3dSmrg return ret;
7501debfc3dSmrg }
7511debfc3dSmrg
7521debfc3dSmrg static bool
gomp_loop_ull_ordered_guided_next(gomp_ull * istart,gomp_ull * iend)7531debfc3dSmrg gomp_loop_ull_ordered_guided_next (gomp_ull *istart, gomp_ull *iend)
7541debfc3dSmrg {
7551debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
7561debfc3dSmrg bool ret;
7571debfc3dSmrg
7581debfc3dSmrg gomp_ordered_sync ();
7591debfc3dSmrg gomp_mutex_lock (&thr->ts.work_share->lock);
7601debfc3dSmrg ret = gomp_iter_ull_guided_next_locked (istart, iend);
7611debfc3dSmrg if (ret)
7621debfc3dSmrg gomp_ordered_next ();
7631debfc3dSmrg else
7641debfc3dSmrg gomp_ordered_last ();
7651debfc3dSmrg gomp_mutex_unlock (&thr->ts.work_share->lock);
7661debfc3dSmrg
7671debfc3dSmrg return ret;
7681debfc3dSmrg }
7691debfc3dSmrg
7701debfc3dSmrg bool
GOMP_loop_ull_ordered_runtime_next(gomp_ull * istart,gomp_ull * iend)7711debfc3dSmrg GOMP_loop_ull_ordered_runtime_next (gomp_ull *istart, gomp_ull *iend)
7721debfc3dSmrg {
7731debfc3dSmrg struct gomp_thread *thr = gomp_thread ();
7741debfc3dSmrg
7751debfc3dSmrg switch (thr->ts.work_share->sched)
7761debfc3dSmrg {
7771debfc3dSmrg case GFS_STATIC:
7781debfc3dSmrg case GFS_AUTO:
7791debfc3dSmrg return gomp_loop_ull_ordered_static_next (istart, iend);
7801debfc3dSmrg case GFS_DYNAMIC:
7811debfc3dSmrg return gomp_loop_ull_ordered_dynamic_next (istart, iend);
7821debfc3dSmrg case GFS_GUIDED:
7831debfc3dSmrg return gomp_loop_ull_ordered_guided_next (istart, iend);
7841debfc3dSmrg default:
7851debfc3dSmrg abort ();
7861debfc3dSmrg }
7871debfc3dSmrg }
7881debfc3dSmrg
7891debfc3dSmrg /* We use static functions above so that we're sure that the "runtime"
7901debfc3dSmrg function can defer to the proper routine without interposition. We
7911debfc3dSmrg export the static function with a strong alias when possible, or with
7921debfc3dSmrg a wrapper function otherwise. */
7931debfc3dSmrg
7941debfc3dSmrg #ifdef HAVE_ATTRIBUTE_ALIAS
7951debfc3dSmrg extern __typeof(gomp_loop_ull_static_start) GOMP_loop_ull_static_start
7961debfc3dSmrg __attribute__((alias ("gomp_loop_ull_static_start")));
7971debfc3dSmrg extern __typeof(gomp_loop_ull_dynamic_start) GOMP_loop_ull_dynamic_start
7981debfc3dSmrg __attribute__((alias ("gomp_loop_ull_dynamic_start")));
7991debfc3dSmrg extern __typeof(gomp_loop_ull_guided_start) GOMP_loop_ull_guided_start
8001debfc3dSmrg __attribute__((alias ("gomp_loop_ull_guided_start")));
8011debfc3dSmrg extern __typeof(gomp_loop_ull_dynamic_start) GOMP_loop_ull_nonmonotonic_dynamic_start
8021debfc3dSmrg __attribute__((alias ("gomp_loop_ull_dynamic_start")));
8031debfc3dSmrg extern __typeof(gomp_loop_ull_guided_start) GOMP_loop_ull_nonmonotonic_guided_start
8041debfc3dSmrg __attribute__((alias ("gomp_loop_ull_guided_start")));
805c0a68be4Smrg extern __typeof(GOMP_loop_ull_runtime_start) GOMP_loop_ull_nonmonotonic_runtime_start
806c0a68be4Smrg __attribute__((alias ("GOMP_loop_ull_runtime_start")));
807c0a68be4Smrg extern __typeof(GOMP_loop_ull_runtime_start) GOMP_loop_ull_maybe_nonmonotonic_runtime_start
808c0a68be4Smrg __attribute__((alias ("GOMP_loop_ull_runtime_start")));
8091debfc3dSmrg
8101debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_static_start) GOMP_loop_ull_ordered_static_start
8111debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_static_start")));
8121debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_dynamic_start) GOMP_loop_ull_ordered_dynamic_start
8131debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_dynamic_start")));
8141debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_guided_start) GOMP_loop_ull_ordered_guided_start
8151debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_guided_start")));
8161debfc3dSmrg
8171debfc3dSmrg extern __typeof(gomp_loop_ull_doacross_static_start) GOMP_loop_ull_doacross_static_start
8181debfc3dSmrg __attribute__((alias ("gomp_loop_ull_doacross_static_start")));
8191debfc3dSmrg extern __typeof(gomp_loop_ull_doacross_dynamic_start) GOMP_loop_ull_doacross_dynamic_start
8201debfc3dSmrg __attribute__((alias ("gomp_loop_ull_doacross_dynamic_start")));
8211debfc3dSmrg extern __typeof(gomp_loop_ull_doacross_guided_start) GOMP_loop_ull_doacross_guided_start
8221debfc3dSmrg __attribute__((alias ("gomp_loop_ull_doacross_guided_start")));
8231debfc3dSmrg
8241debfc3dSmrg extern __typeof(gomp_loop_ull_static_next) GOMP_loop_ull_static_next
8251debfc3dSmrg __attribute__((alias ("gomp_loop_ull_static_next")));
8261debfc3dSmrg extern __typeof(gomp_loop_ull_dynamic_next) GOMP_loop_ull_dynamic_next
8271debfc3dSmrg __attribute__((alias ("gomp_loop_ull_dynamic_next")));
8281debfc3dSmrg extern __typeof(gomp_loop_ull_guided_next) GOMP_loop_ull_guided_next
8291debfc3dSmrg __attribute__((alias ("gomp_loop_ull_guided_next")));
8301debfc3dSmrg extern __typeof(gomp_loop_ull_dynamic_next) GOMP_loop_ull_nonmonotonic_dynamic_next
8311debfc3dSmrg __attribute__((alias ("gomp_loop_ull_dynamic_next")));
8321debfc3dSmrg extern __typeof(gomp_loop_ull_guided_next) GOMP_loop_ull_nonmonotonic_guided_next
8331debfc3dSmrg __attribute__((alias ("gomp_loop_ull_guided_next")));
834c0a68be4Smrg extern __typeof(GOMP_loop_ull_runtime_next) GOMP_loop_ull_nonmonotonic_runtime_next
835c0a68be4Smrg __attribute__((alias ("GOMP_loop_ull_runtime_next")));
836c0a68be4Smrg extern __typeof(GOMP_loop_ull_runtime_next) GOMP_loop_ull_maybe_nonmonotonic_runtime_next
837c0a68be4Smrg __attribute__((alias ("GOMP_loop_ull_runtime_next")));
8381debfc3dSmrg
8391debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_static_next) GOMP_loop_ull_ordered_static_next
8401debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_static_next")));
8411debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_dynamic_next) GOMP_loop_ull_ordered_dynamic_next
8421debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_dynamic_next")));
8431debfc3dSmrg extern __typeof(gomp_loop_ull_ordered_guided_next) GOMP_loop_ull_ordered_guided_next
8441debfc3dSmrg __attribute__((alias ("gomp_loop_ull_ordered_guided_next")));
8451debfc3dSmrg #else
8461debfc3dSmrg bool
GOMP_loop_ull_static_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)8471debfc3dSmrg GOMP_loop_ull_static_start (bool up, gomp_ull start, gomp_ull end,
8481debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
8491debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
8501debfc3dSmrg {
8511debfc3dSmrg return gomp_loop_ull_static_start (up, start, end, incr, chunk_size, istart,
8521debfc3dSmrg iend);
8531debfc3dSmrg }
8541debfc3dSmrg
8551debfc3dSmrg bool
GOMP_loop_ull_dynamic_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)8561debfc3dSmrg GOMP_loop_ull_dynamic_start (bool up, gomp_ull start, gomp_ull end,
8571debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
8581debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
8591debfc3dSmrg {
8601debfc3dSmrg return gomp_loop_ull_dynamic_start (up, start, end, incr, chunk_size, istart,
8611debfc3dSmrg iend);
8621debfc3dSmrg }
8631debfc3dSmrg
8641debfc3dSmrg bool
GOMP_loop_ull_guided_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)8651debfc3dSmrg GOMP_loop_ull_guided_start (bool up, gomp_ull start, gomp_ull end,
8661debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
8671debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
8681debfc3dSmrg {
8691debfc3dSmrg return gomp_loop_ull_guided_start (up, start, end, incr, chunk_size, istart,
8701debfc3dSmrg iend);
8711debfc3dSmrg }
8721debfc3dSmrg
8731debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_dynamic_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)8741debfc3dSmrg GOMP_loop_ull_nonmonotonic_dynamic_start (bool up, gomp_ull start,
8751debfc3dSmrg gomp_ull end, gomp_ull incr,
8761debfc3dSmrg gomp_ull chunk_size,
8771debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
8781debfc3dSmrg {
8791debfc3dSmrg return gomp_loop_ull_dynamic_start (up, start, end, incr, chunk_size, istart,
8801debfc3dSmrg iend);
8811debfc3dSmrg }
8821debfc3dSmrg
8831debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_guided_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)8841debfc3dSmrg GOMP_loop_ull_nonmonotonic_guided_start (bool up, gomp_ull start, gomp_ull end,
8851debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
8861debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
8871debfc3dSmrg {
8881debfc3dSmrg return gomp_loop_ull_guided_start (up, start, end, incr, chunk_size, istart,
8891debfc3dSmrg iend);
8901debfc3dSmrg }
8911debfc3dSmrg
8921debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_runtime_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull * istart,gomp_ull * iend)893c0a68be4Smrg GOMP_loop_ull_nonmonotonic_runtime_start (bool up, gomp_ull start,
894c0a68be4Smrg gomp_ull end, gomp_ull incr,
895c0a68be4Smrg gomp_ull *istart, gomp_ull *iend)
896c0a68be4Smrg {
897c0a68be4Smrg return GOMP_loop_ull_runtime_start (up, start, end, incr, istart, iend);
898c0a68be4Smrg }
899c0a68be4Smrg
900c0a68be4Smrg bool
GOMP_loop_ull_maybe_nonmonotonic_runtime_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull * istart,gomp_ull * iend)901c0a68be4Smrg GOMP_loop_ull_maybe_nonmonotonic_runtime_start (bool up, gomp_ull start,
902c0a68be4Smrg gomp_ull end, gomp_ull incr,
903c0a68be4Smrg gomp_ull *istart,
904c0a68be4Smrg gomp_ull *iend)
905c0a68be4Smrg {
906c0a68be4Smrg return GOMP_loop_ull_runtime_start (up, start, end, incr, istart, iend);
907c0a68be4Smrg }
908c0a68be4Smrg
909c0a68be4Smrg bool
GOMP_loop_ull_ordered_static_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9101debfc3dSmrg GOMP_loop_ull_ordered_static_start (bool up, gomp_ull start, gomp_ull end,
9111debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
9121debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
9131debfc3dSmrg {
9141debfc3dSmrg return gomp_loop_ull_ordered_static_start (up, start, end, incr, chunk_size,
9151debfc3dSmrg istart, iend);
9161debfc3dSmrg }
9171debfc3dSmrg
9181debfc3dSmrg bool
GOMP_loop_ull_ordered_dynamic_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9191debfc3dSmrg GOMP_loop_ull_ordered_dynamic_start (bool up, gomp_ull start, gomp_ull end,
9201debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
9211debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
9221debfc3dSmrg {
9231debfc3dSmrg return gomp_loop_ull_ordered_dynamic_start (up, start, end, incr, chunk_size,
9241debfc3dSmrg istart, iend);
9251debfc3dSmrg }
9261debfc3dSmrg
9271debfc3dSmrg bool
GOMP_loop_ull_ordered_guided_start(bool up,gomp_ull start,gomp_ull end,gomp_ull incr,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9281debfc3dSmrg GOMP_loop_ull_ordered_guided_start (bool up, gomp_ull start, gomp_ull end,
9291debfc3dSmrg gomp_ull incr, gomp_ull chunk_size,
9301debfc3dSmrg gomp_ull *istart, gomp_ull *iend)
9311debfc3dSmrg {
9321debfc3dSmrg return gomp_loop_ull_ordered_guided_start (up, start, end, incr, chunk_size,
9331debfc3dSmrg istart, iend);
9341debfc3dSmrg }
9351debfc3dSmrg
9361debfc3dSmrg bool
GOMP_loop_ull_doacross_static_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9371debfc3dSmrg GOMP_loop_ull_doacross_static_start (unsigned ncounts, gomp_ull *counts,
9381debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
9391debfc3dSmrg gomp_ull *iend)
9401debfc3dSmrg {
9411debfc3dSmrg return gomp_loop_ull_doacross_static_start (ncounts, counts, chunk_size,
9421debfc3dSmrg istart, iend);
9431debfc3dSmrg }
9441debfc3dSmrg
9451debfc3dSmrg bool
GOMP_loop_ull_doacross_dynamic_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9461debfc3dSmrg GOMP_loop_ull_doacross_dynamic_start (unsigned ncounts, gomp_ull *counts,
9471debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
9481debfc3dSmrg gomp_ull *iend)
9491debfc3dSmrg {
9501debfc3dSmrg return gomp_loop_ull_doacross_dynamic_start (ncounts, counts, chunk_size,
9511debfc3dSmrg istart, iend);
9521debfc3dSmrg }
9531debfc3dSmrg
9541debfc3dSmrg bool
GOMP_loop_ull_doacross_guided_start(unsigned ncounts,gomp_ull * counts,gomp_ull chunk_size,gomp_ull * istart,gomp_ull * iend)9551debfc3dSmrg GOMP_loop_ull_doacross_guided_start (unsigned ncounts, gomp_ull *counts,
9561debfc3dSmrg gomp_ull chunk_size, gomp_ull *istart,
9571debfc3dSmrg gomp_ull *iend)
9581debfc3dSmrg {
9591debfc3dSmrg return gomp_loop_ull_doacross_guided_start (ncounts, counts, chunk_size,
9601debfc3dSmrg istart, iend);
9611debfc3dSmrg }
9621debfc3dSmrg
9631debfc3dSmrg bool
GOMP_loop_ull_static_next(gomp_ull * istart,gomp_ull * iend)9641debfc3dSmrg GOMP_loop_ull_static_next (gomp_ull *istart, gomp_ull *iend)
9651debfc3dSmrg {
9661debfc3dSmrg return gomp_loop_ull_static_next (istart, iend);
9671debfc3dSmrg }
9681debfc3dSmrg
9691debfc3dSmrg bool
GOMP_loop_ull_dynamic_next(gomp_ull * istart,gomp_ull * iend)9701debfc3dSmrg GOMP_loop_ull_dynamic_next (gomp_ull *istart, gomp_ull *iend)
9711debfc3dSmrg {
9721debfc3dSmrg return gomp_loop_ull_dynamic_next (istart, iend);
9731debfc3dSmrg }
9741debfc3dSmrg
9751debfc3dSmrg bool
GOMP_loop_ull_guided_next(gomp_ull * istart,gomp_ull * iend)9761debfc3dSmrg GOMP_loop_ull_guided_next (gomp_ull *istart, gomp_ull *iend)
9771debfc3dSmrg {
9781debfc3dSmrg return gomp_loop_ull_guided_next (istart, iend);
9791debfc3dSmrg }
9801debfc3dSmrg
9811debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_dynamic_next(gomp_ull * istart,gomp_ull * iend)9821debfc3dSmrg GOMP_loop_ull_nonmonotonic_dynamic_next (gomp_ull *istart, gomp_ull *iend)
9831debfc3dSmrg {
9841debfc3dSmrg return gomp_loop_ull_dynamic_next (istart, iend);
9851debfc3dSmrg }
9861debfc3dSmrg
9871debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_guided_next(gomp_ull * istart,gomp_ull * iend)9881debfc3dSmrg GOMP_loop_ull_nonmonotonic_guided_next (gomp_ull *istart, gomp_ull *iend)
9891debfc3dSmrg {
9901debfc3dSmrg return gomp_loop_ull_guided_next (istart, iend);
9911debfc3dSmrg }
9921debfc3dSmrg
9931debfc3dSmrg bool
GOMP_loop_ull_nonmonotonic_runtime_next(gomp_ull * istart,gomp_ull * iend)994c0a68be4Smrg GOMP_loop_ull_nonmonotonic_runtime_next (gomp_ull *istart, gomp_ull *iend)
995c0a68be4Smrg {
996c0a68be4Smrg return GOMP_loop_ull_runtime_next (istart, iend);
997c0a68be4Smrg }
998c0a68be4Smrg
999c0a68be4Smrg bool
GOMP_loop_ull_maybe_nonmonotonic_runtime_next(gomp_ull * istart,gomp_ull * iend)1000c0a68be4Smrg GOMP_loop_ull_maybe_nonmonotonic_runtime_next (gomp_ull *istart,
1001c0a68be4Smrg gomp_ull *iend)
1002c0a68be4Smrg {
1003c0a68be4Smrg return GOMP_loop_ull_runtime_next (istart, iend);
1004c0a68be4Smrg }
1005c0a68be4Smrg
1006c0a68be4Smrg bool
GOMP_loop_ull_ordered_static_next(gomp_ull * istart,gomp_ull * iend)10071debfc3dSmrg GOMP_loop_ull_ordered_static_next (gomp_ull *istart, gomp_ull *iend)
10081debfc3dSmrg {
10091debfc3dSmrg return gomp_loop_ull_ordered_static_next (istart, iend);
10101debfc3dSmrg }
10111debfc3dSmrg
10121debfc3dSmrg bool
GOMP_loop_ull_ordered_dynamic_next(gomp_ull * istart,gomp_ull * iend)10131debfc3dSmrg GOMP_loop_ull_ordered_dynamic_next (gomp_ull *istart, gomp_ull *iend)
10141debfc3dSmrg {
10151debfc3dSmrg return gomp_loop_ull_ordered_dynamic_next (istart, iend);
10161debfc3dSmrg }
10171debfc3dSmrg
10181debfc3dSmrg bool
GOMP_loop_ull_ordered_guided_next(gomp_ull * istart,gomp_ull * iend)10191debfc3dSmrg GOMP_loop_ull_ordered_guided_next (gomp_ull *istart, gomp_ull *iend)
10201debfc3dSmrg {
10211debfc3dSmrg return gomp_loop_ull_ordered_guided_next (istart, iend);
10221debfc3dSmrg }
10231debfc3dSmrg #endif
1024