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