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