1 /*
2 * Copyright (c) 2017-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 tgtutil.c - Various definitions for the libomptarget runtime
20 *
21 */
22
23 #define _GNU_SOURCE // for vasprintf()
24 #include <stdio.h>
25 #undef _GNU_SOURCE
26 #include "dinit.h"
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 "iliutil.h"
41 #include "llutil.h"
42 #include "ompaccel.h"
43 #include "tgtutil.h"
44 #include "assem.h"
45 #include "dinitutl.h"
46 #include "cgllvm.h"
47 #include "cgmain.h"
48 #include "regutil.h"
49 #include "dtypeutl.h"
50 #include "llassem.h"
51 #include "symfun.h"
52 #include "ccffinfo.h"
53
54 #ifdef OMP_OFFLOAD_LLVM
55 static void change_target_func_smbols(int outlined_func_sptr, int stblk_sptr);
56 static SPTR init_tgt_target_syms(const char *kernelname);
57 #endif
58
59 #if defined(OMP_OFFLOAD_LLVM) || defined(OMP_OFFLOAD_PGI)
60
61 #define MXIDLEN 100
62 static int dataregion = 0;
63
64 static DTYPE tgt_offload_entry_type = DT_NONE;
65
66 /* Flags for use with the entry */
67 #define DT_VOID_NONE DT_NONE
68
69 #ifdef __cplusplus
70 static class ClassTgtApiCalls
71 {
72 public:
operator [](int off)73 const struct tgt_api_entry_t operator[](int off)
74 {
75 switch (off) {
76 case TGT_API_BAD:
77 return {"__INVALID_TGT_API_NAME__", -1, (DTYPE)-1};
78 case TGT_API_REGISTER_LIB:
79 return {"__tgt_register_lib", 0, DT_NONE};
80 case TGT_API_TARGET:
81 return {"__tgt_target", 0, DT_INT};
82 case TGT_API_TARGET_TEAMS:
83 return {"__tgt_target_teams", 0, DT_INT};
84 case TGT_API_TARGET_DATA_BEGIN:
85 return {"__tgt_target_data_begin", 0, DT_NONE};
86 case TGT_API_TARGET_DATA_END:
87 return {"__tgt_target_data_end", 0, DT_NONE};
88 case TGT_API_TARGETUPDATE:
89 return {"__tgt_target_data_update", 0, DT_NONE};
90 default:
91 return {nullptr, 0, DT_NONE};
92 }
93 }
94 } tgt_api_calls;
95 #else
96 static const struct tgt_api_entry_t tgt_api_calls[] = {
97 [TGT_API_BAD] = {"__INVALID_TGT_API_NAME__", -1, -1},
98 [TGT_API_REGISTER_LIB] = {"__tgt_register_lib", 0, DT_VOID_NONE},
99 [TGT_API_TARGET] = {"__tgt_target", 0, DT_INT},
100 [TGT_API_TARGET_TEAMS] = {"__tgt_target_teams", 0, DT_INT},
101 [TGT_API_TARGET_TEAMS_PARALLEL] = {"__tgt_target_teams_parallel", 0, DT_INT},
102 [TGT_API_TARGET_DATA_BEGIN] = {"__tgt_target_data_begin", 0, DT_VOID_NONE},
103 [TGT_API_TARGET_DATA_END] = {"__tgt_target_data_end", 0, DT_VOID_NONE},
104 [TGT_API_TARGETUPDATE] = {"__tgt_target_data_update", 0, DT_VOID_NONE}};
105 #endif
106 static int
gen_null_arg()107 gen_null_arg()
108 {
109 int con, ili;
110 INT tmp[2];
111
112 tmp[0] = 0;
113 tmp[1] = 0;
114 con = getcon(tmp, DT_INT);
115 ili = ad1ili(IL_ACON, con);
116 return ili;
117 }
118 /* Return ili (icon/kcon, or a loaded value) for use with mk_kmpc_api_call
119 * arguments.
120 */
121 static int
ld_sptr(SPTR sptr)122 ld_sptr(SPTR sptr)
123 {
124 ISZ_T sz = size_of(DTYPEG(sptr));
125
126 if (STYPEG(sptr) == ST_CONST) {
127 if (sz == 8)
128 return ad_kcon(CONVAL1G(sptr), CONVAL2G(sptr));
129 return ad_icon(CONVAL2G(sptr));
130 } else {
131 int nme = addnme(NT_VAR, sptr, 0, 0);
132 int ili = mk_address(sptr);
133 if (ILI_OPC(ili) == IL_LDA)
134 nme = ILI_OPND(ili, 2);
135 if(DTYPEG(sptr) == DT_DBLE)
136 return ad3ili(IL_LDDP, ili, nme, MSZ_I8);
137 else if (sz == 8)
138 return ad3ili(IL_LDKR, ili, nme, MSZ_I8);
139 else
140 return ad3ili(IL_LD, ili, nme, mem_size(DTY(DTYPEG(sptr))));
141 }
142 }
143 static char*
getSPTRname(SPTR sptr)144 getSPTRname(SPTR sptr){
145 char* name;
146 if(ST_CONST == STYPEG(sptr)) {
147 NEW(name, char, 100);
148 sprintf(name, "%d", CONVAL2G(sptr));
149 return name;
150 }
151 return getprint(sptr);
152 }
153 static char*
getILIname(int ili)154 getILIname(int ili)
155 {
156 ILI_OP op = ilib.stg_base[ili].opc;
157 char *name, *fname;
158 switch(op)
159 {
160 case IL_ACON:
161 case IL_ICON:
162 return getSPTRname(ILI_SymOPND(ili, 1));
163 case IL_DFRIR:
164 name = getSPTRname(ILI_SymOPND((ILI_SymOPND(ili,1)),1));
165 NEW(fname, char, strlen(name)+5);
166 sprintf(fname,"%s()", name);
167 return fname;
168 case IL_LD:
169 case IL_LDA:
170 case IL_LD256:
171 case IL_LDDCMPLX:
172 case IL_LDDP:
173 case IL_LDHP:
174 case IL_LDKR:
175 case IL_LDQ:
176 case IL_LDQU:
177 case IL_LDSP:
178 return getSPTRname(NME_SYM(ILI_SymOPND(ili, 2)));
179 default:
180 return "[symbol name cannot be printed]";
181 }
182 return "[symbol name cannot be printed]";
183 }
184
185 #define TGT_CHK(_api) \
186 (((_api) > TGT_API_BAD && (_api) < TGT_API_N_ENTRIES) ? _api : TGT_API_BAD)
187
188 #define TGT_NAME(_api) tgt_api_calls[TGT_CHK(_api)].name
189 #define TGT_RET_DTYPE(_api) tgt_api_calls[TGT_CHK(_api)].ret_dtype
190 #define TGT_RET_ILIOPC(_api) tgt_api_calls[TGT_CHK(_api)].ret_iliopc
191
192 /* The return value is allocated and maintained locally, please do not call
193 * 'free' on this, bad things will probably happen.
194 *
195 * Caller is responsible for calling va_end()
196 *
197 * This function will maintain one allocation for unique function name.
198 */
199 static const char *
build_tgt_api_name(int tgt_api)200 build_tgt_api_name(int tgt_api)
201 {
202 static hashmap_t names; /* Maintained in this routine */
203
204 if (!names)
205 names = hashmap_alloc(hash_functions_strings);
206
207 return TGT_NAME(tgt_api);
208 }
209
210 static int
ll_make_tgt_proto(const char * nm,int tgt_api,int argc,DTYPE * args)211 ll_make_tgt_proto(const char *nm, int tgt_api, int argc, DTYPE *args)
212 {
213 DTYPE ret_dtype;
214 /* args contains a list of dtype. The actual sptr of args will be create in
215 ll_make_ftn_outlined_params.
216 */
217 const SPTR func_sptr = getsymbol(nm);
218
219 ret_dtype = TGT_RET_DTYPE(tgt_api);
220
221 DTYPEP(func_sptr, ret_dtype);
222 SCP(func_sptr, SC_EXTERN);
223 STYPEP(func_sptr, ST_PROC);
224 CCSYMP(func_sptr,
225 1); /* currently we make all CCSYM func varargs in Fortran. */
226 CFUNCP(func_sptr, 1);
227 ll_make_ftn_outlined_params(func_sptr, argc, args);
228 ll_process_routine_parameters(func_sptr);
229 return func_sptr;
230 }
231
232 /* Returns the function prototype sptr.
233 * 'reg_opc' ILI op code for return value, e.g., IL_DFRIR or 0 if void
234 * 'ret_dtype' dtype representing return value
235 */
236 static int
mk_tgt_api_call(int tgt_api,int n_args,DTYPE * arg_dtypes,int * arg_ilis)237 mk_tgt_api_call(int tgt_api, int n_args, DTYPE *arg_dtypes, int *arg_ilis)
238 {
239 int i, ilix, altilix, gargs, garg_ilis[n_args];
240 SPTR fn_sptr;
241 const char *nm;
242 const ILI_OP ret_opc = (ILI_OP)TGT_RET_ILIOPC(tgt_api);
243 const DTYPE ret_dtype = TGT_RET_DTYPE(tgt_api);
244
245 /* Create the prototype for the API call */
246 nm = build_tgt_api_name(tgt_api);
247 fn_sptr = (SPTR)ll_make_tgt_proto(nm, tgt_api, n_args, arg_dtypes);
248 sym_is_refd(fn_sptr);
249
250 /* Update ACC routine tables and then create the JSR */
251 update_acc_with_fn(fn_sptr);
252 ilix = ll_ad_outlined_func2(ret_opc, IL_JSR, fn_sptr, n_args, arg_ilis);
253
254 /* Create the GJSR */
255 for (i = n_args - 1; i >= 0; --i) /* Reverse the order */
256 garg_ilis[i] = arg_ilis[n_args - 1 - i];
257 gargs = ll_make_outlined_garg(n_args, garg_ilis, arg_dtypes);
258 altilix = ad3ili(IL_GJSR, fn_sptr, gargs, 0);
259
260 /* Add gjsr as an alt to the jsr */
261 if (ret_opc)
262 ILI_ALT(ILI_OPND(ilix, 1)) = altilix;
263 else
264 ILI_ALT(ilix) = altilix;
265
266 return ilix;
267 }
268
269 SPTR
make_array_sptr(char * name,DTYPE atype,int arraysize)270 make_array_sptr(char *name, DTYPE atype, int arraysize)
271 {
272 SPTR array;
273 DTYPE dtype;
274 array = getsymbol(name);
275 STYPEP(array, ST_ARRAY);
276 CCSYMP(array, 1);
277 {
278 ADSC *adsc;
279 INT con[2] = {0, arraysize};
280
281 dtype = get_array_dtype(1, atype);
282 adsc = AD_DPTR(dtype);
283 AD_LWBD(adsc, 0) = stb.i1;
284 AD_UPBD(adsc, 0) = getcon(con, DT_INT);
285 AD_NUMELM(adsc) = AD_UPBD(adsc, 0);
286 }
287
288 DTYPEP(array, dtype);
289 SCP(array, SC_AUTO);
290 return array;
291 } /* make_array_sptr*/
292
293
294 static int
_tgt_target_fill_size(SPTR sptr,int map_type)295 _tgt_target_fill_size(SPTR sptr, int map_type)
296 {
297 DTYPE dtype = DTYPEG(sptr);
298 int ilix, rilix;
299 ADSC *ad;
300 if(llis_pointer_kind(dtype)) {
301 if (map_type & OMP_TGT_MAPTYPE_IMPLICIT) {
302 ilix = ad_kconi(0);
303 } else
304 /* find the size of pointee */
305 ilix = ad_kconi(size_of(DTySeqTyElement(dtype)));
306 }
307 else if (llis_vector_kind(dtype)) {
308 ompaccelInternalFail("Vector data type is not implemented, cannot be passed to target region. ");
309 } else if (llis_struct_kind(dtype)) {
310 ompaccelInternalFail("Struct data type is not implemented, cannot be passed to target region. ");
311 } else if (llis_function_kind(dtype)) {
312 ompaccelInternalFail("Function data type is not implemented, cannot be passed to target region. ");
313 } else if (llis_integral_kind(dtype) || dtype == DT_DBLE || dtype == DT_FLOAT) {
314 ilix = ad_kconi(size_of(dtype));
315 } else if(llis_array_kind(dtype)) {
316 if(map_type & OMP_TGT_MAPTYPE_IMPLICIT) {
317 ilix = ad_kconi(0);
318 } else {
319 ad = AD_DPTR(dtype);
320 if (SCG(sptr) == SC_STATIC) {
321 ISZ_T size;
322 int j, numdim = AD_NUMDIM(ad);
323 size = 1;
324 for (j = 0; j < numdim; ++j) {
325 size = size * CONVAL2G(AD_UPBD(ad, j)) - CONVAL2G(AD_LWBD(ad, j)) + 1;
326 }
327 size = size_of((DTYPE)DTyAlgTyMember(dtype)) * size;
328 ilix = ad_icon(size);
329 } else {
330 int numdim = AD_NUMDIM(ad);
331 int j;
332 ilix = ad_kconi(1);
333 // todo ompaccel we do not support partial arrays here.
334 for (j = 0; j < numdim; ++j) {
335 if (AD_UPBD(ad, j) != 0) {
336 SPTR ub = (SPTR) AD_UPBD(ad, j);
337 SPTR lb = (SPTR) AD_LWBD(ad, j);
338 rilix = ad2ili(IL_KSUB, ld_sptr(ub), ld_sptr(lb));
339 rilix = ad2ili(IL_KADD, rilix, ad_kconi(1));
340 } else
341 rilix = ad2ili(IL_KADD, ad_kconi(0), ad_kconi(1));
342 ilix = ad2ili(IL_KMUL, ilix, rilix);
343 }
344 ilix = ad2ili(IL_KMUL, ilix, ad_kconi(size_of((DTYPE)(dtype + 1))));
345 }
346 }
347 }else {
348 ompaccelInternalFail("Unknown data type");
349 }
350 return ilix;
351 }
352
353 static int
_tgt_target_fill_maptype(SPTR sptr,int maptype,int isMidnum,int midnum_maptype)354 _tgt_target_fill_maptype(SPTR sptr, int maptype, int isMidnum, int midnum_maptype) {
355 int final_maptype = 0;
356 /*todo ompaccel there are many cases to be covered. It is not completed yet. */
357 if(isMidnum)
358 final_maptype |= midnum_maptype;
359 else if(maptype == 0)
360 final_maptype = OMP_TGT_MAPTYPE_IMPLICIT | OMP_TGT_MAPTYPE_TARGET_PARAM;
361 else
362 final_maptype = maptype;
363
364 DTYPE dtype = DTYPEG(sptr);
365 if(final_maptype & OMP_TGT_MAPTYPE_IMPLICIT) {
366 if (llis_pointer_kind(dtype)) {
367
368 } else if (llis_array_kind(dtype)) {
369
370 } else if (llis_vector_kind(dtype)) {
371 ompaccelInternalFail("Don't know how to implicitly define map type for vector data type ");
372 } else if (llis_integral_kind(dtype) || dtype == DT_DBLE || dtype == DT_FLOAT) {
373 final_maptype |= OMP_TGT_MAPTYPE_LITERAL;
374 } else if (llis_function_kind(dtype)) {
375 ompaccelInternalFail("Don't know how to implicitly define map type for function data type ");
376 } else if (llis_struct_kind(dtype)) {
377 ompaccelInternalFail("Don't know how to implicitly define map type for struct data type ");
378 } else {
379 ompaccelInternalFail("Unknown data type");
380 }
381 }
382 return final_maptype;
383 }
384
385 void
tgt_target_fill_params(SPTR arg_base_sptr,SPTR arg_size_sptr,SPTR args_sptr,SPTR args_maptypes_sptr,OMPACCEL_TINFO * targetinfo)386 tgt_target_fill_params(SPTR arg_base_sptr, SPTR arg_size_sptr, SPTR args_sptr,
387 SPTR args_maptypes_sptr, OMPACCEL_TINFO *targetinfo)
388 {
389 int i, j, ilix, iliy;
390 char *name_base="", *name_length="";
391 OMPACCEL_SYM midnum_sym;
392 DTYPE param_dtype, load_dtype;
393 SPTR param_sptr;
394 LOGICAL isPointer, isMidnum, isImplicit, isThis;
395 /* fill the arrays */
396 /* Build the list: (size, sptr) pairs. */
397
398 for (i = 0; i < targetinfo->n_symbols; ++i) {
399 int nme_args, nme_size, nme_base, nme_types;
400 nme_args = add_arrnme(NT_ARR, args_sptr, addnme(NT_VAR, args_sptr, 0, 0), 0, ad_icon(i), FALSE);
401 nme_size = add_arrnme(NT_ARR, arg_size_sptr, addnme(NT_VAR, arg_size_sptr, 0, 0), 0, ad_icon(i), FALSE);
402 nme_base = add_arrnme(NT_ARR, arg_base_sptr, addnme(NT_VAR, arg_base_sptr, 0, 0), 0, ad_icon(i), FALSE);
403 nme_types = add_arrnme(NT_ARR, args_maptypes_sptr, addnme(NT_VAR, args_maptypes_sptr, 0, 0), 0, ad_icon(i), FALSE);
404
405 isMidnum = FALSE;
406 param_sptr = targetinfo->symbols[i].host_sym;
407 param_dtype = DTYPEG(param_sptr);
408 isPointer = llis_pointer_kind(param_dtype);
409
410 /* This is for fortran allocatable arrays.
411 * We keep the base symbol as a quiet symbol that has the map type info.
412 * When the symbol is a pointer, it's base symbol might be in the quiet symbol list.
413 * Then we should look for its map type.
414 */
415 if(isPointer) {
416 for (j = 0; j < targetinfo->n_quiet_symbols; ++j) {
417 SPTR midnum_sptr = MIDNUMG(targetinfo->quiet_symbols[j].host_sym);
418 if (midnum_sptr == param_sptr || HASHLKG(midnum_sptr) == param_sptr) {
419 midnum_sym = targetinfo->quiet_symbols[j];
420 isMidnum = TRUE;
421 break;
422 }
423 }
424 }
425 /* Implicit map(to:) for the array descriptor */
426 if(DESCARRAYG(param_sptr)) {
427 targetinfo->symbols[i].map_type = OMP_TGT_MAPTYPE_TARGET_PARAM | OMP_TGT_MAPTYPE_TO;
428 }
429 /* assign map type */
430 targetinfo->symbols[i].map_type = _tgt_target_fill_maptype(param_sptr, targetinfo->symbols[i].map_type, isMidnum, midnum_sym.map_type);
431 ilix = ad4ili(IL_ST, ad_icon(targetinfo->symbols[i].map_type),
432 ad_acon(args_maptypes_sptr, i * TARGET_PTRSIZE), nme_types, MSZ_I8);
433 chk_block(ilix);
434
435 /* Find the base */
436 if(targetinfo->symbols[i].in_map) {
437 if(llis_array_kind(param_dtype))
438 param_dtype = array_element_dtype(param_dtype);
439 else if (llis_pointer_kind(param_dtype))
440 param_dtype = DTySeqTyElement(param_dtype);
441 iliy = targetinfo->symbols[i].ili_base;
442 ilix = mk_ompaccel_store(iliy, DT_ADDR, nme_base,
443 ad_acon(arg_base_sptr, i * TARGET_PTRSIZE));
444 /* Assign args */
445 chk_block(ilix);
446 ilix = ad1ili(IL_IKMV, targetinfo->symbols[i].ili_lowerbound);
447 ilix = mk_ompaccel_mul(ilix, DT_INT8, ad_kconi(size_of(param_dtype)),
448 DT_INT8);
449 ilix = ad1ili(IL_KAMV, ilix);
450 ilix = mk_ompaccel_add(iliy, DT_ADDR, ilix, DT_INT8);
451 ilix = mk_ompaccel_store(ilix, DT_ADDR, nme_args,
452 ad_acon(args_sptr, i * TARGET_PTRSIZE));
453 name_base = getILIname(targetinfo->symbols[i].ili_lowerbound);
454 chk_block(ilix);
455 } else {
456 /* Optimization - Pass by value for scalar */
457 if (TY_ISSCALAR(DTY(param_dtype)) && (targetinfo->symbols[i].map_type & OMP_TGT_MAPTYPE_IMPLICIT) || isMidnum || isThis ) {
458 iliy = mk_ompaccel_ldsptr(param_sptr);
459 load_dtype = param_dtype;
460 } else {
461 iliy = mk_address(param_sptr);
462 load_dtype = DT_ADDR;
463 }
464 /* Assign args */
465 ilix = mk_ompaccel_store(iliy, load_dtype, nme_args, ad_acon(args_sptr, i * TARGET_PTRSIZE));
466 chk_block(ilix);
467 /* assign args_base */
468 ilix = mk_ompaccel_store(iliy, load_dtype, nme_base, ad_acon(arg_base_sptr, i * TARGET_PTRSIZE));
469 chk_block(ilix);
470 }
471 /* assign size */
472 if(targetinfo->symbols[i].in_map) {
473 ilix = ikmove(targetinfo->symbols[i].ili_length);
474 ilix = mk_ompaccel_mul(ilix, DT_INT8, ad_kconi(size_of(param_dtype)), DT_INT8);
475 name_length = getILIname(targetinfo->symbols[i].ili_length);
476 } else {
477 if(isMidnum)
478 ilix = _tgt_target_fill_size(midnum_sym.host_sym, targetinfo->symbols[i].map_type);
479 else
480 ilix = _tgt_target_fill_size(param_sptr, targetinfo->symbols[i].map_type);
481 }
482 ilix = ad4ili(IL_STKR, ilix, ad_acon(arg_size_sptr, i * TARGET_PTRSIZE), nme_size,
483 TARGET_PTRSIZE == 8 ? MSZ_I8 : MSZ_WORD);
484 chk_block(ilix);
485 }
486 }
487
488 int
ll_make_tgt_target(SPTR outlined_func_sptr,int64_t device_id,SPTR stblk_sptr)489 ll_make_tgt_target(SPTR outlined_func_sptr, int64_t device_id, SPTR stblk_sptr)
490 {
491 SPTR sptr, arg_base_sptr, arg_size_sptr, args_sptr, args_maptypes_sptr;
492 char *name, *rname;
493 OMPACCEL_TINFO *targetinfo;
494 int ili_hostptr;
495
496 rname = SYMNAME(outlined_func_sptr);
497 NEW(name, char, 100);
498
499 targetinfo = ompaccel_tinfo_get(outlined_func_sptr);
500 #if OMP_OFFLOAD_LLVM
501 sptr = init_tgt_target_syms(rname);
502 ili_hostptr = ad_acon(sptr, 0);
503 #endif
504 if (targetinfo->n_symbols == 0) {
505 int locargs[7];
506 DTYPE locarg_types[] = {DT_INT8, DT_ADDR, DT_INT, DT_ADDR,
507 DT_ADDR, DT_ADDR, DT_ADDR};
508 locargs[6] = ad_icon(device_id);
509 locargs[5] = ili_hostptr;
510 locargs[4] = ad_icon(targetinfo->n_symbols);
511 locargs[3] = gen_null_arg();
512 locargs[2] = gen_null_arg();
513 locargs[1] = gen_null_arg();
514 locargs[0] = gen_null_arg();
515 // call the RT
516 int call_ili = mk_tgt_api_call(TGT_API_TARGET, 7, locarg_types, locargs);
517 return call_ili;
518 } else {
519 sprintf(name, "%s_base", rname);
520 arg_base_sptr = make_array_sptr(name, DT_CPTR, targetinfo->n_symbols);
521 sprintf(name, "%s_size", rname);
522 arg_size_sptr = make_array_sptr(name, DT_INT8, targetinfo->n_symbols);
523 sprintf(name, "%s_args", rname);
524 args_sptr = make_array_sptr(name, DT_CPTR, targetinfo->n_symbols);
525 sprintf(name, "%s_type", rname);
526 args_maptypes_sptr = make_array_sptr(name, DT_INT8, targetinfo->n_symbols);
527
528 tgt_target_fill_params(arg_base_sptr, arg_size_sptr, args_sptr,
529 args_maptypes_sptr, targetinfo);
530
531 // prepare argument for tgt target
532 int locargs[7];
533 DTYPE locarg_types[] = {DT_INT8, DT_ADDR, DT_INT, DT_ADDR,
534 DT_ADDR, DT_ADDR, DT_ADDR};
535 locargs[6] = ad_icon(device_id);
536 locargs[5] = ili_hostptr;
537 locargs[4] = ad_icon(targetinfo->n_symbols);
538 locargs[3] = ad_acon(arg_base_sptr, 0);
539 locargs[2] = ad_acon(args_sptr, 0);
540 locargs[1] = ad_acon(arg_size_sptr, 0);
541 locargs[0] = ad_acon(args_maptypes_sptr, 0);
542 #ifdef OMP_OFFLOAD_LLVM
543 change_target_func_smbols(outlined_func_sptr, stblk_sptr);
544 #endif
545 // call the RT
546 int call_ili = mk_tgt_api_call(TGT_API_TARGET, 7, locarg_types, locargs);
547
548 return call_ili;
549 }
550 }
551
552 int
ll_make_tgt_target_teams(SPTR outlined_func_sptr,int64_t device_id,SPTR stblk_sptr,int32_t num_teams,int32_t thread_limit)553 ll_make_tgt_target_teams(SPTR outlined_func_sptr, int64_t device_id,
554 SPTR stblk_sptr, int32_t num_teams,
555 int32_t thread_limit)
556 {
557 SPTR sptr, arg_base_sptr, arg_size_sptr, args_sptr, args_maptypes_sptr;
558 char *name, *rname;
559 OMPACCEL_TINFO *targetinfo = ompaccel_tinfo_get(outlined_func_sptr);
560 int ili_hostptr, nargs = targetinfo->n_symbols;
561 rname = SYMNAME(outlined_func_sptr);
562 NEW(name, char, 100);
563 #if OMP_OFFLOAD_LLVM
564 sptr = init_tgt_target_syms(rname);
565 ili_hostptr = ad_acon(sptr, 0);
566 #endif
567
568 sprintf(name, "%s_base", rname);
569 arg_base_sptr = make_array_sptr(name, DT_CPTR, nargs);
570 sprintf(name, "%s_size", rname);
571 arg_size_sptr = make_array_sptr(name, DT_INT8, nargs);
572 sprintf(name, "%s_args", rname);
573 args_sptr = make_array_sptr(name, DT_CPTR, nargs);
574 sprintf(name, "%s_type", rname);
575 args_maptypes_sptr = make_array_sptr(name, DT_INT8, nargs);
576
577 tgt_target_fill_params(arg_base_sptr, arg_size_sptr, args_sptr,
578 args_maptypes_sptr, targetinfo);
579
580 // prepare argument for tgt target
581 int locargs[9];
582 DTYPE locarg_types[] = {DT_INT8, DT_ADDR, DT_INT, DT_ADDR, DT_ADDR,
583 DT_ADDR, DT_ADDR, DT_INT, DT_INT};
584 locargs[8] = ad_icon(device_id);
585 locargs[7] = ili_hostptr;
586 locargs[6] = ad_icon(nargs);
587 locargs[5] = ad_acon(arg_base_sptr, 0);
588 locargs[4] = ad_acon(args_sptr, 0);
589 locargs[3] = ad_acon(arg_size_sptr, 0);
590 locargs[2] = ad_acon(args_maptypes_sptr, 0);
591 locargs[1] = ad_icon(num_teams);
592 locargs[0] = ad_icon(thread_limit);
593 #ifdef OMP_OFFLOAD_LLVM
594 change_target_func_smbols(outlined_func_sptr, stblk_sptr);
595 #endif
596 // call the RT
597 int call_ili =
598 mk_tgt_api_call(TGT_API_TARGET_TEAMS, 9, locarg_types, locargs);
599
600 return call_ili;
601 }
602
603 int
ll_make_tgt_target_teams_parallel(SPTR outlined_func_sptr,int64_t device_id,SPTR stblk_sptr,int32_t num_teams,int32_t thread_limit,int32_t num_threads,int32_t mode)604 ll_make_tgt_target_teams_parallel(SPTR outlined_func_sptr, int64_t device_id,
605 SPTR stblk_sptr, int32_t num_teams,
606 int32_t thread_limit, int32_t num_threads, int32_t mode)
607 {
608 SPTR sptr, arg_base_sptr, arg_size_sptr, args_sptr, args_maptypes_sptr;
609 char *name, *rname;
610 OMPACCEL_TINFO *targetinfo = ompaccel_tinfo_get(outlined_func_sptr);
611 int ili_hostptr, nargs = targetinfo->n_symbols;
612 rname = SYMNAME(outlined_func_sptr);
613 NEW(name, char, 100);
614 ili_hostptr = ad1ili(IL_ACON, get_acon(outlined_func_sptr, 0));
615
616 sprintf(name, "%s_base", rname);
617 arg_base_sptr = make_array_sptr(name, DT_CPTR, nargs);
618 sprintf(name, "%s_size", rname);
619 arg_size_sptr = make_array_sptr(name, DT_INT8, nargs);
620 sprintf(name, "%s_args", rname);
621 args_sptr = make_array_sptr(name, DT_CPTR, nargs);
622 sprintf(name, "%s_type", rname);
623 args_maptypes_sptr = make_array_sptr(name, DT_INT8, nargs);
624
625 tgt_target_fill_params(arg_base_sptr, arg_size_sptr, args_sptr,
626 args_maptypes_sptr, targetinfo);
627
628 // prepare argument for tgt target
629 int locargs[11];
630 DTYPE locarg_types[] = {DT_INT8, DT_ADDR, DT_INT, DT_ADDR, DT_ADDR,
631 DT_ADDR, DT_ADDR, DT_INT, DT_INT, DT_INT, DT_INT};
632 locargs[10] = ad_icon(device_id);
633 locargs[9] = ili_hostptr;
634 locargs[8] = ad_icon(nargs);
635 locargs[7] = ad_acon(arg_base_sptr, 0);
636 locargs[6] = ad_acon(args_sptr, 0);
637 locargs[5] = ad_acon(arg_size_sptr, 0);
638 locargs[4] = ad_acon(args_maptypes_sptr, 0);
639 locargs[3] = num_teams;
640 locargs[2] = thread_limit;
641 locargs[1] = num_threads;
642 locargs[0] = ad_icon(mode);
643
644 // call the RT
645 int call_ili =
646 mk_tgt_api_call(TGT_API_TARGET_TEAMS_PARALLEL, 11, locarg_types, locargs);
647
648 return call_ili;
649 }
650
651 int
ll_make_tgt_target_data_begin(int device_id,OMPACCEL_TINFO * targetinfo)652 ll_make_tgt_target_data_begin(int device_id, OMPACCEL_TINFO *targetinfo)
653 {
654 int call_ili, nargs;
655 SPTR arg_base_sptr, args_sptr, arg_size_sptr, args_maptypes_sptr;
656 char name[12];
657
658 int locargs[6];
659 DTYPE locarg_types[] = {DT_INT8, DT_INT, DT_ADDR, DT_ADDR, DT_ADDR, DT_ADDR};
660
661 if (targetinfo == NULL) {
662 interr("Map item list is not found", 0, ERR_Fatal);
663 }
664 nargs = targetinfo->n_symbols;
665
666 sprintf(name, "edata%d_base", dataregion);
667 arg_base_sptr = make_array_sptr(name, DT_CPTR, nargs);
668 sprintf(name, "edata%d_size", dataregion);
669 arg_size_sptr = make_array_sptr(name, DT_INT8, nargs);
670 sprintf(name, "edata%d_args", dataregion);
671 args_sptr = make_array_sptr(name, DT_CPTR, nargs);
672 sprintf(name, "edata%d_type", dataregion);
673 args_maptypes_sptr = make_array_sptr(name, DT_INT8, nargs);
674 dataregion++;
675
676 tgt_target_fill_params(arg_base_sptr, arg_size_sptr, args_sptr,
677 args_maptypes_sptr, targetinfo);
678
679 locargs[5] = ad_icon(device_id);
680 locargs[4] = ad_icon(nargs);
681 locargs[3] = ad_acon(arg_base_sptr, 0);
682 locargs[2] = ad_acon(args_sptr, 0);
683 locargs[1] = ad_acon(arg_size_sptr, 0);
684 locargs[0] = ad_acon(args_maptypes_sptr, 0);
685
686 // call the RT
687 call_ili =
688 mk_tgt_api_call(TGT_API_TARGET_DATA_BEGIN, 6, locarg_types, locargs);
689
690 return call_ili;
691 }
692
693 static int
_tgt_target_fill_targetdata(int device_id,OMPACCEL_TINFO * targetinfo,int tgt_api)694 _tgt_target_fill_targetdata(int device_id, OMPACCEL_TINFO *targetinfo, int tgt_api)
695 {
696 int call_ili, nargs;
697 SPTR arg_base_sptr, args_sptr, arg_size_sptr, args_maptypes_sptr;
698 char name[12];
699
700 int locargs[6];
701 DTYPE
702 locarg_types[] = {DT_INT8, DT_INT, DT_ADDR, DT_ADDR, DT_ADDR, DT_ADDR};
703
704 if (targetinfo == NULL) {
705 interr("Map item list is not found", 0, ERR_Fatal);
706 }
707
708 nargs = targetinfo->n_symbols;
709
710 sprintf(name, "xdata%d_base", dataregion);
711 arg_base_sptr = make_array_sptr(name, DT_CPTR, nargs);
712 sprintf(name, "xdata%d_size", dataregion);
713 arg_size_sptr = make_array_sptr(name, DT_INT8, nargs);
714 sprintf(name, "xdata%d_args", dataregion);
715 args_sptr = make_array_sptr(name, DT_CPTR, nargs);
716 sprintf(name, "xdata%d_type", dataregion);
717 args_maptypes_sptr = make_array_sptr(name, DT_INT8, nargs);
718 dataregion++;
719
720 tgt_target_fill_params(arg_base_sptr, arg_size_sptr, args_sptr,
721 args_maptypes_sptr, targetinfo);
722
723 locargs[5] = ad_icon(device_id);
724 locargs[4] = ad_icon(nargs);
725 locargs[3] = ad_acon(arg_base_sptr, 0);
726 locargs[2] = ad_acon(args_sptr, 0);
727 locargs[1] = ad_acon(arg_size_sptr, 0);
728 locargs[0] = ad_acon(args_maptypes_sptr, 0);
729
730 // call the RT
731 call_ili = mk_tgt_api_call(tgt_api, 6, locarg_types, locargs);
732
733 return call_ili;
734 }
735
736 int
ll_make_tgt_targetupdate_end(int device_id,OMPACCEL_TINFO * targetinfo)737 ll_make_tgt_targetupdate_end(int device_id, OMPACCEL_TINFO *targetinfo)
738 {
739 return _tgt_target_fill_targetdata(device_id, targetinfo, TGT_API_TARGETUPDATE);
740 }
741 int
ll_make_tgt_target_data_end(int device_id,OMPACCEL_TINFO * targetinfo)742 ll_make_tgt_target_data_end(int device_id, OMPACCEL_TINFO *targetinfo)
743 {
744 return _tgt_target_fill_targetdata(device_id, targetinfo, TGT_API_TARGET_DATA_END);
745 }
746 #endif
747
748 #ifdef OMP_OFFLOAD_LLVM
749 static void
change_target_func_smbols(int outlined_func_sptr,int stblk_sptr)750 change_target_func_smbols(int outlined_func_sptr, int stblk_sptr)
751 {
752 int dpdsc, paramct, i, j, block_sptr, target_sptr;
753 const LLUplevel *uplevel;
754
755 // perhaps it is an empty target region
756 if (PARSYMSG(stblk_sptr) == 0) {
757 return;
758 }
759
760 uplevel = llmp_get_uplevel(stblk_sptr);
761 paramct = PARAMCTG(outlined_func_sptr);
762
763 for (i = 0; i < uplevel->vals_count; ++i) {
764 block_sptr = uplevel->vals[i];
765 if (!block_sptr)
766 continue;
767 dpdsc = DPDSCG(outlined_func_sptr);
768 for (j = 0; j < paramct; ++j, ++dpdsc) {
769 target_sptr = aux.dpdsc_base[dpdsc];
770 if (strncmp(&SYMNAME(target_sptr)[4], SYMNAME(block_sptr),
771 strlen(SYMNAME(block_sptr))) == 0) {
772 uplevel->vals[i] = target_sptr;
773 break;
774 }
775 }
776 }
777 }
778 DTYPE
ll_make_struct(int count,char * name,TGT_ST_TYPE * meminfo,ISZ_T sz)779 ll_make_struct(int count, char *name, TGT_ST_TYPE *meminfo, ISZ_T sz)
780 {
781 DTYPE dtype;
782 int i;
783 SPTR mem, tag, prev_mem, first_mem;
784 char sname[MXIDLEN];
785
786 tag = SPTR_NULL;
787 dtype = cg_get_type(6, TY_STRUCT, NOSYM);
788 if (name) {
789 sprintf(sname, "%s", name);
790 tag = getsymbol(sname);
791 DTYPEP(tag, dtype);
792 OMPACCSTRUCTP(tag, 1);
793 }
794
795 prev_mem = first_mem = SPTR_NULL;
796 for (i = 0; i < count; ++i) {
797 mem = (SPTR)addnewsym(meminfo[i].name); // ???
798 STYPEP(mem, ST_MEMBER);
799 PAROFFSETP(mem, meminfo[i].psptr);
800 DTYPEP(mem, meminfo[i].dtype);
801 if (prev_mem > 0)
802 SYMLKP(prev_mem, mem);
803 SYMLKP(mem, NOSYM);
804 PSMEMP(mem, mem);
805 VARIANTP(mem, prev_mem);
806 CCSYMP(mem, 1);
807 ADDRESSP(mem, sz);
808 SCP(mem, SC_NONE);
809 if (first_mem == 0)
810 first_mem = mem;
811 sz += size_of(meminfo[i].dtype);
812 prev_mem = mem;
813 }
814
815 DTySetAlgTy(dtype, first_mem, sz, tag, 0, 0);
816 return dtype;
817 }
818
819 /*
820 * struct __tgt_offload_entry { void*, char*, i64, i32, i32 }
821 */
822 DTYPE
ll_make_tgt_offload_entry(char * name)823 ll_make_tgt_offload_entry(char *name)
824 {
825 TGT_ST_TYPE meminfo[] = {{"addr", DT_ADDR, 0, 0},
826 {"name", DT_ADDR, 0, 0},
827 {"size", DT_INT8, 0, 0},
828 {"flags", DT_INT, 0, 0},
829 {"reserved", DT_INT, 0, 0}};
830
831 return ll_make_struct(5, name, meminfo, 0);
832 }
833
834 /*
835 * struct __tgt_offload_entry { void*, void*, __tgt_offload_entry
836 * *,__tgt_offload_entry * }
837 */
838 DTYPE
ll_make_tgt_device_image(char * name,DTYPE entrytype)839 ll_make_tgt_device_image(char *name, DTYPE entrytype)
840 {
841 DTYPE dtype1, dtype2;
842 dtype1 = get_type(2, TY_PTR, DT_BINT);
843 dtype2 = get_type(2, TY_PTR, entrytype);
844 TGT_ST_TYPE meminfo[] = {
845 {"ImageStart", dtype1, 0, 0},
846 {"ImageEnd", dtype1, 0, 0},
847 {"EntriesBegin", dtype2, 0, 0},
848 {"EntriesEnd", dtype2, 0, 0},
849 };
850
851 return ll_make_struct(4, name, meminfo, 0);
852 }
853
854 /*
855 * struct __tgt_bin_desc { i32, __tgt_device_image*, __tgt_offload_entry
856 * *,__tgt_offload_entry * }
857 */
858 DTYPE
ll_make_tgt_bin_descriptor(char * name,DTYPE entrytype,DTYPE deviceimagetype)859 ll_make_tgt_bin_descriptor(char *name, DTYPE entrytype, DTYPE deviceimagetype)
860 {
861 DTYPE dtype1, dtype2;
862 dtype1 = get_type(2, TY_PTR, entrytype);
863 dtype2 = get_type(2, TY_PTR, deviceimagetype);
864 TGT_ST_TYPE meminfo[] = {
865 {"NumDeviceImages", DT_INT8, 0, 0},
866 {"DeviceImages", dtype2, 0, 0},
867 {"HostEntriesBegin", dtype1, 0, 0},
868 {"HostEntriesEnd", dtype1, 0, 0},
869 };
870
871 return ll_make_struct(4, name, meminfo, 0);
872 }
873
874 static SPTR
init_tgt_target_syms(const char * kernelname)875 init_tgt_target_syms(const char *kernelname)
876 {
877 SPTR eptr1, eptr2, eptr3;
878 size_t size;
879 char *kernelname_, *sname_region, *sname_entry;
880 size = 100 + strlen(kernelname);
881
882 /* regionId */
883 NEW(sname_region, char, size);
884 strcpy(sname_region, ".openmp.offload.region.");
885 strcat(sname_region, kernelname);
886 eptr1 = (SPTR)addnewsym(sname_region);
887 DTYPEP(eptr1, DT_BINT);
888 SCP(eptr1, SC_EXTERN);
889 STYPEP(eptr1, ST_VAR);
890 // DINITP(eptr1,1);
891 SYMLKP(eptr1, gbl.consts);
892 gbl.consts = eptr1;
893 OMPACCSTRUCTP(eptr1, 1);
894
895 // device functions gets "_" in the end.
896 NEW(kernelname_, char, size);
897 sprintf(kernelname_, "%s_\00", kernelname);
898 eptr2 = getstring(kernelname_, strlen(kernelname) + 1);
899 DINITP(eptr2, 1);
900
901 NEW(sname_entry, char, size);
902 strcpy(sname_entry, ".openmp.offload.entry.");
903 strcat(sname_entry, kernelname);
904 eptr3 = (SPTR)addnewsym(sname_entry);
905 DTYPEP(eptr3, tgt_offload_entry_type);
906 SCP(eptr3, SC_EXTERN);
907 STYPEP(eptr3, ST_STRUCT);
908 DINITP(eptr3, 1);
909 SECTP(eptr3, 1);
910 WEAKP(eptr3, 1);
911 OMPACCSTRUCTP(eptr3, 1);
912
913 dinit_put(DINIT_SECT, OMP_OFFLOAD_SEC);
914 dinit_put(DINIT_LOC, (ISZ_T)eptr3);
915 dinit_put(DINIT_OFFSET, 0);
916 dinit_put(DINIT_LABEL, eptr1);
917 dinit_put(DINIT_OFFSET, 8);
918 dinit_put(DINIT_LABEL, eptr2);
919 gbl.saddr = 16;
920
921 return eptr1;
922 }
923
924 void
init_tgt_register_syms()925 init_tgt_register_syms()
926 {
927 SPTR tptr1, tptr2, tptr3, tptr4;
928
929 tptr1 = (SPTR)addnewsym(".omp_offloading.entries_begin");
930 DTYPEP(tptr1, tgt_offload_entry_type);
931 SCP(tptr1, SC_EXTERN);
932 DCLDP(tptr1, 1);
933 STYPEP(tptr1, ST_VAR);
934 SYMLKP(tptr1, gbl.consts);
935 gbl.consts = tptr1;
936 OMPACCRTP(tptr1, 1);
937
938 tptr2 = (SPTR)addnewsym(".omp_offloading.entries_end");
939 DTYPEP(tptr2, tgt_offload_entry_type);
940 SCP(tptr2, SC_EXTERN);
941 DCLDP(tptr2, 1);
942 STYPEP(tptr2, ST_VAR);
943 SYMLKP(tptr2, gbl.consts);
944 gbl.consts = tptr2;
945 OMPACCRTP(tptr2, 1);
946
947 tptr3 = (SPTR)addnewsym(".omp_offloading.img_start.nvptx64-nvidia-cuda");
948 DTYPEP(tptr3, DT_BINT);
949 SCP(tptr3, SC_EXTERN);
950 STYPEP(tptr3, ST_VAR);
951 SYMLKP(tptr3, gbl.consts);
952 gbl.consts = tptr3;
953 OMPACCRTP(tptr3, 1);
954
955 tptr4 = (SPTR)addnewsym(".omp_offloading.img_end.nvptx64-nvidia-cuda");
956 DTYPEP(tptr4, DT_BINT);
957 SCP(tptr4, SC_EXTERN);
958 DCLDP(tptr4, 1);
959 STYPEP(tptr4, ST_VAR);
960 SYMLKP(tptr4, gbl.consts);
961 gbl.consts = tptr4;
962 OMPACCRTP(tptr4, 1);
963 }
964
965 int
ll_make_tgt_register_lib()966 ll_make_tgt_register_lib()
967 {
968 SPTR sptr;
969 DTYPE dtype_bindesc, dtype_entry, dtype_devimage, dtype_pofbindesc;
970
971 dtype_entry = tgt_offload_entry_type;
972 dtype_devimage = ll_make_tgt_device_image("__tgt_device_image", dtype_entry);
973 dtype_bindesc =
974 ll_make_tgt_bin_descriptor("__tgt_bin_desc", dtype_entry, dtype_devimage);
975
976 sptr = (SPTR)addnewsym(".omp_offloading.descriptor");
977 STYPEP(sptr, ST_STRUCT);
978 SCP(sptr, SC_EXTERN);
979 REFP(sptr, 1);
980 DTYPEP(sptr, dtype_bindesc);
981
982 dtype_pofbindesc = get_type(2, TY_PTR, dtype_bindesc);
983 int args[1];
984 DTYPE arg_types[1] = {dtype_pofbindesc};
985 args[0] = ad_acon(sptr, 0);
986 return mk_tgt_api_call(TGT_API_REGISTER_LIB, 1, arg_types, args);
987 }
988
989 int
ll_make_tgt_register_lib2()990 ll_make_tgt_register_lib2()
991 {
992 SPTR tptr1, tptr2, tptr3, tptr4, tptr;
993 SPTR sptr, sptr2;
994 int i, ilix, nme, offset, addr;
995 DTYPE dtype_entry, dtype_devimage, dtype_bindesc, dtype_pofbindesc;
996
997 init_tgt_register_syms();
998
999 for (tptr = gbl.consts; tptr > NOSYM; tptr = SYMLKG(tptr)) {
1000 if (OMPACCRTG(tptr)) {
1001 tptr4 = tptr;
1002 tptr3 = SYMLKG(tptr4);
1003 tptr2 = SYMLKG(tptr3);
1004 tptr1 = SYMLKG(tptr2);
1005 break;
1006 }
1007 }
1008 assert(!tptr || !tptr2 || !tptr3 || !tptr4,
1009 "OpenMP Offload structures are not found.", 0, ERR_Fatal);
1010
1011 dtype_entry =
1012 tgt_offload_entry_type; // ll_make_tgt_offload_entry("__tgt_offload_entry");
1013 dtype_devimage = ll_make_tgt_device_image("__tgt_device_image", dtype_entry);
1014 dtype_bindesc =
1015 ll_make_tgt_bin_descriptor("__tgt_bin_desc", dtype_entry, dtype_devimage);
1016
1017 sptr = (SPTR)addnewsym(".omp_offloading.device_images");
1018 STYPEP(sptr, ST_STRUCT);
1019 SCP(sptr, SC_LOCAL);
1020 REFP(sptr, 1);
1021 DTYPEP(sptr, dtype_devimage);
1022 nme = addnme(NT_VAR, sptr, 0, 0);
1023
1024 offset = 0;
1025
1026 i = DTyAlgTyMember(dtype_devimage);
1027 addr = ad_acon(sptr, offset);
1028 ilix =
1029 ad4ili(IL_ST, ad_acon(tptr3, 0), addr,
1030 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1031 offset += size_of(DTYPEG(i));
1032 chk_block(ilix);
1033
1034 i = SYMLKG(i);
1035 addr = ad_acon(sptr, offset);
1036 ilix =
1037 ad4ili(IL_ST, ad_acon(tptr4, 0), addr,
1038 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1039 offset += size_of(DTYPEG(i));
1040 chk_block(ilix);
1041
1042 i = SYMLKG(i);
1043 addr = ad_acon(sptr, offset);
1044 ilix =
1045 ad4ili(IL_ST, ad_acon(tptr1, 0), addr,
1046 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1047 offset += size_of(DTYPEG(i));
1048 chk_block(ilix);
1049
1050 i = SYMLKG(i);
1051 addr = ad_acon(sptr, offset);
1052 ilix =
1053 ad4ili(IL_ST, ad_acon(tptr2, 0), addr,
1054 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1055 chk_block(ilix);
1056
1057 sptr2 = (SPTR)addnewsym(".omp_offloading.descriptor");
1058 STYPEP(sptr2, ST_STRUCT);
1059 SCP(sptr2, SC_LOCAL);
1060 REFP(sptr2, 1);
1061 DTYPEP(sptr2, dtype_bindesc);
1062 nme = addnme(NT_VAR, sptr2, 0, 0);
1063
1064 offset = 0;
1065 i = DTyAlgTyMember(dtype_bindesc);
1066 addr = ad_acon(sptr2, offset);
1067 ilix =
1068 ad4ili(IL_ST, ad_icon(1), addr, addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0),
1069 mem_size(DTY(DTYPEG(i))));
1070 offset += size_of(DTYPEG(i));
1071 chk_block(ilix);
1072 i = SYMLKG(i);
1073 addr = ad_acon(sptr2, offset);
1074 ilix =
1075 ad4ili(IL_ST, ad_acon(sptr, 0), addr,
1076 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1077 offset += size_of(DTYPEG(i));
1078 chk_block(ilix);
1079 i = SYMLKG(i);
1080 addr = ad_acon(sptr2, offset);
1081 ilix =
1082 ad4ili(IL_ST, ad_acon(tptr1, 0), addr,
1083 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1084 offset += size_of(DTYPEG(i));
1085 chk_block(ilix);
1086 i = SYMLKG(i);
1087 addr = ad_acon(sptr2, offset);
1088 ilix =
1089 ad4ili(IL_ST, ad_acon(tptr2, 0), addr,
1090 addnme(NT_MEM, (SPTR)PSMEMG(i), nme, 0), mem_size(DTY(DTYPEG(i))));
1091 offset += size_of(DTYPEG(i));
1092 chk_block(ilix);
1093
1094 dtype_pofbindesc = get_type(2, TY_PTR, dtype_bindesc);
1095 int args[1];
1096 DTYPE arg_types[1] = {dtype_pofbindesc};
1097 args[0] = ad_acon(sptr2, 0);
1098 return mk_tgt_api_call(TGT_API_REGISTER_LIB, 1, arg_types, args);
1099 }
1100
1101 void
init_tgtutil()1102 init_tgtutil()
1103 {
1104 tgt_offload_entry_type = ll_make_tgt_offload_entry("__tgt_offload_entry_");
1105 }
1106
1107 #endif
1108