1 /*
2  * Copyright (c) 2016-2019, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /** \file
19  * \brief outliner.c - extract regions into subroutines; add uplevel references
20  * as arguments
21  *
22  */
23 
24 #define _GNU_SOURCE // for vasprintf()
25 #include <stdio.h>
26 #undef _GNU_SOURCE
27 #include "kmpcutil.h"
28 #include "error.h"
29 #include "semant.h"
30 #include "ilmtp.h"
31 #include "ilm.h"
32 #include "ili.h"
33 #include "expand.h"
34 #include "exputil.h"
35 #include "outliner.h"
36 #include "machreg.h"
37 #include "mp.h"
38 #include "ll_structure.h"
39 #include "llmputil.h"
40 #include "llutil.h"
41 #if defined(OMP_OFFLOAD_LLVM) || defined(OMP_OFFLOAD_PGI)
42 #include "ompaccel.h"
43 #endif
44 #include "cgllvm.h"
45 #include "cgmain.h"
46 #include <unistd.h>
47 #include "regutil.h"
48 #include "dtypeutl.h"
49 #include "llassem.h"
50 #include "ll_ftn.h"
51 #include "symfun.h"
52 
53 #define MXIDLEN 250
54 static DTYPE kmpc_ident_dtype;
55 
56 /* Flags for use with the entry */
57 #define DT_VOID_NONE DT_NONE
58 
59 #define KMPC_FLAG_NONE 0x00
60 #define KMPC_FLAG_STR_FMT 0x01 /* Treat KMPC_NAME as a format str */
61 
62 #ifdef __cplusplus
63 static class ClassKmpcApiCalls
64 {
65 public:
operator [](int off)66   const struct kmpc_api_entry_t operator[](int off)
67   {
68     switch (off) {
69     case KMPC_API_BAD:
70       return {"__INVALID_KMPC_API_NAME__", (ILI_OP)-1, (DTYPE)-1, -1};
71     case KMPC_API_FORK_CALL:
72       return {"__kmpc_fork_call", IL_NONE, DT_VOID_NONE, 0};
73     case KMPC_API_BARRIER:
74       return {"__kmpc_barrier", IL_NONE, DT_VOID_NONE, 0};
75     case KMPC_API_CANCEL_BARRIER:
76       return {"__kmpc_cancel_barrier", IL_NONE, DT_VOID_NONE, 0};
77     case KMPC_API_COPYPRIVATE:
78       return {"__kmpc_copyprivate", IL_NONE, DT_VOID_NONE, 0};
79     case KMPC_API_CRITICAL:
80       return {"__kmpc_critical", IL_NONE, DT_VOID_NONE, 0};
81     case KMPC_API_END_CRITICAL:
82       return {"__kmpc_end_critical", IL_NONE, DT_VOID_NONE, 0};
83     case KMPC_API_SINGLE:
84       return {"__kmpc_single", IL_DFRIR, DT_INT, 0};
85     case KMPC_API_END_SINGLE:
86       return {"__kmpc_end_single", IL_NONE, DT_VOID_NONE, 0};
87     case KMPC_API_MASTER:
88       return {"__kmpc_master", IL_DFRIR, DT_INT, 0};
89     case KMPC_API_END_MASTER:
90       return {"__kmpc_end_master", IL_NONE, DT_VOID_NONE, 0};
91     case KMPC_API_FLUSH:
92       return {"__kmpc_flush", IL_NONE, DT_VOID_NONE, 0};
93     case KMPC_API_ORDERED:
94       return {"__kmpc_ordered", IL_NONE, DT_VOID_NONE, 0};
95     case KMPC_API_END_ORDERED:
96       return {"__kmpc_end_ordered", IL_NONE, DT_VOID_NONE, 0};
97     case KMPC_API_FOR_STATIC_INIT:
98       return {"__kmpc_for_static_init_%d%s", IL_NONE, DT_VOID_NONE,
99               KMPC_FLAG_STR_FMT};
100     case KMPC_API_FOR_STATIC_FINI:
101       return {"__kmpc_for_static_fini", IL_NONE, DT_VOID_NONE, 0};
102     case KMPC_API_DISPATCH_INIT:
103       return {"__kmpc_dispatch_init_%d%s", IL_NONE, DT_VOID_NONE,
104               KMPC_FLAG_STR_FMT}; /*4,4u,8,8u are possible*/
105     case KMPC_API_DISPATCH_NEXT:
106       return {"__kmpc_dispatch_next_%d%s", IL_DFRIR, DT_INT,
107               KMPC_FLAG_STR_FMT}; /*4,4u,8,8u are possible*/
108     case KMPC_API_DISPATCH_FINI:
109       return {"__kmpc_dispatch_fini_%d%s", IL_NONE, DT_VOID_NONE,
110               KMPC_FLAG_STR_FMT}; /*4,4u,8,8u are possible*/
111     case KMPC_API_GLOBAL_THREAD_NUM:
112       return {"__kmpc_global_thread_num", IL_DFRIR, DT_INT, 0};
113     case KMPC_API_GLOBAL_NUM_THREADS:
114       return {"__kmpc_global_num_threads", IL_DFRIR, DT_INT, 0};
115     case KMPC_API_BOUND_THREAD_NUM:
116       return {"__kmpc_bound_thread_num", IL_DFRIR, DT_INT, 0};
117     case KMPC_API_BOUND_NUM_THREADS:
118       return {"__kmpc_bound_num_threads", IL_DFRIR, DT_INT, 0};
119     case KMPC_API_PUSH_NUM_THREADS:
120       return {"__kmpc_push_num_threads", IL_NONE, DT_VOID_NONE, 0};
121     case KMPC_API_SERIALIZED_PARALLEL:
122       return {"__kmpc_serialized_parallel", IL_NONE, DT_VOID_NONE, 0};
123     case KMPC_API_END_SERIALIZED_PARALLEL:
124       return {"__kmpc_end_serialized_parallel", IL_NONE, DT_VOID_NONE, 0};
125     case KMPC_API_THREADPRIVATE_CACHED:
126       return {"__kmpc_threadprivate_cached", IL_DFRAR, DT_CPTR, 0};
127     case KMPC_API_THREADPRIVATE_REGISTER_VEC:
128       return {"__kmpc_threadprivate_register_vec", IL_NONE, DT_VOID_NONE, 0};
129     case KMPC_API_THREADPRIVATE_REGISTER:
130       return {"__kmpc_threadprivate_register", IL_NONE, DT_VOID_NONE, 0};
131     case KMPC_API_TASK:
132       return {"__kmpc_omp_task", IL_NONE, DT_VOID_NONE, 0};
133     case KMPC_API_TASK_BEGIN_IF0:
134       return {"__kmpc_omp_task_begin_if0", IL_NONE, DT_VOID_NONE, 0};
135     case KMPC_API_TASK_COMPLETE_IF0:
136       return {"__kmpc_omp_task_complete_if0", IL_NONE, DT_VOID_NONE, 0};
137     case KMPC_API_TASK_ALLOC:
138       return {"__kmpc_omp_task_alloc", IL_DFRAR, DT_CPTR, 0};
139     case KMPC_API_TASK_WAIT:
140       return {"__kmpc_omp_taskwait", IL_DFRIR, DT_INT, 0};
141     case KMPC_API_TASK_YIELD:
142       return {"__kmpc_omp_taskyield", IL_DFRIR, DT_INT, 0};
143     case KMPC_API_CANCEL:
144       return {"__kmpc_cancel", IL_DFRIR, DT_INT, 0};
145     case KMPC_API_CANCELLATIONPOINT:
146       return {"__kmpc_cancellationpoint", IL_DFRIR, DT_INT, 0};
147     case KMPC_API_TASKGROUP:
148       return {"__kmpc_taskgroup", IL_NONE, DT_VOID_NONE, 0};
149     case KMPC_API_END_TASKGROUP:
150       return {"__kmpc_end_taskgroup", IL_NONE, DT_VOID_NONE, 0};
151     case KMPC_API_TASK_WITH_DEPS:
152       return {"__kmpc_task_with_deps", IL_DFRIR, DT_INT, 0};
153     case KMPC_API_WAIT_DEPS:
154       return {"__kmpc_wait_deps", IL_NONE, DT_VOID_NONE, 0};
155     case KMPC_API_TASKLOOP:
156       return {"__kmpc_taskloop", IL_NONE, DT_VOID_NONE, 0};
157     case KMPC_API_THREADPRIVATE:
158       return {"__kmpc_threadprivate", IL_DFRAR, DT_CPTR, 0};
159     case KMPC_API_FORK_TEAMS:
160       return {"__kmpc_fork_teams", IL_NONE, DT_VOID_NONE, 0};
161     case KMPC_API_PUSH_NUM_TEAMS:
162       return {"__kmpc_push_num_teams", IL_NONE, DT_VOID_NONE, 0};
163     case KMPC_API_DIST_FOR_STATIC_INIT:
164       return {"__kmpc_dist_for_static_init_%d%s", IL_NONE, DT_VOID_NONE,
165               KMPC_FLAG_STR_FMT};
166     case KMPC_API_DIST_DISPATCH_INIT:
167       return {"__kmpc_dist_dispatch_init_%d%s", IL_NONE, DT_VOID_NONE,
168               KMPC_FLAG_STR_FMT}; /*4,4u,8,8u are possible*/
169     case KMPC_API_PUSH_PROC_BIND:
170       return {"__kmpc_push_proc_bind", IL_NONE, DT_VOID_NONE, 0};
171     case KMPC_API_ATOMIC_RD:
172       return {"__kmpc_atomic_%s%d_rd", IL_NONE, DT_VOID_NONE,
173               KMPC_FLAG_STR_FMT};
174     case KMPC_API_ATOMIC_WR:
175       return {"__kmpc_atomic_%s%d_wr", IL_NONE, DT_VOID_NONE,
176               KMPC_FLAG_STR_FMT};
177       /* OpenMP Accelerator RT (libomptarget-nvptx) - non standard - */
178     case KMPC_API_FOR_STATIC_INIT_SIMPLE_SPMD:
179       return {"__kmpc_for_static_init_%d%s_simple_spmd", IL_NONE, DT_VOID_NONE,
180               KMPC_FLAG_STR_FMT};
181       break;
182     case KMPC_API_SPMD_KERNEL_INIT:
183       return {"__kmpc_spmd_kernel_init", IL_NONE, DT_VOID_NONE, 0};
184       break;
185     case KMPC_API_PUSH_TARGET_TRIPCOUNT:
186       return {"__kmpc_push_target_tripcount", IL_NONE, DT_VOID_NONE, 0};
187       break;
188     case KMPC_API_KERNEL_INIT_PARAMS:
189       return {"__kmpc_kernel_init_params", IL_NONE, DT_VOID_NONE, 0};
190       break;
191     case KMPC_API_SHUFFLE_I32:
192       return {"__kmpc_shuffle_int32", IL_NONE, DT_INT, 0};
193       break;
194     case KMPC_API_SHUFFLE_I64:
195       return {"__kmpc_shuffle_int64", IL_NONE, DT_INT8, 0};
196       break;
197     case KMPC_API_NVPTX_PARALLEL_REDUCE_NOWAIT_SIMPLE_SPMD:
198       return {"__kmpc_nvptx_parallel_reduce_nowait_simple_spmd", IL_NONE,
199               DT_INT, 0};
200       break;
201     case KMPC_API_NVPTX_END_REDUCE_NOWAIT:
202       return {"__kmpc_nvptx_end_reduce_nowait", IL_NONE, DT_VOID_NONE, 0};
203       break;
204     default:
205       return {NULL, IL_NONE, DT_NONE, 0};
206     }
207   }
208 } kmpc_api_calls;
209 #else
210 static const struct kmpc_api_entry_t kmpc_api_calls[] = {
211     [KMPC_API_BAD] = {"__INVALID_KMPC_API_NAME__", -1, -1, -1},
212     [KMPC_API_FORK_CALL] = {"__kmpc_fork_call", 0, DT_VOID_NONE, 0},
213     [KMPC_API_BARRIER] = {"__kmpc_barrier", 0, DT_VOID_NONE, 0},
214     [KMPC_API_CANCEL_BARRIER] = {"__kmpc_cancel_barrier", 0, DT_VOID_NONE, 0},
215     [KMPC_API_COPYPRIVATE] = {"__kmpc_copyprivate", 0, DT_VOID_NONE, 0},
216     [KMPC_API_CRITICAL] = {"__kmpc_critical", 0, DT_VOID_NONE, 0},
217     [KMPC_API_END_CRITICAL] = {"__kmpc_end_critical", 0, DT_VOID_NONE, 0},
218     [KMPC_API_SINGLE] = {"__kmpc_single", IL_DFRIR, DT_INT, 0},
219     [KMPC_API_END_SINGLE] = {"__kmpc_end_single", 0, DT_VOID_NONE, 0},
220     [KMPC_API_MASTER] = {"__kmpc_master", IL_DFRIR, DT_INT, 0},
221     [KMPC_API_END_MASTER] = {"__kmpc_end_master", 0, DT_VOID_NONE, 0},
222     [KMPC_API_FLUSH] = {"__kmpc_flush", 0, DT_VOID_NONE, 0},
223     [KMPC_API_ORDERED] = {"__kmpc_ordered", 0, DT_VOID_NONE, 0},
224     [KMPC_API_END_ORDERED] = {"__kmpc_end_ordered", 0, DT_VOID_NONE, 0},
225     [KMPC_API_FOR_STATIC_INIT] = {"__kmpc_for_static_init_%d%s", 0,
226                                   DT_VOID_NONE, KMPC_FLAG_STR_FMT},
227     [KMPC_API_FOR_STATIC_FINI] = {"__kmpc_for_static_fini", 0, DT_VOID_NONE, 0},
228     [KMPC_API_DISPATCH_INIT] = {"__kmpc_dispatch_init_%d%s", 0, DT_VOID_NONE,
229                                 KMPC_FLAG_STR_FMT}, /*4,4u,8,8u are possible*/
230     [KMPC_API_DISPATCH_NEXT] = {"__kmpc_dispatch_next_%d%s", IL_DFRIR, DT_INT,
231                                 KMPC_FLAG_STR_FMT}, /*4,4u,8,8u are possible*/
232     [KMPC_API_DISPATCH_FINI] = {"__kmpc_dispatch_fini_%d%s", 0, DT_VOID_NONE,
233                                 KMPC_FLAG_STR_FMT}, /*4,4u,8,8u are possible*/
234     [KMPC_API_GLOBAL_THREAD_NUM] = {"__kmpc_global_thread_num", IL_DFRIR,
235                                     DT_INT, 0},
236     [KMPC_API_GLOBAL_NUM_THREADS] = {"__kmpc_global_num_threads", IL_DFRIR,
237                                      DT_INT, 0},
238     [KMPC_API_BOUND_THREAD_NUM] = {"__kmpc_bound_thread_num", IL_DFRIR, DT_INT,
239                                    0},
240     [KMPC_API_BOUND_NUM_THREADS] = {"__kmpc_bound_num_threads", IL_DFRIR,
241                                     DT_INT, 0},
242     [KMPC_API_PUSH_NUM_THREADS] = {"__kmpc_push_num_threads", 0, DT_VOID_NONE,
243                                    0},
244     [KMPC_API_SERIALIZED_PARALLEL] = {"__kmpc_serialized_parallel", 0,
245                                       DT_VOID_NONE, 0},
246     [KMPC_API_END_SERIALIZED_PARALLEL] = {"__kmpc_end_serialized_parallel", 0,
247                                           DT_VOID_NONE, 0},
248     [KMPC_API_THREADPRIVATE_CACHED] = {"__kmpc_threadprivate_cached", IL_DFRAR,
249                                        DT_CPTR, 0},
250     [KMPC_API_THREADPRIVATE_REGISTER_VEC] =
251         {"__kmpc_threadprivate_register_vec", 0, DT_VOID_NONE, 0},
252     [KMPC_API_THREADPRIVATE_REGISTER] = {"__kmpc_threadprivate_register", 0,
253                                          DT_VOID_NONE, 0},
254     [KMPC_API_TASK] = {"__kmpc_omp_task", 0, DT_VOID_NONE, 0},
255     [KMPC_API_TASK_BEGIN_IF0] = {"__kmpc_omp_task_begin_if0", 0, DT_VOID_NONE,
256                                  0},
257     [KMPC_API_TASK_COMPLETE_IF0] = {"__kmpc_omp_task_complete_if0", 0,
258                                     DT_VOID_NONE, 0},
259     [KMPC_API_TASK_ALLOC] = {"__kmpc_omp_task_alloc", IL_DFRAR, DT_CPTR, 0},
260     [KMPC_API_TASK_WAIT] = {"__kmpc_omp_taskwait", IL_DFRIR, DT_INT, 0},
261     [KMPC_API_TASK_YIELD] = {"__kmpc_omp_taskyield", IL_DFRIR, DT_INT, 0},
262     [KMPC_API_CANCEL] = {"__kmpc_cancel", IL_DFRIR, DT_INT, 0},
263     [KMPC_API_CANCELLATIONPOINT] = {"__kmpc_cancellationpoint", IL_DFRIR,
264                                     DT_INT, 0},
265     [KMPC_API_TASKGROUP] = {"__kmpc_taskgroup", 0, DT_VOID_NONE, 0},
266     [KMPC_API_END_TASKGROUP] = {"__kmpc_end_taskgroup", 0, DT_VOID_NONE, 0},
267     [KMPC_API_TASK_WITH_DEPS] = {"__kmpc_task_with_deps", IL_DFRIR, DT_INT, 0},
268     [KMPC_API_WAIT_DEPS] = {"__kmpc_wait_deps", 0, DT_VOID_NONE, 0},
269     [KMPC_API_TASKLOOP] = {"__kmpc_taskloop", 0, DT_VOID_NONE, 0},
270     [KMPC_API_THREADPRIVATE] = {"__kmpc_threadprivate", IL_DFRAR, DT_CPTR, 0},
271     [KMPC_API_FORK_TEAMS] = {"__kmpc_fork_teams", 0, DT_VOID_NONE, 0},
272     [KMPC_API_PUSH_NUM_TEAMS] = {"__kmpc_push_num_teams", 0, DT_VOID_NONE, 0},
273     [KMPC_API_DIST_FOR_STATIC_INIT] = {"__kmpc_dist_for_static_init_%d%s", 0,
274                                        DT_VOID_NONE, KMPC_FLAG_STR_FMT},
275     [KMPC_API_DIST_DISPATCH_INIT] =
276         {"__kmpc_dist_dispatch_init_%d%s", 0, DT_VOID_NONE,
277          KMPC_FLAG_STR_FMT}, /*4,4u,8,8u are possible*/
278     [KMPC_API_PUSH_PROC_BIND] = {"__kmpc_push_proc_bind", 0, DT_VOID_NONE, 0},
279     [KMPC_API_ATOMIC_RD] = {"__kmpc_atomic_%s%d_rd", 0, DT_VOID_NONE,
280                             KMPC_FLAG_STR_FMT},
281     [KMPC_API_ATOMIC_WR] = {"__kmpc_atomic_%s%d_wr", 0, DT_VOID_NONE,
282                             KMPC_FLAG_STR_FMT},
283     /* OpenMP Accelerator RT (libomptarget-nvptx) - non standard - */
284     [KMPC_API_FOR_STATIC_INIT_SIMPLE_SPMD] =
285         {"__kmpc_for_static_init_%d%s_simple_spmd", 0, DT_VOID_NONE,
286          KMPC_FLAG_STR_FMT},
287     [KMPC_API_SPMD_KERNEL_INIT] = {"__kmpc_spmd_kernel_init", 0, DT_VOID_NONE,
288                                    0},
289     [KMPC_API_PUSH_TARGET_TRIPCOUNT] = {"__kmpc_push_target_tripcount", 0,
290                                         DT_VOID_NONE, 0},
291     [KMPC_API_KERNEL_INIT_PARAMS] = {"__kmpc_kernel_init_params", 0,
292                                      DT_VOID_NONE, 0},
293     [KMPC_API_SHUFFLE_I32] = {"__kmpc_shuffle_int32", 0, DT_INT, 0},
294     [KMPC_API_SHUFFLE_I64] = {"__kmpc_shuffle_int64", 0, DT_INT8, 0},
295     [KMPC_API_NVPTX_PARALLEL_REDUCE_NOWAIT_SIMPLE_SPMD] =
296         {"__kmpc_nvptx_parallel_reduce_nowait_simple_spmd", 0, DT_INT, 0},
297     [KMPC_API_NVPTX_END_REDUCE_NOWAIT] = {"__kmpc_nvptx_end_reduce_nowait", 0,
298                                           DT_VOID_NONE, 0},
299 };
300 #endif
301 
302 #define KMPC_NAME(_api) kmpc_api_calls[KMPC_CHK(_api)].name
303 #define KMPC_RET_DTYPE(_api) kmpc_api_calls[KMPC_CHK(_api)].ret_dtype
304 
305 #define KMPC_RET_ILIOPC(_api) kmpc_api_calls[KMPC_CHK(_api)].ret_iliopc
306 #define KMPC_FLAGS(_api) kmpc_api_calls[KMPC_CHK(_api)].flags
307 
308 #define KMPC_CHK(_api) \
309   (((_api) > KMPC_API_BAD && (_api) < KMPC_API_N_ENTRIES) ? _api : KMPC_API_BAD)
310 
311 /*
312  * void __kmpc_fork_call ( ident_t loc, kmp_int32 argc, kmpc_micro
313  * microtask,...)
314  *                         DT_ADDR      INT             DT_ADDR
315  *
316  *
317  *
318  * all outlined function are in this form:
319  *
320  * void outlined_func_uniqname(INT* gbl_tid, INT* bnd_tid, struct* );
321  *
322  * gbl_tid: global thread identity of thread
323  * bnd_tid: local id of thread
324  * struct*: pointers to shared variables - actual struct size depends on size of
325  * sh vars.
326  *
327  */
328 #include "mwd.h"
329 static void
dump_loop_args(const loop_args_t * args)330 dump_loop_args(const loop_args_t *args)
331 {
332   FILE *fp = gbl.dbgfil ? gbl.dbgfil : stdout;
333   bool isdevice = false;
334   fprintf(fp, "********** KMPC Loop Arguments (line:%d) **********\n",
335           gbl.lineno);
336   fprintf(fp, "**** Target: %s ****\n", isdevice ? "Device" : "Host");
337   fprintf(fp, "Lower Bound: %d (%s) (%s)\n", args->lower, SYMNAME(args->lower),
338           stb.tynames[DTY(DTYPEG(args->lower))]);
339   fprintf(fp, "Upper Bound: %d (%s) (%s)\n", args->upper, SYMNAME(args->upper),
340           stb.tynames[DTY(DTYPEG(args->upper))]);
341   fprintf(fp, "Stride:      %d (%s) (%s)\n", args->stride,
342           SYMNAME(args->stride), stb.tynames[DTY(DTYPEG(args->stride))]);
343   fprintf(fp, "Chunk:       %d (%s) (%s)\n", args->chunk, SYMNAME(args->chunk),
344           stb.tynames[DTY(DTYPEG(args->chunk))]);
345   fprintf(fp, "dtype:       %d (%s) \n", args->dtype,
346           stb.tynames[DTY(args->dtype)]);
347   fprintf(fp, "**********\n\n");
348 }
349 
350 /* Return ili (icon/kcon, or a loaded value) for use with mk_kmpc_api_call
351  * arguments.
352  */
353 static int
ld_sptr(SPTR sptr)354 ld_sptr(SPTR sptr)
355 {
356   ISZ_T sz = size_of(DTYPEG(sptr));
357 
358   if (STYPEG(sptr) == ST_CONST) {
359     if (sz == 8)
360       return ad_kcon(CONVAL1G(sptr), CONVAL2G(sptr));
361     return ad_icon(CONVAL2G(sptr));
362   } else {
363     int nme = addnme(NT_VAR, sptr, 0, 0);
364     int ili = mk_address(sptr);
365     if (ILI_OPC(ili) == IL_LDA)
366       nme = ILI_OPND(ili, 2);
367     if (sz == 8)
368       return ad3ili(IL_LDKR, ili, nme, MSZ_I8);
369     return ad3ili(IL_LD, ili, nme, mem_size(DTY(DTYPEG(sptr))));
370   }
371 
372   assert(0, "Invalid sptr for mk_kmpc_api_call arguments", sptr, ERR_Fatal);
373 }
374 
375 static int
gen_null_arg()376 gen_null_arg()
377 {
378   int con, ili;
379   INT tmp[2];
380 
381   tmp[0] = 0;
382   tmp[1] = 0;
383   con = getcon(tmp, DT_INT);
384   ili = ad1ili(IL_ACON, con);
385   return ili;
386 }
387 
388 DTYPE
ll_make_kmpc_struct_type(int count,char * name,KMPC_ST_TYPE * meminfo,ISZ_T sz)389 ll_make_kmpc_struct_type(int count, char *name, KMPC_ST_TYPE *meminfo, ISZ_T sz)
390 {
391   DTYPE dtype;
392   int i;
393   SPTR mem, tag, prev_mem, first_mem;
394   char sname[MXIDLEN];
395 
396   tag = SPTR_NULL;
397   dtype = cg_get_type(6, TY_STRUCT, NOSYM);
398   if (name) {
399     sprintf(sname, "struct%s", name);
400     tag = getsymbol(sname);
401     DTYPEP(tag, dtype);
402   }
403 
404   prev_mem = first_mem = SPTR_NULL;
405   mem = NOSYM;
406   for (i = 0; i < count; ++i) {
407     mem = addnewsym(meminfo[i].name);
408     STYPEP(mem, ST_MEMBER);
409     PAROFFSETP(mem, meminfo[i].psptr);
410     DTYPEP(mem, meminfo[i].dtype);
411     if (prev_mem > 0)
412       SYMLKP(prev_mem, mem);
413     SYMLKP(mem, NOSYM);
414     PSMEMP(mem, mem);
415     VARIANTP(mem, prev_mem);
416     CCSYMP(mem, 1);
417     ADDRESSP(mem, sz);
418     SCP(mem, SC_NONE);
419     if (first_mem == 0)
420       first_mem = mem;
421     sz += size_of(meminfo[i].dtype);
422     prev_mem = mem;
423   }
424 
425   DTySetAlgTy(dtype, first_mem, sz, tag, 0, 0);
426   return dtype;
427 }
428 
429 /*
430  * struct ident { i32, i32, i32, i32, char* }
431  */
432 static DTYPE
ll_make_kmpc_ident_type(void)433 ll_make_kmpc_ident_type(void)
434 {
435   KMPC_ST_TYPE meminfo[] = {{"reserved_1", DT_INT, 0, 0},
436                             {"flags", DT_INT, 0, 0},
437                             {"reserved_2", DT_INT, 0, 0},
438                             {"reserved_3", DT_INT, 0, 0},
439                             {"psource", DT_CPTR, 0, 0}};
440 
441   if (kmpc_ident_dtype == DT_NONE)
442     kmpc_ident_dtype =
443         ll_make_kmpc_struct_type(5, "_pgi_kmpc_ident_t", meminfo, 0);
444   return kmpc_ident_dtype;
445 }
446 
447 /* Name 'nm' should be formatted and passed in: use build_kmpc_api_name() */
448 static SPTR
ll_make_kmpc_proto(const char * nm,int kmpc_api,int argc,DTYPE * args)449 ll_make_kmpc_proto(const char *nm, int kmpc_api, int argc, DTYPE *args)
450 {
451   DTYPE ret_dtype;
452   /* args contains a list of dtype.  The actual sptr of args will be create in
453      ll_make_ftn_outlined_params.
454    */
455   const SPTR func_sptr = getsymbol(nm);
456 
457   if (!nm)
458     nm = KMPC_NAME(kmpc_api);
459 
460   ret_dtype = KMPC_RET_DTYPE(kmpc_api);
461 
462   DTYPEP(func_sptr, ret_dtype);
463   SCP(func_sptr, SC_EXTERN);
464   STYPEP(func_sptr, ST_PROC);
465   CCSYMP(func_sptr,
466          1); /* currently we make all CCSYM func varargs in Fortran. */
467   CFUNCP(func_sptr, 1);
468   ll_make_ftn_outlined_params(func_sptr, argc, args);
469   ll_process_routine_parameters(func_sptr);
470 
471   /* Update ABI (special case) */
472   if (kmpc_api == KMPC_API_FORK_CALL) {
473     LL_ABI_Info *abi = ll_proto_get_abi(nm);
474     abi->is_varargs = true;
475   }
476   /* Update ABI (special case) */
477   if (kmpc_api == KMPC_API_FORK_TEAMS) {
478     LL_ABI_Info *abi = ll_proto_get_abi(nm);
479     abi->is_varargs = true;
480   }
481   return func_sptr;
482 }
483 
484 /* Argument instance representing location information
485  * This creates a struct ptr instance (for use as an argument).
486  * src/kmp.h:
487  * ident_t = {
488  *     i32 reserved;
489  *     i32 flags;
490  *     i32 reserved;
491  *     i32 reserved;
492  *     char *psource -- funcname;lineno;lineno
493  */
494 static int
make_kmpc_ident_arg(void)495 make_kmpc_ident_arg(void)
496 {
497   int i, ilix, nme, offset;
498   static int n;
499   const DTYPE dtype = ll_make_kmpc_ident_type();
500   const SPTR ident = getnewccsym('I', ++n, ST_STRUCT);
501 
502   SCP(ident, SC_LOCAL);
503   REFP(ident, 1); /* don't want it to go in sym_is_refd */
504   DTYPEP(ident, dtype);
505   nme = addnme(NT_VAR, ident, 0, 0);
506 
507   /* Set the fields to to 0 for now */
508   offset = 0;
509   for (i = DTyAlgTyMember(dtype); i > NOSYM; i = SYMLKG(i)) {
510     const int addr = ad_acon(ident, offset);
511     ilix = ad4ili(IL_ST, ad_icon(0), addr, addnme(NT_MEM, PSMEMG(i), nme, 0),
512                   mem_size(DTY(DTYPEG(i))));
513     offset += size_of(DTYPEG(i));
514     chk_block(ilix);
515   }
516 
517   return ad_acon(ident, 0);
518 }
519 
520 /* The return value is allocated and maintained locally, please do not call
521  * 'free' on this, bad things will probably happen.
522  *
523  * Caller is responsible for calling va_end()
524  *
525  * This function will maintain one allocation for unique function name.
526  */
527 static const char *
build_kmpc_api_name(int kmpc_api,va_list va)528 build_kmpc_api_name(int kmpc_api, va_list va)
529 {
530   static hashmap_t names; /* Maintained in this routine */
531 
532   if (!names)
533     names = hashmap_alloc(hash_functions_strings);
534 
535   if (KMPC_FLAGS(kmpc_api) & KMPC_FLAG_STR_FMT) {
536     char *nm, *res;
537 
538     /* Construct the name */
539     vasprintf(&nm, KMPC_NAME(kmpc_api), va);
540 
541     /* If the name has already been allocated, use that to save memory */
542     if (hashmap_lookup(names, (hash_key_t)nm, (hash_data_t *)&res)) {
543       free(nm);
544       return res;
545     } else {
546       hashmap_insert(names, (hash_key_t)nm, (hash_data_t)nm);
547       return nm;
548     }
549   } else
550     return KMPC_NAME(kmpc_api);
551 
552   assert(false, "build_kmpc_api_name: Incorrect return value", 0, ERR_Fatal);
553 }
554 
555 /* Returns the function prototype sptr.
556  * 'reg_opc'   ILI op code for return value, e.g., IL_DFRIR or 0 if void
557  * 'ret_dtype' dtype representing return value
558  */
559 static int
mk_kmpc_api_call(int kmpc_api,int n_args,DTYPE * arg_dtypes,int * arg_ilis,...)560 mk_kmpc_api_call(int kmpc_api, int n_args, DTYPE *arg_dtypes, int *arg_ilis,
561                  ...)
562 {
563   int i, r, ilix, altilix, gargs;
564   SPTR fn_sptr;
565   int *garg_ilis = ALLOCA(int, n_args);
566   const char *nm;
567   const ILI_OP ret_opc = KMPC_RET_ILIOPC(kmpc_api);
568   const DTYPE ret_dtype = KMPC_RET_DTYPE(kmpc_api);
569   va_list va;
570 
571   /* Some calls will make use of this (see: KMPC_FLAG_STR_FMT) */
572   va_start(va, arg_ilis);
573 
574   /* Create the prototype for the API call */
575   nm = build_kmpc_api_name(kmpc_api, va);
576   fn_sptr = ll_make_kmpc_proto(nm, kmpc_api, n_args, arg_dtypes);
577   sym_is_refd(fn_sptr);
578 
579   /* Update ACC routine tables and then create the JSR */
580   update_acc_with_fn(fn_sptr);
581   ilix = ll_ad_outlined_func2(ret_opc, IL_JSR, fn_sptr, n_args, arg_ilis);
582 
583   /* Create the GJSR */
584   for (i = n_args - 1; i >= 0; --i) /* Reverse the order */
585     garg_ilis[i] = arg_ilis[n_args - 1 - i];
586   gargs = ll_make_outlined_garg(n_args, garg_ilis, arg_dtypes);
587   altilix = ad3ili(IL_GJSR, fn_sptr, gargs, 0);
588 
589   /* Add gjsr as an alt to the jsr */
590   if (ret_opc)
591     ILI_ALT(ILI_OPND(ilix, 1)) = altilix;
592   else
593     ILI_ALT(ilix) = altilix;
594 
595   va_end(va);
596   return ilix;
597 }
598 
599 /* Generic routine that returns a jsr to __kmpc_<api_name>
600  * This is for all kmpc function calls that look like:
601  * int api_func(ident *)
602  */
603 static int
ll_make_kmpc_generic_ptr(int kmpc_api)604 ll_make_kmpc_generic_ptr(int kmpc_api)
605 {
606   int args[1];
607   DTYPE arg_types[] = {DT_CPTR};
608   args[0] = gen_null_arg();
609   return mk_kmpc_api_call(kmpc_api, 1, arg_types, args);
610 }
611 
612 #define KMPC_GENERIC_P(_fn, _api)          \
613   int _fn(void)                            \
614   {                                        \
615     return ll_make_kmpc_generic_ptr(_api); \
616   }
KMPC_GENERIC_P(ll_make_kmpc_global_thread_num,KMPC_API_GLOBAL_THREAD_NUM)617 KMPC_GENERIC_P(ll_make_kmpc_global_thread_num, KMPC_API_GLOBAL_THREAD_NUM)
618 KMPC_GENERIC_P(ll_make_kmpc_global_num_threads, KMPC_API_GLOBAL_NUM_THREADS)
619 KMPC_GENERIC_P(ll_make_kmpc_bound_thread_num, KMPC_API_BOUND_THREAD_NUM)
620 KMPC_GENERIC_P(ll_make_kmpc_bound_num_threads, KMPC_API_BOUND_NUM_THREADS)
621 
622 /* Generic routine that returns a jsr to __kmpc_<api_name>
623  * This is for all kmpc function calls that look like
624  * void api_func(ident *, global_tid).
625  *
626  * Many kmpc routines follow this prototype so we generalize our code here to
627  * generate this.
628  */
629 static int
630 ll_make_kmpc_generic_ptr_int(int kmpc_api)
631 {
632   int args[2];
633   DTYPE arg_types[2] = {DT_CPTR, DT_INT};
634   args[1] = gen_null_arg();
635 #ifdef OMP_OFFLOAD_LLVM
636   if (gbl.ompaccel_intarget)
637     args[0] = ompaccel_nvvm_get_gbl_tid();
638   else
639 #endif
640     args[0] = ll_get_gtid_val_ili();
641   return mk_kmpc_api_call(kmpc_api, 2, arg_types, args);
642 }
643 
644 #define KMPC_GENERIC_P_I(_fn, _api)            \
645   int _fn(void)                                \
646   {                                            \
647     return ll_make_kmpc_generic_ptr_int(_api); \
648   }
KMPC_GENERIC_P_I(ll_make_kmpc_barrier,KMPC_API_BARRIER)649 KMPC_GENERIC_P_I(ll_make_kmpc_barrier, KMPC_API_BARRIER)
650 KMPC_GENERIC_P_I(ll_make_kmpc_cancel_barrier, KMPC_API_CANCEL_BARRIER)
651 KMPC_GENERIC_P_I(ll_make_kmpc_master, KMPC_API_MASTER)
652 KMPC_GENERIC_P_I(ll_make_kmpc_end_master, KMPC_API_END_MASTER)
653 KMPC_GENERIC_P_I(ll_make_kmpc_single, KMPC_API_SINGLE)
654 KMPC_GENERIC_P_I(ll_make_kmpc_end_single, KMPC_API_END_SINGLE)
655 KMPC_GENERIC_P_I(ll_make_kmpc_ordered, KMPC_API_ORDERED)
656 KMPC_GENERIC_P_I(ll_make_kmpc_end_ordered, KMPC_API_END_ORDERED)
657 KMPC_GENERIC_P_I(ll_make_kmpc_for_static_fini, KMPC_API_FOR_STATIC_FINI)
658 KMPC_GENERIC_P_I(ll_make_kmpc_task_wait, KMPC_API_TASK_WAIT)
659 KMPC_GENERIC_P_I(ll_make_kmpc_taskgroup, KMPC_API_TASKGROUP)
660 KMPC_GENERIC_P_I(ll_make_kmpc_end_taskgroup, KMPC_API_END_TASKGROUP)
661 
662 /* Generic routine that returns a jsr to __kmpc_<api_name>
663  * This is for all kmpc function calls that look like
664  * void api_func(ident *, global_tid, kmp_int32).
665  *
666  * Many kmpc routines follow this prototype so we generalize our code here to
667  * generate this.
668  */
669 static int
670 ll_make_kmpc_generic_ptr_2int(int kmpc_api, int argili)
671 {
672   int args[3];
673   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_INT};
674   args[2] = gen_null_arg();
675 #ifdef OMP_OFFLOAD_LLVM
676   if (flg.omptarget)
677     args[1] = ompaccel_nvvm_get_gbl_tid();
678   else
679 #endif
680     args[1] = ll_get_gtid_val_ili();
681   args[0] = argili;
682   return mk_kmpc_api_call(kmpc_api, 3, arg_types, args);
683 }
684 
685 #define KMPC_GENERIC_P_2I(_fn, _api, argili)            \
686   int _fn(int argili)                                   \
687   {                                                     \
688     return ll_make_kmpc_generic_ptr_2int(_api, argili); \
689   }
KMPC_GENERIC_P_2I(ll_make_kmpc_push_proc_bind,KMPC_API_PUSH_PROC_BIND,argili)690 KMPC_GENERIC_P_2I(ll_make_kmpc_push_proc_bind, KMPC_API_PUSH_PROC_BIND, argili)
691 KMPC_GENERIC_P_2I(ll_make_kmpc_push_num_threads, KMPC_API_PUSH_NUM_THREADS,
692                   argili)
693 KMPC_GENERIC_P_2I(ll_make_kmpc_cancel, KMPC_API_CANCEL, argili)
694 KMPC_GENERIC_P_2I(ll_make_kmpc_cancellationpoint, KMPC_API_CANCELLATIONPOINT,
695                   argili)
696 
697 /* arglist is 1 containing the uplevel pointer */
698 int
699 ll_make_kmpc_fork_call(SPTR sptr, int argc, int *arglist, RegionType rt,
700                        int ngangs_ili)
701 {
702   int argili, args[5];
703   DTYPE arg_types[] = {DT_CPTR, DT_INT, DT_CPTR, DT_NONE, DT_NONE};
704   arg_types[3] = DT_CPTR;
705 
706   int call_pgi_kmpc_fork_call = (rt == OPENACC);
707   call_pgi_kmpc_fork_call = 0;
708 
709   if (call_pgi_kmpc_fork_call) {
710     // In case we call pgi_kmpc_fork_call, we must also pass in the
711     // number of gangs. Because the function takes varargs, the num_gangs
712     // argument needs to appear before end of argument list - thus shift
713     // arguments over to make room for num_gangs argument.
714     arg_types[4] = arg_types[3];
715     arg_types[3] = arg_types[2];
716     arg_types[2] = DT_INT; // num_gangs is integer argument
717     args[4] = gen_null_arg();
718     args[3] = ad_icon(argc);
719     args[2] = ngangs_ili;
720   } else {
721     args[3] = gen_null_arg(); /* ident */
722     args[2] = ad_icon(argc);
723   }
724 
725   args[1] = ad1ili(IL_ACON, get_acon(sptr, 0));
726   args[0] = *arglist;
727     return mk_kmpc_api_call(KMPC_API_FORK_CALL, 4, arg_types, args);
728 }
729 
730 /* arglist is 1 containing the uplevel pointer */
731 int
ll_make_kmpc_fork_teams(SPTR sptr,int argc,int * arglist)732 ll_make_kmpc_fork_teams(SPTR sptr, int argc, int *arglist)
733 {
734   int argili, args[4];
735   DTYPE arg_types[] = {DT_CPTR, DT_INT, DT_CPTR, DT_NONE};
736   arg_types[3] = DT_CPTR;
737   args[3] = gen_null_arg(); /* ident */
738   args[2] = ad_icon(argc);
739   args[1] = ad1ili(IL_ACON, get_acon(sptr, 0));
740   args[0] = *arglist;
741   return mk_kmpc_api_call(KMPC_API_FORK_TEAMS, 4, arg_types, args);
742 }
743 
744 int
ll_make_kmpc_flush(void)745 ll_make_kmpc_flush(void)
746 {
747   int args[1];
748   DTYPE arg_types[1] = {DT_CPTR};
749   args[0] = gen_null_arg();
750   return mk_kmpc_api_call(KMPC_API_FLUSH, 1, arg_types, args);
751 }
752 
753 int
ll_make_kmpc_copyprivate(SPTR array_sptr,int single_ili,int copyfunc_acon)754 ll_make_kmpc_copyprivate(SPTR array_sptr, int single_ili, int copyfunc_acon)
755 {
756   int args[6];
757   DTYPE arg_types[6] = {DT_CPTR, DT_INT, (DTYPE)-1, DT_CPTR, DT_CPTR, DT_INT};
758   args[5] = gen_null_arg();        /* ident */
759   args[4] = ll_get_gtid_val_ili(); /* tid   */
760   if (TARGET_PTRSIZE == 8) {
761     /* cpy_size (ignore) */
762     arg_types[2] = DT_INT8;
763     args[3] = ad_kconi(0);
764   } else {
765     /* cpy_size (ignore) */
766     arg_types[2] = DT_INT;
767     args[3] = ad_icon(0);
768   }
769   args[2] = ad_acon(array_sptr, 0); /* cpy_data          */
770   args[1] = copyfunc_acon;          /* cpy_func          */
771   args[0] = single_ili;             /* didit             */
772   return mk_kmpc_api_call(KMPC_API_COPYPRIVATE, 6, arg_types, args);
773 }
774 
775 int
ll_make_kmpc_critical(SPTR sem)776 ll_make_kmpc_critical(SPTR sem)
777 {
778   int args[3];
779   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_CPTR};
780   args[2] = gen_null_arg();        /* ident */
781   args[1] = ll_get_gtid_val_ili(); /* tid   */
782   if (sem)
783     args[0] = ad_acon(sem, 0); /* critical_name:= i32 [8] */
784   else
785     args[0] = ad_aconi(0); /* critical_name:= i32 [8] */
786   return mk_kmpc_api_call(KMPC_API_CRITICAL, 3, arg_types, args);
787 }
788 
789 int
ll_make_kmpc_end_critical(SPTR sem)790 ll_make_kmpc_end_critical(SPTR sem)
791 {
792   int args[3];
793   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_CPTR};
794   args[2] = gen_null_arg();        /* ident */
795   args[1] = ll_get_gtid_val_ili(); /* tid   */
796   if (sem)
797     args[0] = ad_acon(sem, 0); /* critical_name:= i32 [8] */
798   else
799     args[0] = ad_aconi(0); /* critical_name:= i32 [8] */
800   return mk_kmpc_api_call(KMPC_API_END_CRITICAL, 3, arg_types, args);
801 }
802 
803 /* Return a result or JSR ili to __kmpc_push_num_teams() */
804 int
ll_make_kmpc_push_num_teams(int nteams_ili,int thread_limit_ili)805 ll_make_kmpc_push_num_teams(int nteams_ili, int thread_limit_ili)
806 {
807   int args[4];
808   DTYPE arg_types[4] = {DT_CPTR, DT_INT, DT_INT, DT_INT};
809   args[3] = gen_null_arg();        /* ident */
810   args[2] = ll_get_gtid_val_ili(); /* tid   */
811   args[1] = nteams_ili;            /* num_threads := i32 [8] */
812   args[0] = thread_limit_ili;      /* thread_limit := i32 [8] */
813   return mk_kmpc_api_call(KMPC_API_PUSH_NUM_TEAMS, 4, arg_types, args);
814 }
815 
816 /* Return a result or JSR ili to __kmpc_serialized_parallel() */
817 int
ll_make_kmpc_serialized_parallel(void)818 ll_make_kmpc_serialized_parallel(void)
819 {
820   int args[2];
821   DTYPE arg_types[2] = {DT_CPTR, DT_INT};
822   args[1] = gen_null_arg();        /* ident */
823   args[0] = ll_get_gtid_val_ili(); /* tid   */
824   return mk_kmpc_api_call(KMPC_API_SERIALIZED_PARALLEL, 2, arg_types, args);
825 }
826 
827 /* Return a result or JSR ili to __kmpc_end_serialized_parallel() */
828 int
ll_make_kmpc_end_serialized_parallel(void)829 ll_make_kmpc_end_serialized_parallel(void)
830 {
831   int args[2];
832   DTYPE arg_types[2] = {DT_CPTR, DT_INT};
833   args[1] = gen_null_arg();        /* ident */
834   args[0] = ll_get_gtid_val_ili(); /* tid   */
835   return mk_kmpc_api_call(KMPC_API_END_SERIALIZED_PARALLEL, 2, arg_types, args);
836 }
837 
838 /* Return a result or JSR ili to __kmpc_threadprivate_cached() */
839 int
ll_make_kmpc_threadprivate_cached(int data_ili,int size_ili,int cache_ili)840 ll_make_kmpc_threadprivate_cached(int data_ili, int size_ili, int cache_ili)
841 {
842   int args[5];
843   DTYPE arg_types[5] = {DT_CPTR, DT_INT, DT_CPTR, DT_INT8, DT_CPTR};
844   /*size_t*/
845   args[4] = gen_null_arg();        /* ident     */
846   args[3] = ll_get_gtid_val_ili(); /* tid       */
847   args[2] = data_ili;              /* data      */
848 
849   /* size */
850   args[1] = (IL_RES(ILI_OPC(size_ili)) != ILIA_KR) ? ad1ili(IL_IKMV, size_ili)
851                                                    : size_ili;
852   args[0] = cache_ili; /* cache     */
853   return mk_kmpc_api_call(KMPC_API_THREADPRIVATE_CACHED, 5, arg_types, args);
854 }
855 
856 /* Return a result or JSR ili to __kmpc_threadprivate_register() */
857 int
ll_make_kmpc_threadprivate_register(int data_ili,int ctor_ili,int cctor_ili,int dtor_ili)858 ll_make_kmpc_threadprivate_register(int data_ili, int ctor_ili, int cctor_ili,
859                                     int dtor_ili)
860 {
861   int args[5];
862   DTYPE arg_types[5] = {DT_CPTR, DT_CPTR, DT_CPTR, DT_CPTR, DT_CPTR};
863   args[4] = gen_null_arg(); /* ident     */
864   args[3] = data_ili;       /* data      */
865   args[2] = ctor_ili;       /* ctor   funcptr */
866   args[1] = cctor_ili;      /* cctor funcptr  */
867   args[0] = dtor_ili;       /* dtor  funcptr  */
868   return mk_kmpc_api_call(KMPC_API_THREADPRIVATE_REGISTER, 5, arg_types, args);
869 }
870 /* Return a result or JSR ili to __kmpc_threadprivate_register_vec() */
871 int
ll_make_kmpc_threadprivate_register_vec(int data_ili,int ctor_ili,int cctor_ili,int dtor_ili,int size_ili)872 ll_make_kmpc_threadprivate_register_vec(int data_ili, int ctor_ili,
873                                         int cctor_ili, int dtor_ili,
874                                         int size_ili)
875 {
876   int args[6];
877   DTYPE arg_types[6] = {DT_CPTR, DT_CPTR, DT_CPTR, DT_CPTR, DT_CPTR, DT_INT8};
878   /* size_t */
879   args[5] = gen_null_arg(); /* ident          */
880   args[4] = data_ili;       /* data           */
881   args[3] = ctor_ili;       /* ctor func_ptr  */
882   args[2] = cctor_ili;      /* cctor func_ptr */
883   args[1] = dtor_ili;       /* dtor  func_ptr */
884   args[0] = size_ili;       /* vec size       */
885   return mk_kmpc_api_call(KMPC_API_THREADPRIVATE_REGISTER_VEC, 6, arg_types,
886                           args);
887 }
888 
889 /* Returns the KMPC flags set for tasking flags given our representation
890  * as presented in the MP_TASK_XXX flags (see mp.h).
891  */
892 int
mp_to_kmpc_tasking_flags(const int mp)893 mp_to_kmpc_tasking_flags(const int mp)
894 {
895   int kmpc = (mp & MP_TASK_UNTIED) ? KMPC_TASK_UNTIED : KMPC_TASK_TIED;
896   if (mp & MP_TASK_FINAL)
897     kmpc |= KMPC_TASK_FINAL;
898   if (mp & MP_TASK_PRIORITY)
899     kmpc |= KMPC_TASK_PRIORITY;
900   return kmpc;
901 }
902 
903 SPTR
ll_make_kmpc_task_arg(SPTR base,SPTR sptr,SPTR scope_sptr,SPTR flags_sptr,int uplevel_ili)904 ll_make_kmpc_task_arg(SPTR base, SPTR sptr, SPTR scope_sptr, SPTR flags_sptr,
905                       int uplevel_ili)
906 {
907   LLTask *task;
908   LLUplevel *up;
909   int offset, size, shared_size, i, nme, call_ili, ilix, args[6];
910   SPTR uplevel_sym;
911   DTYPE arg_types[6] = {DT_CPTR, DT_INT, DT_INT, DT_INT, DT_INT, DT_CPTR};
912   DTYPE dtype;
913 
914   /*
915    * __kmp_omp_task_alloc will set the value of ptr_to_offset2.
916    * other-data includes private data.
917    *
918    * task_alloc_sptr =>
919    *   offset  [ offset0        | offset1    | offset2  | ... ]
920    *   info    [ ptr_to_offset2 | other-data | first_share_var_addr | ... ]
921    */
922 
923   /* Calculate size of all privates */
924   task = llmp_get_task(scope_sptr);
925   size = llmp_task_get_size(task);
926   uplevel_sym = ll_get_uplevel_sym();
927   if (uplevel_sym != SPTR_NULL) {
928     dtype = DTYPEG(uplevel_sym);
929     shared_size = size_of(dtype);
930   } else {
931     shared_size = getTaskSharedSize(scope_sptr);
932   }
933 
934   /* Create the api call */
935   args[5] = gen_null_arg();        /* ident             */
936   args[4] = ll_get_gtid_val_ili(); /* tid               */
937   args[3] = ld_sptr(flags_sptr);   /* flags             */
938   args[2] = ad_icon(size);         /* sizeof_kmp_task_t */
939   args[1] = ad_icon(shared_size);  /* sizeof_shareds    */
940   args[0] = ad_acon(sptr, 0);      /* task_entry        */
941   call_ili = mk_kmpc_api_call(KMPC_API_TASK_ALLOC, 6, arg_types, args);
942 
943   /* Create a temp to store the allocation result into */
944   ADDRTKNP(base, true);
945   nme = addnme(NT_VAR, base, 0, 0);
946   ilix = ad4ili(IL_STA, call_ili, ad_acon(base, 0), nme, MSZ_PTR);
947   chk_block(ilix);
948 
949   return base;
950 }
951 
952 /* Return a JSR ili to __kpmc_omp_task.
953  * task_sptr: sptr representing the allocated task value
954  *            resulting from calling kmpc_omp_task_alloc()
955  *            See: ll_make_kmpc_task_arg()
956  */
957 int
ll_make_kmpc_task(SPTR task_sptr)958 ll_make_kmpc_task(SPTR task_sptr)
959 {
960   int args[3];
961   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_CPTR};
962   args[2] = gen_null_arg();        /* ident */
963   args[1] = ll_get_gtid_val_ili(); /* tid   */
964   args[0] = ad2ili(IL_LDA, ad_acon(task_sptr, 0),
965                    addnme(NT_VAR, task_sptr, 0, 0)); /* task  */
966   return mk_kmpc_api_call(KMPC_API_TASK, 3, arg_types, args);
967 }
968 
969 /* Return a JSR ili to __kmpc_omp_taskyield  */
970 int
ll_make_kmpc_task_yield(void)971 ll_make_kmpc_task_yield(void)
972 {
973   int args[3];
974   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_INT};
975   args[2] = gen_null_arg();        /* ident    */
976   args[1] = ll_get_gtid_val_ili(); /* tid      */
977   args[0] = ad_icon(0);            /* end_part */
978   return mk_kmpc_api_call(KMPC_API_TASK_YIELD, 3, arg_types, args);
979 }
980 
981 int
ll_make_kmpc_task_begin_if0(SPTR task_sptr)982 ll_make_kmpc_task_begin_if0(SPTR task_sptr)
983 {
984   int args[3];
985   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_CPTR};
986   args[2] = gen_null_arg();                           /* ident */
987   args[1] = ll_get_gtid_val_ili();                    /* tid   */
988   args[0] = ad2ili(IL_LDA, ad_acon(task_sptr, 0), 0); /* task  */
989   return mk_kmpc_api_call(KMPC_API_TASK_BEGIN_IF0, 3, arg_types, args);
990 }
991 
992 int
ll_make_kmpc_task_complete_if0(SPTR task_sptr)993 ll_make_kmpc_task_complete_if0(SPTR task_sptr)
994 {
995   int args[3];
996   DTYPE arg_types[3] = {DT_CPTR, DT_INT, DT_CPTR};
997   args[2] = gen_null_arg();                           /* ident */
998   args[1] = ll_get_gtid_val_ili();                    /* tid   */
999   args[0] = ad2ili(IL_LDA, ad_acon(task_sptr, 0), 0); /* task  */
1000   return mk_kmpc_api_call(KMPC_API_TASK_COMPLETE_IF0, 3, arg_types, args);
1001 }
1002 
1003 /* Given an mp (schedule enumeration) return a KMPC equivalent enumerated
1004  * value.
1005  */
1006 #define SCHED_PREFIX(_enum_val) (MP_SCH_##_enum_val)
1007 kmpc_sched_e
mp_sched_to_kmpc_sched(int sched)1008 mp_sched_to_kmpc_sched(int sched)
1009 {
1010   if(sched & MP_SCH_ATTR_DEVICEDIST)
1011     return KMP_DISTRIBUTE_STATIC_CHUNKED_CHUNKONE;
1012   switch (sched) {
1013   case SCHED_PREFIX(AUTO):
1014     return KMP_SCH_AUTO;
1015   case SCHED_PREFIX(DYNAMIC):
1016     return KMP_SCH_DYNAMIC_CHUNKED;
1017   case SCHED_PREFIX(GUIDED):
1018     return KMP_SCH_GUIDED_CHUNKED;
1019   case SCHED_PREFIX(RUNTIME):
1020     return KMP_SCH_RUNTIME_CHUNKED;
1021   case SCHED_PREFIX(STATIC):
1022     return KMP_SCH_STATIC;
1023   case SCHED_PREFIX(DIST_STATIC):
1024     return KMP_DISTRIBUTE_STATIC;
1025 
1026   /* Ordered */
1027   case SCHED_PREFIX(AUTO) | MP_SCH_ATTR_ORDERED:
1028     return KMP_ORD_AUTO;
1029   case SCHED_PREFIX(RUNTIME) | MP_SCH_ATTR_ORDERED:
1030     return KMP_ORD_RUNTIME;
1031   case SCHED_PREFIX(STATIC) | MP_SCH_ATTR_ORDERED:
1032     return KMP_ORD_STATIC;
1033   case SCHED_PREFIX(STATIC) | MP_SCH_ATTR_ORDERED | MP_SCH_ATTR_CHUNKED:
1034     return KMP_ORD_STATIC_CHUNKED;
1035   case SCHED_PREFIX(DYNAMIC) | MP_SCH_ATTR_ORDERED:
1036   case SCHED_PREFIX(DYNAMIC) | MP_SCH_ATTR_ORDERED | MP_SCH_ATTR_CHUNKED:
1037     return KMP_ORD_DYNAMIC_CHUNKED;
1038 
1039   /* Special cases of static */
1040   case SCHED_PREFIX(STATIC) | MP_SCH_ATTR_CHUNKED:
1041   case SCHED_PREFIX(STATIC) | MP_SCH_ATTR_CHUNKED | MP_SCH_CHUNK_1:
1042   case SCHED_PREFIX(STATIC) | MP_SCH_CHUNK_1:
1043   case SCHED_PREFIX(STATIC) | MP_SCH_ATTR_CHUNKED | MP_SCH_BLK_CYC:
1044   case SCHED_PREFIX(STATIC) | MP_SCH_BLK_CYC:
1045   case SCHED_PREFIX(STATIC) | MP_SCH_BLK_ALN:
1046     return KMP_SCH_STATIC_CHUNKED;
1047 
1048   /* distribute scheduling */
1049   case SCHED_PREFIX(DIST_STATIC) | MP_SCH_ATTR_CHUNKED:
1050     return KMP_DISTRIBUTE_STATIC_CHUNKED;
1051 
1052   case SCHED_PREFIX(DIST_STATIC) | MP_SCH_ATTR_CHUNKED | MP_SCH_BLK_CYC:
1053   case SCHED_PREFIX(DIST_STATIC) | MP_SCH_ATTR_CHUNKED | MP_SCH_CHUNK_1:
1054     return KMP_DISTRIBUTE_STATIC_CHUNKED;
1055 
1056   default:
1057     error(S_0155_OP1_OP2, ERR_Warning, gbl.lineno,
1058           "Unsupported OpenMP schedule type.", NULL);
1059   }
1060   return KMP_SCH_DEFAULT;
1061 }
1062 
1063 /* Returns 'true' if this dtype is to be treated as a signed value */
1064 static bool
is_signed(int dtype)1065 is_signed(int dtype)
1066 {
1067   return true;
1068 }
1069 
1070 /* Return a JSR ili to __kmpc_for_static_init_<size><signed|unsigned>
1071  *
1072  * args: list of ili values for each arg, see the case below if args is NULL.
1073  */
1074 int
ll_make_kmpc_for_static_init_args(DTYPE dtype,int * inargs)1075 ll_make_kmpc_for_static_init_args(DTYPE dtype, int *inargs)
1076 {
1077   int args[9];
1078   DTYPE arg_types[9] = {DT_CPTR, DT_INT,  DT_INT,  DT_CPTR, DT_CPTR,
1079                         DT_CPTR, DT_CPTR, DT_INT8, DT_INT8};
1080   if (!inargs) {
1081     args[8] = gen_null_arg();        /* ident     */
1082     args[7] = ll_get_gtid_val_ili(); /* tid       */
1083     args[6] = ad_icon(0);            /* sched     */
1084     args[5] = gen_null_arg();        /* plastiter */
1085     args[4] = gen_null_arg();        /* plower    */
1086     args[3] = gen_null_arg();        /* pupper    */
1087     args[2] = gen_null_arg();        /* pstridr   */
1088     args[1] = ad_icon(0);            /* incr      */
1089     args[0] = ad_icon(0);            /* chunk     */
1090     inargs = args;
1091   }
1092 
1093   arg_types[7] = dtype; /* incr  */
1094   arg_types[8] = dtype; /* chunk */
1095 
1096   return mk_kmpc_api_call(KMPC_API_FOR_STATIC_INIT, 9, arg_types, inargs,
1097                           size_of(dtype), is_signed(dtype) ? "" : "u");
1098 }
1099 
1100 /* Return a JSR ili to __kmpc_for_static_init_<size><signed|unsigned>
1101  * TODO: Merge this routine with ll_make_kmpc_for_static_init_args
1102  */
1103 int
ll_make_kmpc_for_static_init(const loop_args_t * inargs)1104 ll_make_kmpc_for_static_init(const loop_args_t *inargs)
1105 {
1106   int args[9];
1107   DTYPE arg_types[9] = {DT_CPTR, DT_INT,  DT_INT,  DT_CPTR, DT_CPTR,
1108                         DT_CPTR, DT_CPTR, DT_INT8, DT_INT8};
1109   const DTYPE dtype = inargs->dtype;
1110   const SPTR lower = inargs->lower;
1111   const SPTR upper = inargs->upper;
1112   const SPTR stride = inargs->stride;
1113   SPTR last = inargs->last;
1114   int chunk = inargs->chunk ? ld_sptr(inargs->chunk) : ad_icon(0);
1115   const int sched = mp_sched_to_kmpc_sched(inargs->sched);
1116   const int dtypesize = size_of(dtype);
1117 
1118   if (dtypesize == 4) {
1119     chunk = kimove(chunk);
1120   } else if (dtypesize == 8) {
1121     chunk = ikmove(chunk);
1122   }
1123 
1124   args[8] = gen_null_arg();        /* ident */
1125   args[7] = ll_get_gtid_val_ili(); /* tid   */
1126   args[6] = ad_icon(sched);        /* sched     */
1127   if (!last || STYPEG(last) == ST_CONST) {
1128     last = getccsym_sc((int)'l', stb.stg_avail, ST_VAR, SCG(lower));
1129     DTYPEP(last, DT_INT);
1130     STYPEP(last, ST_VAR);
1131     ENCLFUNCP(last, GBL_CURRFUNC);
1132   }
1133   ADDRTKNP(last, 1);
1134   args[5] = mk_address(last);   /* plastiter */
1135   args[4] = mk_address(lower);  /* plower    */
1136   args[3] = mk_address(upper);  /* pupper    */
1137   args[2] = mk_address(stride); /* pstridr   */
1138   args[1] = ld_sptr(stride);    /* incr      */
1139   args[0] = chunk;              /* chunk     */
1140 
1141   ADDRTKNP(upper, 1);
1142   ADDRTKNP(stride, 1);
1143   ADDRTKNP(lower, 1);
1144 
1145   arg_types[7] = dtype; /* incr  */
1146   arg_types[8] = dtype; /* chunk */
1147 
1148   if (DBGBIT(45, 0x8))
1149     dump_loop_args(inargs);
1150 
1151   return mk_kmpc_api_call(KMPC_API_FOR_STATIC_INIT, 9, arg_types, args,
1152                           size_of(dtype), is_signed(dtype) ? "" : "u");
1153 }
1154 
1155 /* Return a JSR ili to __kmpc_dist_for_static_init_<size><signed|unsigned> */
1156 int
ll_make_kmpc_dist_for_static_init(const loop_args_t * inargs)1157 ll_make_kmpc_dist_for_static_init(const loop_args_t *inargs)
1158 {
1159   int args[10];
1160   DTYPE arg_types[10] = {DT_CPTR, DT_INT,  DT_INT,  DT_CPTR, DT_CPTR,
1161                          DT_CPTR, DT_CPTR, DT_CPTR, DT_INT8, DT_INT8};
1162   const DTYPE dtype = inargs->dtype;
1163   const SPTR lower = inargs->lower;
1164   const SPTR upper = inargs->upper;
1165   const SPTR stride = inargs->stride;
1166   SPTR last = inargs->last;
1167   const SPTR upperd = inargs->upperd;
1168   int chunk = inargs->chunk ? ld_sptr(inargs->chunk) : ad_icon(0);
1169   const int sched = mp_sched_to_kmpc_sched(inargs->sched);
1170   const int dtypesize = size_of(dtype);
1171 
1172   if (dtypesize == 4) {
1173     chunk = kimove(chunk);
1174   } else if (dtypesize == 8) {
1175     chunk = ikmove(chunk);
1176   }
1177 
1178   args[9] = gen_null_arg();        /* ident */
1179   args[8] = ll_get_gtid_val_ili(); /* tid   */
1180   args[7] = ad_icon(sched);        /* sched */
1181   if (!last || STYPEG(last) == ST_CONST) {
1182     last = getccsym_sc((int)'l', stb.stg_avail, ST_VAR, SCG(lower));
1183     DTYPEP(last, DT_INT);
1184     STYPEP(last, ST_VAR);
1185     ENCLFUNCP(last, GBL_CURRFUNC);
1186   }
1187   ADDRTKNP(last, 1);
1188   args[6] = mk_address(last);   /* plastiter */
1189   args[5] = mk_address(lower);  /* plower    */
1190   args[4] = mk_address(upper);  /* pupper    */
1191   args[3] = mk_address(upperd); /* upperd   */
1192   args[2] = mk_address(stride); /* pstridr   */
1193   args[1] = ld_sptr(stride);    /* incr      */
1194   args[0] = chunk;              /* chunk     */
1195 
1196   ADDRTKNP(upper, 1);
1197   ADDRTKNP(stride, 1);
1198   ADDRTKNP(lower, 1);
1199   ADDRTKNP(upperd, 1);
1200 
1201   arg_types[8] = dtype; /* incr  */
1202   arg_types[9] = dtype; /* chunk */
1203 
1204   if (DBGBIT(45, 0x8))
1205     dump_loop_args(inargs);
1206 
1207   return mk_kmpc_api_call(KMPC_API_DIST_FOR_STATIC_INIT, 10, arg_types, args,
1208                           size_of(dtype), is_signed(dtype) ? "" : "u");
1209 }
1210 
1211 int
ll_make_kmpc_dispatch_next(SPTR lower,SPTR upper,SPTR stride,SPTR last,DTYPE dtype)1212 ll_make_kmpc_dispatch_next(SPTR lower, SPTR upper, SPTR stride, SPTR last,
1213                            DTYPE dtype)
1214 {
1215   int args[6];
1216   DTYPE arg_types[6] = {DT_CPTR, DT_INT, DT_CPTR, DT_CPTR, DT_CPTR, DT_CPTR};
1217 
1218   /* Stride cannot be a pointer to a const, it will be updated by kmpc */
1219   args[5] = gen_null_arg();        /* ident     */
1220   args[4] = ll_get_gtid_val_ili(); /* tid       */
1221   if (!last || STYPEG(last) == ST_CONST) {
1222     last = getccsym_sc((int)'l', stb.stg_avail, ST_VAR, SCG(lower));
1223     DTYPEP(last, DT_INT);
1224     STYPEP(last, ST_VAR);
1225     ENCLFUNCP(last, GBL_CURRFUNC);
1226   }
1227   ADDRTKNP(last, 1);
1228   args[3] = mk_address(last);   /* plastflag */
1229   args[2] = mk_address(lower);  /* plower    */
1230   args[1] = mk_address(upper);  /* pupper    */
1231   args[0] = mk_address(stride); /* pstride   */
1232   ADDRTKNP(upper, 1);
1233   ADDRTKNP(lower, 1);
1234   ADDRTKNP(stride, 1);
1235   return mk_kmpc_api_call(KMPC_API_DISPATCH_NEXT, 6, arg_types, args,
1236                           size_of(dtype), is_signed(dtype) ? "" : "u");
1237 }
1238 
1239 /* Return a result or JSR ili to __kmpc_dispatch_init_<size><signed|unsigned> */
1240 int
ll_make_kmpc_dispatch_init(const loop_args_t * inargs)1241 ll_make_kmpc_dispatch_init(const loop_args_t *inargs)
1242 {
1243   int args[7];
1244   DTYPE arg_types[7] = {DT_CPTR,  DT_INT,  DT_INT, DT_UINT8,
1245                         DT_UINT8, DT_INT8, DT_INT8};
1246 
1247   const DTYPE dtype = inargs->dtype;
1248   const int lower = ld_sptr(inargs->lower);
1249   const int upper = ld_sptr(inargs->upper);
1250   const int stride = ld_sptr(inargs->stride);
1251   int chunk = ld_sptr(inargs->chunk);
1252   const int sched = mp_sched_to_kmpc_sched(inargs->sched);
1253   const int dtypesize = size_of(dtype);
1254 
1255   if (dtypesize == 4) {
1256     chunk = kimove(chunk);
1257   } else if (dtypesize == 8) {
1258     chunk = ikmove(chunk);
1259   }
1260 
1261   /* Update to use the proper dtype */
1262   arg_types[3] = dtype; /* lower  */
1263   arg_types[4] = dtype; /* upper  */
1264   arg_types[5] = dtype; /* stride */
1265   arg_types[6] = dtype; /* chunk  */
1266 
1267   /* Build up the arguments */
1268   args[6] = gen_null_arg();        /* ident */
1269   args[5] = ll_get_gtid_val_ili(); /* tid   */
1270   args[4] = ad_icon(sched);        /* sched */
1271   args[3] = lower;                 /* lower */
1272   args[2] = upper;                 /* upper */
1273   args[1] = stride;                /* incr  */
1274   args[0] = chunk;                 /* chunk */
1275 
1276   if (DBGBIT(45, 0x8))
1277     dump_loop_args(inargs);
1278 
1279   /* This will have a 4,4u,8,8u appended to the end of the function name */
1280   return mk_kmpc_api_call(KMPC_API_DISPATCH_INIT, 7, arg_types, args,
1281                           size_of(dtype), is_signed(dtype) ? "" : "u");
1282 }
1283 
1284 /* Return a result or JSR ili to
1285  * __kmpc_dist_dispatch_init_<size><signed|unsigned> */
1286 int
ll_make_kmpc_dist_dispatch_init(const loop_args_t * inargs)1287 ll_make_kmpc_dist_dispatch_init(const loop_args_t *inargs)
1288 {
1289   int args[8];
1290   DTYPE arg_types[8] = {DT_CPTR,  DT_INT,   DT_INT,  DT_CPTR,
1291                         DT_UINT8, DT_UINT8, DT_INT8, DT_INT8};
1292 
1293   const DTYPE dtype = inargs->dtype;
1294   const int lower = ld_sptr(inargs->lower);
1295   const int upper = ld_sptr(inargs->upper);
1296   const int stride = ld_sptr(inargs->stride);
1297   SPTR last = inargs->last;
1298   const int upperd = inargs->upperd;
1299   int chunk = ld_sptr(inargs->chunk);
1300   const int sched = mp_sched_to_kmpc_sched(inargs->sched);
1301   const int dtypesize = size_of(dtype);
1302 
1303   if (dtypesize == 4) {
1304     chunk = kimove(chunk);
1305   } else if (dtypesize == 8) {
1306     chunk = ikmove(chunk);
1307   }
1308 
1309   /* Update to use the proper dtype */
1310   arg_types[4] = dtype; /* lower  */
1311   arg_types[5] = dtype; /* upper  */
1312   arg_types[6] = dtype; /* stride */
1313   arg_types[7] = dtype; /* chunk  */
1314 
1315   /* Build up the arguments */
1316   args[7] = gen_null_arg();        /* ident */
1317   args[6] = ll_get_gtid_val_ili(); /* tid   */
1318   args[5] = ad_icon(sched);        /* sched */
1319 
1320   if (!last || STYPEG(last) == ST_CONST) {
1321     last = getccsym_sc((int)'l', stb.stg_avail, ST_VAR, SCG(lower));
1322     DTYPEP(last, DT_INT);
1323     STYPEP(last, ST_VAR);
1324     ENCLFUNCP(last, GBL_CURRFUNC);
1325   }
1326   ADDRTKNP(last, 1);
1327   args[4] = mk_address(last); /* plastiter */
1328   args[3] = lower;            /* lower */
1329   args[2] = upper;            /* upper */
1330   args[1] = stride;           /* incr  */
1331   args[0] = chunk;            /* chunk */
1332 
1333   if (DBGBIT(45, 0x8))
1334     dump_loop_args(inargs);
1335 
1336   /* This will have a 4,4u,8,8u appended to the end of the function name */
1337   return mk_kmpc_api_call(KMPC_API_DIST_DISPATCH_INIT, 8, arg_types, args,
1338                           size_of(dtype), is_signed(dtype) ? "" : "u");
1339 }
1340 
1341 /* Return a result or JSR ili to __kmpc_dispatch_fini_<size><signed|unsigned> */
1342 int
ll_make_kmpc_dispatch_fini(DTYPE dtype)1343 ll_make_kmpc_dispatch_fini(DTYPE dtype)
1344 {
1345   int args[2];
1346   DTYPE arg_types[2] = {DT_CPTR, DT_INT};
1347   args[1] = gen_null_arg();
1348   args[0] = ll_get_gtid_val_ili();
1349   return mk_kmpc_api_call(KMPC_API_DISPATCH_FINI, 2, arg_types, args,
1350                           size_of(dtype), is_signed(dtype) ? "" : "u");
1351 }
1352 
1353 /* Return a result or JSR ili to __kmpc_taskloop
1354  * kmpc_taskloop(ident, gtid, (?*) task,
1355                  (int)if_val,
1356                  (int64*) lb,   (int64*)ub, (int64)st,
1357                  (int)nogroup,  (int)sched, (int64)grainsize,
1358                   * task_dup)
1359  */
1360 int
ll_make_kmpc_taskloop(int * inargs)1361 ll_make_kmpc_taskloop(int *inargs)
1362 {
1363   int args[11];
1364   DTYPE arg_types[11] = {DT_CPTR, DT_INT, DT_CPTR, DT_INT,  DT_CPTR, DT_CPTR,
1365                          DT_INT8, DT_INT, DT_INT,  DT_INT8, DT_CPTR};
1366 
1367   /* Build up the arguments */
1368   args[10] = gen_null_arg();       /* ident */
1369   args[9] = ll_get_gtid_val_ili(); /* gtid   */
1370   args[8] = inargs[0];             /* task structure */
1371   args[7] = inargs[1];             /* if_val */
1372   args[6] = inargs[2];             /* lower */
1373   args[5] = inargs[3];             /* upper */
1374   args[4] = inargs[4];             /* stride */
1375   args[3] = inargs[5];             /* 1:nogroup */
1376   args[2] = inargs[6];             /* 0:none,1:grainsize,2:num_task */
1377   args[1] = inargs[7];             /* grainsize */
1378   args[0] = inargs[8] ? inargs[8] : gen_null_arg(); /* task_dup */
1379 
1380   return mk_kmpc_api_call(KMPC_API_TASKLOOP, 11, arg_types, args);
1381 }
1382 
1383 int
ll_make_kmpc_task_with_deps(const loop_args_t * inargs)1384 ll_make_kmpc_task_with_deps(const loop_args_t *inargs)
1385 {
1386   return 0;
1387 }
1388 
1389 int
ll_make_kmpc_omp_wait_deps(const loop_args_t * inargs)1390 ll_make_kmpc_omp_wait_deps(const loop_args_t *inargs)
1391 {
1392   return 0;
1393 }
1394 
1395 void
reset_kmpc_ident_dtype(void)1396 reset_kmpc_ident_dtype(void)
1397 {
1398   kmpc_ident_dtype = DT_NONE;
1399 }
1400 
1401 /* Return a result or JSR ili to __kmpc_threadprivate() */
1402 int
ll_make_kmpc_threadprivate(int data_ili,int size_ili)1403 ll_make_kmpc_threadprivate(int data_ili, int size_ili)
1404 {
1405   int args[4];
1406   DTYPE arg_types[4] = {DT_CPTR, DT_INT, DT_CPTR, DT_INT8};
1407   /*size_t*/
1408   args[3] = gen_null_arg();        /* ident     */
1409   args[2] = ll_get_gtid_val_ili(); /* tid       */
1410   args[1] = data_ili;              /* data      */
1411   args[0] = size_ili;              /* size      */
1412   return mk_kmpc_api_call(KMPC_API_THREADPRIVATE, 4, arg_types, args);
1413 }
1414 
1415 int
ll_make_kmpc_atomic_write(int * opnd,DTYPE dtype)1416 ll_make_kmpc_atomic_write(int *opnd, DTYPE dtype)
1417 {
1418   char *type = "";
1419   int args[4];
1420   DTYPE arg_types[4] = {DT_CPTR, DT_INT, DT_CPTR, DT_CPTR};
1421   args[3] = gen_null_arg();        /* ident     */
1422   args[2] = ll_get_gtid_val_ili(); /* tid       */
1423   args[1] = opnd[1];               /*  lhs      */
1424   args[0] = opnd[2];               /*  rhs      */
1425 
1426   switch (dtype) {
1427   case DT_BLOG:
1428   case DT_SLOG:
1429   case DT_LOG:
1430   case DT_LOG8:
1431   case DT_BINT:
1432 #ifdef DT_SINT
1433   case DT_SINT:
1434 #endif
1435   case DT_USINT:
1436   case DT_INT:
1437   case DT_UINT:
1438   case DT_INT8:
1439     return mk_kmpc_api_call(KMPC_API_ATOMIC_WR, 4, arg_types, args, "fixed",
1440                             size_of(dtype));
1441 
1442 #ifdef DT_FLOAT
1443   case DT_FLOAT:
1444 #endif
1445 #ifdef DT_DBLE
1446   case DT_DBLE:
1447     return mk_kmpc_api_call(KMPC_API_ATOMIC_WR, 4, arg_types, args, "float",
1448                             size_of(dtype));
1449 #endif
1450   case DT_CMPLX:
1451   case DT_DCMPLX:
1452     return mk_kmpc_api_call(KMPC_API_ATOMIC_WR, 4, arg_types, args, "cmplx",
1453                             size_of(dtype));
1454   default:
1455     break;
1456   }
1457   return 0;
1458 }
1459 
1460 int
ll_make_kmpc_atomic_read(int * opnd,DTYPE dtype)1461 ll_make_kmpc_atomic_read(int *opnd, DTYPE dtype)
1462 {
1463   char *type = "";
1464   int args[4];
1465   DTYPE arg_types[5] = {DT_CPTR, DT_INT, DT_CPTR, DT_CPTR};
1466   args[3] = gen_null_arg();        /* ident     */
1467   args[2] = ll_get_gtid_val_ili(); /* tid       */
1468   args[1] = opnd[1];               /*  lhs      */
1469   args[0] = opnd[2];               /*  rhs      */
1470 
1471   switch (dtype) {
1472   case DT_BLOG:
1473   case DT_SLOG:
1474   case DT_LOG:
1475   case DT_LOG8:
1476   case DT_BINT:
1477 #ifdef DT_SINT
1478   case DT_SINT:
1479 #endif
1480   case DT_USINT:
1481   case DT_INT:
1482   case DT_UINT:
1483   case DT_INT8:
1484     return mk_kmpc_api_call(KMPC_API_ATOMIC_RD, 4, arg_types, args, "fixed",
1485                             size_of(dtype));
1486 
1487 #ifdef DT_FLOAT
1488   case DT_FLOAT:
1489 #endif
1490 #ifdef DT_DBLE
1491   case DT_DBLE:
1492     return mk_kmpc_api_call(KMPC_API_ATOMIC_RD, 4, arg_types, args, "float",
1493                             size_of(dtype));
1494 #endif
1495   case DT_CMPLX:
1496   case DT_DCMPLX:
1497     return mk_kmpc_api_call(KMPC_API_ATOMIC_RD, 4, arg_types, args, "cmplx",
1498                             size_of(dtype));
1499   default:
1500     break;
1501   }
1502   return 0;
1503 }
1504 
1505 #ifdef OMP_OFFLOAD_LLVM
1506 
1507 static DTYPE
create_dtype_funcprototype()1508 create_dtype_funcprototype()
1509 {
1510   DTYPE dtypeFinal, dtypeInner;
1511   dtypeInner = get_type(2, TY_PROC, DT_ANY);
1512   dtypeFinal = get_type(2, TY_PTR, dtypeInner);
1513   return dtypeFinal;
1514 }
1515 
1516 /* OpenMP Accelerator RT (libomptarget-nvptx) - non standard - */
1517 int
ll_make_kmpc_push_target_tripcount(int device_id,SPTR sptr)1518 ll_make_kmpc_push_target_tripcount(int device_id, SPTR sptr)
1519 {
1520   int args[2];
1521   DTYPE arg_types[2] = {DT_INT8, DT_UINT8};
1522   /*size_t*/
1523   args[1] = ad_icon(device_id); /* device_id           */
1524   args[0] = ld_sptr(sptr);      /* sptr_tripcount      */
1525   return mk_kmpc_api_call(KMPC_API_PUSH_TARGET_TRIPCOUNT, 2, arg_types, args);
1526 }
1527 
1528 int
ll_make_kmpc_shuffle(int ili_val,int ili_delta,int ili_size,bool isint64)1529 ll_make_kmpc_shuffle(int ili_val, int ili_delta, int ili_size, bool isint64)
1530 {
1531   int args[3];
1532   DTYPE arg_types[3] = {DT_INT, DT_SINT, DT_SINT};
1533   if (isint64)
1534     arg_types[0] = DT_INT8;
1535   /*size_t*/
1536   args[2] = ili_val;   /* value               */
1537   args[1] = ili_delta; /* delta               */
1538   args[0] = ili_size;  /* size                */
1539   if (isint64)
1540     return mk_kmpc_api_call(KMPC_API_SHUFFLE_I64, 3, arg_types, args);
1541   return mk_kmpc_api_call(KMPC_API_SHUFFLE_I32, 3, arg_types, args);
1542 }
1543 
1544 int
ll_make_kmpc_kernel_init_params(int ReductionScratchpadPtr)1545 ll_make_kmpc_kernel_init_params(int ReductionScratchpadPtr)
1546 {
1547   int args[1];
1548   DTYPE arg_types[1] = {DT_ADDR};
1549   /*size_t*/
1550   args[1] = ReductionScratchpadPtr; /* Scratchpad pointer for reduction*/
1551   return mk_kmpc_api_call(KMPC_API_KERNEL_INIT_PARAMS, 1, arg_types, args);
1552 }
1553 
1554 int
ll_make_kmpc_spmd_kernel_init(int sptr)1555 ll_make_kmpc_spmd_kernel_init(int sptr)
1556 {
1557   int args[3];
1558   DTYPE arg_types[3] = {DT_INT, DT_SINT, DT_SINT};
1559   args[2] = sptr; // ld_sptr(sptr);
1560   args[1] = gen_null_arg();
1561   args[0] = gen_null_arg();
1562   return mk_kmpc_api_call(KMPC_API_SPMD_KERNEL_INIT, 3, arg_types, args);
1563 }
1564 
1565 int
ll_make_kmpc_nvptx_parallel_reduce_nowait_simple_spmd(int ili_num_vars,int ili_reduce_size,int ili_reduceData,SPTR sptrShuffleFn,SPTR sptrCopyFn)1566 ll_make_kmpc_nvptx_parallel_reduce_nowait_simple_spmd(int ili_num_vars,
1567                                                       int ili_reduce_size,
1568                                                       int ili_reduceData,
1569                                                       SPTR sptrShuffleFn,
1570                                                       SPTR sptrCopyFn)
1571 {
1572   DTYPE dtypeShuffleFn = create_dtype_funcprototype();
1573   DTYPE dtypeCopyFn = create_dtype_funcprototype();
1574   int args[6];
1575   DTYPE arg_types[6] = {DT_INT,  DT_INT,         DT_INT8,
1576                         DT_ADDR, dtypeShuffleFn, dtypeCopyFn};
1577   args[5] = ompaccel_nvvm_get_gbl_tid(); /* global id           */
1578   args[4] = ili_num_vars;                /* num vars            */
1579   args[3] = ili_reduce_size;             /* reducesize          */
1580   args[2] = ili_reduceData;              /* reduceData          */
1581   args[1] = mk_address(sptrShuffleFn);   /* shuffle Fn          */
1582   args[0] = mk_address(sptrCopyFn);      /* Inter warp copy Fn  */
1583 
1584   return mk_kmpc_api_call(KMPC_API_NVPTX_PARALLEL_REDUCE_NOWAIT_SIMPLE_SPMD, 6,
1585                           arg_types, args);
1586 }
1587 
1588 int
ll_make_kmpc_nvptx_end_reduce_nowait()1589 ll_make_kmpc_nvptx_end_reduce_nowait()
1590 {
1591   int args[1];
1592   DTYPE arg_types[1] = {DT_INT};
1593   args[0] = ompaccel_nvvm_get_gbl_tid(); /* global id      */
1594   return mk_kmpc_api_call(KMPC_API_NVPTX_END_REDUCE_NOWAIT, 1, arg_types, args);
1595 }
1596 
1597 int
ll_make_kmpc_for_static_init_simple_spmd(const loop_args_t * inargs,int sched)1598 ll_make_kmpc_for_static_init_simple_spmd(const loop_args_t *inargs, int sched)
1599 {
1600   int args[9];
1601   DTYPE arg_types[9] = {DT_CPTR, DT_INT,  DT_INT,  DT_CPTR, DT_CPTR,
1602                         DT_CPTR, DT_CPTR, DT_INT8, DT_INT8};
1603   DTYPE dtype = inargs->dtype;
1604   SPTR lower = inargs->lower;
1605   SPTR upper = inargs->upper;
1606   SPTR stride = inargs->stride;
1607   int last = inargs->last;
1608   int chunk = inargs->chunk ? ld_sptr(inargs->chunk) : ad_icon(0);
1609   const int dtypesize = size_of(dtype);
1610 
1611   if (dtypesize == 4) {
1612     chunk = kimove(chunk);
1613   } else if (dtypesize == 8) {
1614     chunk = ikmove(chunk);
1615   }
1616 
1617   args[8] = gen_null_arg(); /* ident */
1618   args[7] = ad_icon(0);
1619   args[6] = ad_icon(sched); /* sched     */
1620   if (last
1621       && STYPEG(last) != ST_CONST
1622   ) {
1623     args[5] = mk_address((SPTR)last); /* plastiter */
1624     ADDRTKNP(last, 1);
1625   } else {
1626     args[5] = gen_null_arg();
1627   }
1628   args[4] = mk_address(lower);  /* plower    */
1629   args[3] = mk_address(upper);  /* pupper    */
1630   args[2] = mk_address(stride); /* pstridr   */
1631   args[1] = ld_sptr(stride);    /* incr      */
1632   args[0] = chunk;              /* chunk     */
1633 
1634   ADDRTKNP(upper, 1);
1635   ADDRTKNP(stride, 1);
1636   ADDRTKNP(lower, 1);
1637 
1638   arg_types[7] = dtype; /* incr  */
1639   arg_types[8] = dtype; /* chunk */
1640 
1641   if (DBGBIT(45, 0x8))
1642     dump_loop_args(inargs);
1643 
1644   return mk_kmpc_api_call(KMPC_API_FOR_STATIC_INIT_SIMPLE_SPMD, 9, arg_types,
1645                           args, size_of(dtype), is_signed(dtype) ? "" : "u");
1646 }
1647 #endif /* End #ifdef OMP_OFFLOAD_LLVM */
1648