/* PR target/78694. */ enum { MEMMODEL_RELAXED, MEMMODEL_ACQUIRE, PRIORITY_INSERT_END }; enum { PQ_CHILDREN, PQ_TASKGROUP }; struct gomp_team_state { struct gomp_team *team; }; enum gomp_task_kind { GOMP_TASK_UNDEFERRED, GOMP_TASK_WAITING }; struct gomp_taskwait { _Bool in_taskwait; }; struct gomp_task { struct gomp_task *parent; int children_queue; struct gomp_taskgroup *taskgroup; int dependers; struct gomp_taskwait taskwait; enum gomp_task_kind kind; _Bool in_tied_task; } j, q, *n; struct gomp_taskgroup { _Bool in_taskgroup_wait; int num_children; } l; struct gomp_team { int task_queue; int task_running_count; }; struct gomp_thread { struct gomp_team_state ts; struct gomp_task task; } extern __thread a; int b, c, d, e, f, g, h, i, k, m, o, p, r; void priority_queue_next_task (struct gomp_task *, int, int); int gomp_task_run_pre (struct gomp_task *, struct gomp_task, struct gomp_team); void priority_queue_insert (int, struct gomp_task); void priority_queue_insert2 (int, struct gomp_task, int, int, int); void priority_queue_insert3 (int, struct gomp_task, int, int, int); void gomp_sem_post (int); void free (void *); _Bool s; int GOMP_taskgroup_end () { struct gomp_thread *t = &a; struct gomp_team u = *t->ts.team; struct gomp_task *v = &t->task, *w; if (__atomic_load_n (&l.num_children, MEMMODEL_ACQUIRE)) while (1) { if (l.num_children) priority_queue_next_task (v, u.task_queue, r); else if (w) free (w); if (n->kind == GOMP_TASK_WAITING) { s = gomp_task_run_pre (n, q, u); if (__builtin_expect (s, 0)) { if (w) free (w); goto finish_cancelled; } n = 0; l.in_taskgroup_wait = 1; } if (w) { t->task = *n; if (__builtin_expect (p, 0)) if (o) t->task = *v; } if (n) { struct gomp_task x = x; for (; i; b++) { struct gomp_task y = j; if (g) continue; priority_queue_insert (PQ_CHILDREN, x); if (x.taskwait.in_taskwait) priority_queue_insert2 (PQ_TASKGROUP, y, e, 0, d); if (h) gomp_sem_post (f); priority_queue_insert3 (k, y, PRIORITY_INSERT_END, 0, d); ++c; } } finish_cancelled: w = (struct gomp_task *) (n - u.task_running_count - v); } v->taskgroup = (struct gomp_taskgroup *) m; return 1; }