1 /* 2 * Copyright (c) 2015-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 #ifndef LLMPUTIL_H_ 19 #define LLMPUTIL_H_ 20 21 /** \file 22 * \brief OpenMP utility routines for LLVM compilers 23 */ 24 25 #include "gbldefs.h" 26 #include "global.h" 27 #include "symtab.h" 28 29 /** Uplevel data structure containing a list of shared variables for the region 30 * nest that this uplevel belongs to. The shared variables in this structure 31 * are represented as a list of unique sptrs. 32 */ 33 typedef struct { 34 int *vals; /* Array containing shared var sptrs */ 35 int vals_size; /* Total allocated slots in vals */ 36 int vals_count; /* Traditionally "available" or vals_avl */ 37 DTYPE dtype; ///< The true dtype containing fields and their offsets 38 SPTR parent; /* sptr of its parent */ 39 /* TODO: Consider using a hashset to speed-unique lookup */ 40 } LLUplevel; 41 42 /** First private variable: 43 * This information is necessary to generate code that allows a particular task 44 * to know which variables are stored in its allocated memory (task memory). 45 * First privates for the task have to be stored in that memory. 46 */ 47 typedef struct _llprivate_t { 48 int shared_sptr; /**< Represents the caller's copy */ 49 int private_sptr; /**< Represents the callee's copy (local) */ 50 } LLFirstPrivate; 51 52 /// Task data structure containing a list of private variables for the task. 53 typedef struct { 54 int scope_sptr; /**< Outlined task's scope sptr (BMPSCOPE ST_BLOCK) */ 55 int task_sptr; /**< Outlined function representing the task */ 56 LLFirstPrivate *privs; /**< Array of private sptrs for this task */ 57 int privs_count; 58 int privs_size; 59 int actual_size; /**< Bytes in task: First priv size + base task size */ 60 } LLTask; 61 62 /// Data attributes for each data reference used in an OpenMP target region. 63 typedef enum { 64 // No flags 65 OMP_TGT_MAPTYPE_NONE = 0x000, 66 // copy data from host to device 67 OMP_TGT_MAPTYPE_TO = 0x001, 68 // copy data from device to host 69 OMP_TGT_MAPTYPE_FROM = 0x002, 70 // copy regardless of the reference count 71 OMP_TGT_MAPTYPE_ALWAYS = 0x004, 72 // force unmapping of data 73 OMP_TGT_MAPTYPE_DELETE = 0x008, 74 // map the pointer as well as the pointee 75 OMP_TGT_MAPTYPE_PTR_AND_OBJ = 0x010, 76 // pass device base address to kernel 77 OMP_TGT_MAPTYPE_TARGET_PARAM = 0x020, 78 // return base device address of mapped data 79 OMP_TGT_MAPTYPE_RETURN_PARAM = 0x040, 80 // private variable - not mapped 81 OMP_TGT_MAPTYPE_PRIVATE = 0x080, 82 // copy by value - not mapped 83 OMP_TGT_MAPTYPE_LITERAL = 0x100, 84 // mapping is implicit 85 OMP_TGT_MAPTYPE_IMPLICIT = 0x200, 86 // member of struct, member given by 4 MSBs - 1 87 OMP_TGT_MAPTYPE_MEMBER_OF = 0xffff000000000000 88 } tgt_map_type; 89 90 91 /* The modes of target related regions. */ 92 typedef enum { 93 mode_none_target, 94 mode_target, 95 mode_target_teams, 96 mode_target_teams_distribute, 97 mode_target_teams_distribute_simd, 98 mode_target_teams_distribute_parallel_for, 99 mode_target_teams_distribute_parallel_for_simd, 100 mode_target_parallel, 101 mode_target_parallel_for, 102 mode_target_parallel_for_simd, 103 mode_target_data_enter_region, 104 mode_target_data_exit_region, 105 mode_target_data_region, 106 mode_outlinedfunc_teams, 107 mode_outlinedfunc_parallel, 108 mode_targetupdate_begin, 109 mode_targetupdate_end, 110 } OMP_TARGET_MODE; 111 112 bool is_omp_mode_target(OMP_TARGET_MODE mode); 113 114 /* The name of the modes of target related regions. */ 115 static const char *omp_target_mode_names[] = { 116 "None target", 117 "target", 118 "target teams", 119 "target teams distribute", 120 "target teams distribute simd", 121 "target teams distribute parallel for", 122 "target teams distribute parallel for simd", 123 "target parallel", 124 "target parallel for", 125 "target parallel for simd", 126 "target data enter", 127 "target data exit", 128 "target data", 129 "outlined teams region", 130 "outlined parallel region", 131 "target update begin", 132 "target update end" }; 133 134 135 /* Obtain a previously created task object, where scope_sptr is the BMPSCOPE 136 * scope sptr containing the task. 137 */ 138 extern LLTask *llmp_get_task(int scope_sptr); 139 140 /* Return the task base size without any private values being stored. */ 141 extern int llmp_task_get_base_task_size(void); 142 143 /* Return the task's total size including task metadata and priv vars */ 144 extern int llmp_task_get_size(LLTask *task); 145 146 /* Set the task function sptr */ 147 extern void llmp_task_set_fnsptr(LLTask *task, int task_sptr); 148 149 /* Return a task a object associated to 'task_sptr' */ 150 extern LLTask *llmp_task_get_by_fnsptr(int task_sptr); 151 152 /* Returns the sptr of the 'private' (local to the callee) copy of the 153 * private variable represented by 'sptr'. 154 */ 155 extern int llmp_task_get_private(const LLTask *task, int sptr, int incl); 156 157 /// \brief Uniquely add a shared variable 158 int llmp_add_shared_var(LLUplevel *up, int shared_sptr); 159 160 /// \brief Return a new key (index) into our table of all uplevels 161 int llmp_get_next_key(void); 162 163 /** 164 \brief ... 165 */ 166 int llmp_task_add_loopvar(LLTask *task, int num, DTYPE dtype); 167 168 /** 169 \brief Add a private sptr to the task object. 170 priv: sptr to the private copy of the private variable. 171 ADDRESSP is called to set the offset to the kmpc task 172 object where this private data will live during program 173 execution. 174 / 175 */ 176 int llmp_task_add_private(LLTask *task, int shared_sptr, SPTR private_sptr); 177 178 /** 179 \brief ... 180 */ 181 int llmp_task_get_base_task_size(void); 182 183 /** 184 \brief ... 185 */ 186 int llmp_task_get_private(const LLTask *task, int sptr, int encl); 187 188 /** 189 \brief ... 190 */ 191 INT llmp_task_get_privoff(int sptr, const LLTask *task); 192 193 /** 194 \brief ... 195 */ 196 int llmp_task_get_size(LLTask *task); 197 198 /** 199 \brief ... 200 */ 201 int llmp_uplevel_has_parent(int uplevel); 202 203 /** 204 \brief Create task object that can be searched for later using \p scope_sptr 205 \param scope_sptr ... 206 */ 207 LLTask *llmp_create_task(int scope_sptr); 208 209 /** 210 \brief ... 211 */ 212 LLTask *llmp_get_task(int scope_sptr); 213 214 /** 215 \brief ... 216 */ 217 LLTask *llmp_task_get_by_fnsptr(int task_sptr); 218 219 /// \brief Retrieve an LLUplevel instance by key 220 LLUplevel *llmp_create_uplevel_bykey(int key); 221 222 /** 223 \brief Create an LLUplevel instance 224 \param stblock_sptr Block where this region nest begins. 225 This is used as a key into the global list of all uplevels. 226 */ 227 LLUplevel *llmp_create_uplevel(int uplevel_sptr); 228 229 /// \brief Obtain a previously created uplevel 230 LLUplevel *llmp_get_uplevel(int uplevel_sptr); 231 232 /** Return an uplevel pointer if it has an entry in uplevel table 233 or NULL if there is no entry. 234 */ 235 LLUplevel *llmp_has_uplevel(int uplevel_sptr); 236 237 /** 238 \brief ... 239 */ 240 void dump_all_uplevel(void); 241 242 /** 243 \brief ... 244 */ 245 void dump_uplevel(LLUplevel *up); 246 247 /** 248 \brief ... 249 */ 250 void llmp_add_shared_var_charlen(LLUplevel *up, int shared_sptr); 251 252 /** 253 \brief ... 254 */ 255 void llmp_append_uplevel(int from_sptr, int to_sptr); 256 257 /** 258 \brief ... 259 */ 260 void llmp_concur_add_shared_var(int uplevel_sptr, int shared_sptr); 261 262 /** 263 \brief ... 264 */ 265 void llmp_reset_uplevel(void); 266 267 /** 268 \brief Return symbol pointer of its parent. 269 */ 270 SPTR llmp_get_parent_sptr(SPTR); 271 272 /** 273 \brief Create a task object if it does not already exist for \p scope_sptr 274 Add a private sptr to the task object. shared, priv: See 275 llmp_task_add_private 276 */ 277 void llmp_task_add(int scope_sptr, int shared_sptr, SPTR private_sptr); 278 279 /** 280 \brief ... 281 */ 282 void llmp_task_set_fnsptr(LLTask *task, int task_sptr); 283 284 /** 285 \brief Set the dtype (actual struct of member pointers) 286 */ 287 void llmp_uplevel_set_dtype(LLUplevel *up, DTYPE dtype); 288 289 /** 290 \brief Set uplevel parent field. 291 */ 292 void llmp_uplevel_set_parent(SPTR uplevel_sptr, SPTR parent_sptr); 293 294 /** 295 \brief Return outermost uplevel of current region. 296 */ 297 LLUplevel *llmp_outermost_uplevel(SPTR child); 298 299 /** 300 \brief Return uplevel pointer of current uplevel's parent 301 */ 302 LLUplevel *llmp_parent_uplevel(SPTR child); 303 304 #endif /* LLMPUTIL_H_ */ 305