blob: cf165df9c2da0ed89dc7166817179fbf20e09e2f [file] [log] [blame]
Jim Cownie33f7b242014-04-09 15:40:23 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.txt for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "offload_table.h"
12#include "offload_common.h"
13
14#if !HOST_LIBRARY
15// Predefined offload entries
16extern void omp_set_num_threads_lrb(void*);
17extern void omp_get_max_threads_lrb(void*);
18extern void omp_get_num_procs_lrb(void*);
19extern void omp_set_dynamic_lrb(void*);
20extern void omp_get_dynamic_lrb(void*);
21extern void omp_set_nested_lrb(void*);
22extern void omp_get_nested_lrb(void*);
23extern void omp_set_schedule_lrb(void*);
24extern void omp_get_schedule_lrb(void*);
25
26extern void omp_init_lock_lrb(void*);
27extern void omp_destroy_lock_lrb(void*);
28extern void omp_set_lock_lrb(void*);
29extern void omp_unset_lock_lrb(void*);
30extern void omp_test_lock_lrb(void*);
31
32extern void omp_init_nest_lock_lrb(void*);
33extern void omp_destroy_nest_lock_lrb(void*);
34extern void omp_set_nest_lock_lrb(void*);
35extern void omp_unset_nest_lock_lrb(void*);
36extern void omp_test_nest_lock_lrb(void*);
37
38extern void kmp_set_stacksize_lrb(void*);
39extern void kmp_get_stacksize_lrb(void*);
40extern void kmp_set_stacksize_s_lrb(void*);
41extern void kmp_get_stacksize_s_lrb(void*);
42extern void kmp_set_blocktime_lrb(void*);
43extern void kmp_get_blocktime_lrb(void*);
44extern void kmp_set_library_serial_lrb(void*);
45extern void kmp_set_library_turnaround_lrb(void*);
46extern void kmp_set_library_throughput_lrb(void*);
47extern void kmp_set_library_lrb(void*);
48extern void kmp_get_library_lrb(void*);
49extern void kmp_set_defaults_lrb(void*);
50
51extern void kmp_create_affinity_mask_lrb(void*);
52extern void kmp_destroy_affinity_mask_lrb(void*);
53extern void kmp_set_affinity_lrb(void*);
54extern void kmp_get_affinity_lrb(void*);
55extern void kmp_get_affinity_max_proc_lrb(void*);
56extern void kmp_set_affinity_mask_proc_lrb(void*);
57extern void kmp_unset_affinity_mask_proc_lrb(void*);
58extern void kmp_get_affinity_mask_proc_lrb(void*);
59
60// Predefined entries on the target side
61static FuncTable::Entry predefined_entries[] = {
62 "omp_set_num_threads_target",
63 (void*) &omp_set_num_threads_lrb,
64 "omp_get_max_threads_target",
65 (void*) &omp_get_max_threads_lrb,
66 "omp_get_num_procs_target",
67 (void*) &omp_get_num_procs_lrb,
68 "omp_set_dynamic_target",
69 (void*) &omp_set_dynamic_lrb,
70 "omp_get_dynamic_target",
71 (void*) &omp_get_dynamic_lrb,
72 "omp_set_nested_target",
73 (void*) &omp_set_nested_lrb,
74 "omp_get_nested_target",
75 (void*) &omp_get_nested_lrb,
76 "omp_set_schedule_target",
77 (void*) &omp_set_schedule_lrb,
78 "omp_get_schedule_target",
79 (void*) &omp_get_schedule_lrb,
80
81 "omp_init_lock_target",
82 (void*) &omp_init_lock_lrb,
83 "omp_destroy_lock_target",
84 (void*) &omp_destroy_lock_lrb,
85 "omp_set_lock_target",
86 (void*) &omp_set_lock_lrb,
87 "omp_unset_lock_target",
88 (void*) &omp_unset_lock_lrb,
89 "omp_test_lock_target",
90 (void*) &omp_test_lock_lrb,
91
92 "omp_init_nest_lock_target",
93 (void*) &omp_init_nest_lock_lrb,
94 "omp_destroy_nest_lock_target",
95 (void*) &omp_destroy_nest_lock_lrb,
96 "omp_set_nest_lock_target",
97 (void*) &omp_set_nest_lock_lrb,
98 "omp_unset_nest_lock_target",
99 (void*) &omp_unset_nest_lock_lrb,
100 "omp_test_nest_lock_target",
101 (void*) &omp_test_nest_lock_lrb,
102
103 "kmp_set_stacksize_target",
104 (void*) &kmp_set_stacksize_lrb,
105 "kmp_get_stacksize_target",
106 (void*) &kmp_get_stacksize_lrb,
107 "kmp_set_stacksize_s_target",
108 (void*) &kmp_set_stacksize_s_lrb,
109 "kmp_get_stacksize_s_target",
110 (void*) &kmp_get_stacksize_s_lrb,
111 "kmp_set_blocktime_target",
112 (void*) &kmp_set_blocktime_lrb,
113 "kmp_get_blocktime_target",
114 (void*) &kmp_get_blocktime_lrb,
115 "kmp_set_library_serial_target",
116 (void*) &kmp_set_library_serial_lrb,
117 "kmp_set_library_turnaround_target",
118 (void*) &kmp_set_library_turnaround_lrb,
119 "kmp_set_library_throughput_target",
120 (void*) &kmp_set_library_throughput_lrb,
121 "kmp_set_library_target",
122 (void*) &kmp_set_library_lrb,
123 "kmp_get_library_target",
124 (void*) &kmp_get_library_lrb,
125 "kmp_set_defaults_target",
126 (void*) &kmp_set_defaults_lrb,
127
128 "kmp_create_affinity_mask_target",
129 (void*) &kmp_create_affinity_mask_lrb,
130 "kmp_destroy_affinity_mask_target",
131 (void*) &kmp_destroy_affinity_mask_lrb,
132 "kmp_set_affinity_target",
133 (void*) &kmp_set_affinity_lrb,
134 "kmp_get_affinity_target",
135 (void*) &kmp_get_affinity_lrb,
136 "kmp_get_affinity_max_proc_target",
137 (void*) &kmp_get_affinity_max_proc_lrb,
138 "kmp_set_affinity_mask_proc_target",
139 (void*) &kmp_set_affinity_mask_proc_lrb,
140 "kmp_unset_affinity_mask_proc_target",
141 (void*) &kmp_unset_affinity_mask_proc_lrb,
142 "kmp_get_affinity_mask_proc_target",
143 (void*) &kmp_get_affinity_mask_proc_lrb,
144
145 (const char*) -1,
146 (void*) -1
147};
148
149static FuncList::Node predefined_table = {
150 { predefined_entries, -1 },
151 0, 0
152};
153
154// Entry table
155FuncList __offload_entries(&predefined_table);
156#else
157FuncList __offload_entries;
158#endif // !HOST_LIBRARY
159
160// Function table. No predefined entries.
161FuncList __offload_funcs;
162
163// Var table
164VarList __offload_vars;
165
166// Given the function name returns the associtated function pointer
167const void* FuncList::find_addr(const char *name)
168{
169 const void* func = 0;
170
171 m_lock.lock();
172
173 for (Node *n = m_head; n != 0; n = n->next) {
174 for (const Table::Entry *e = n->table.entries;
175 e->name != (const char*) -1; e++) {
176 if (e->name != 0 && strcmp(e->name, name) == 0) {
177 func = e->func;
178 break;
179 }
180 }
181 }
182
183 m_lock.unlock();
184
185 return func;
186}
187
188// Given the function pointer returns the associtated function name
189const char* FuncList::find_name(const void *func)
190{
191 const char* name = 0;
192
193 m_lock.lock();
194
195 for (Node *n = m_head; n != 0; n = n->next) {
196 for (const Table::Entry *e = n->table.entries;
197 e->name != (const char*) -1; e++) {
198 if (e->func == func) {
199 name = e->name;
200 break;
201 }
202 }
203 }
204
205 m_lock.unlock();
206
207 return name;
208}
209
210// Returns max name length from all tables
211int64_t FuncList::max_name_length(void)
212{
213 if (m_max_name_len < 0) {
214 m_lock.lock();
215
216 m_max_name_len = 0;
217 for (Node *n = m_head; n != 0; n = n->next) {
218 if (n->table.max_name_len < 0) {
219 n->table.max_name_len = 0;
220
221 // calculate max name length in a single table
222 for (const Table::Entry *e = n->table.entries;
223 e->name != (const char*) -1; e++) {
224 if (e->name != 0) {
225 size_t len = strlen(e->name) + 1;
226 if (n->table.max_name_len < len) {
227 n->table.max_name_len = len;
228 }
229 }
230 }
231 }
232
233 // select max from all tables
234 if (m_max_name_len < n->table.max_name_len) {
235 m_max_name_len = n->table.max_name_len;
236 }
237 }
238
239 m_lock.unlock();
240 }
241 return m_max_name_len;
242}
243
244// Debugging dump
245void FuncList::dump(void)
246{
247 OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
248
249 m_lock.lock();
250
251 for (Node *n = m_head; n != 0; n = n->next) {
252 for (const Table::Entry *e = n->table.entries;
253 e->name != (const char*) -1; e++) {
254 if (e->name != 0) {
255 OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e->func, e->name);
256 }
257 }
258 }
259
260 m_lock.unlock();
261}
262
263// Debugging dump
264void VarList::dump(void)
265{
266 OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
267
268 m_lock.lock();
269
270 for (Node *n = m_head; n != 0; n = n->next) {
271 for (const Table::Entry *e = n->table.entries;
272 e->name != (const char*) -1; e++) {
273 if (e->name != 0) {
274#if HOST_LIBRARY
275 OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e->name, e->addr,
276 e->size);
277#else // HOST_LIBRARY
278 OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e->name, e->addr);
279#endif // HOST_LIBRARY
280 }
281 }
282 }
283
284 m_lock.unlock();
285}
286
287//
288int64_t VarList::table_size(int64_t &nelems)
289{
290 int64_t length = 0;
291
292 nelems = 0;
293
294 // calculate string table size and number of elements
295 for (Node *n = m_head; n != 0; n = n->next) {
296 for (const Table::Entry *e = n->table.entries;
297 e->name != (const char*) -1; e++) {
298 if (e->name != 0) {
299 length += strlen(e->name) + 1;
300 nelems++;
301 }
302 }
303 }
304
305 return nelems * sizeof(BufEntry) + length;
306}
307
308// copy table to the gven buffer
309void VarList::table_copy(void *buf, int64_t nelems)
310{
311 BufEntry* elems = static_cast<BufEntry*>(buf);
312 char* names = reinterpret_cast<char*>(elems + nelems);
313
314 // copy entries to buffer
315 for (Node *n = m_head; n != 0; n = n->next) {
316 for (const Table::Entry *e = n->table.entries;
317 e->name != (const char*) -1; e++) {
318 if (e->name != 0) {
319 // name field contains offset to the name from the beginning
320 // of the buffer
321 elems->name = names - static_cast<char*>(buf);
322 elems->addr = reinterpret_cast<intptr_t>(e->addr);
323
324 // copy name to string table
325 const char *name = e->name;
326 while ((*names++ = *name++) != '\0');
327
328 elems++;
329 }
330 }
331 }
332}
333
334// patch name offsets in a buffer
335void VarList::table_patch_names(void *buf, int64_t nelems)
336{
337 BufEntry* elems = static_cast<BufEntry*>(buf);
338 for (int i = 0; i < nelems; i++) {
339 elems[i].name += reinterpret_cast<intptr_t>(buf);
340 }
341}
342
343// Adds given list element to the global lookup table list
344extern "C" void __offload_register_tables(
345 FuncList::Node *entry_table,
346 FuncList::Node *func_table,
347 VarList::Node *var_table
348)
349{
350 OFFLOAD_DEBUG_TRACE(2, "Registering offload function entry table %p\n",
351 entry_table);
352 __offload_entries.add_table(entry_table);
353
354 OFFLOAD_DEBUG_TRACE(2, "Registering function table %p\n", func_table);
355 __offload_funcs.add_table(func_table);
356
357 OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table);
358 __offload_vars.add_table(var_table);
359}
360
361// Removes given list element from the global lookup table list
362extern "C" void __offload_unregister_tables(
363 FuncList::Node *entry_table,
364 FuncList::Node *func_table,
365 VarList::Node *var_table
366)
367{
368 __offload_entries.remove_table(entry_table);
369
370 OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table);
371 __offload_funcs.remove_table(func_table);
372
373 OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table);
374 __offload_vars.remove_table(var_table);
375}