Skip to content

Commit 3de4cd1

Browse files
author
George Rokos
committedFeb 1, 2017
[OpenMP] Initial implementation of OpenMP offloading library - libomptarget plugins.
This is the patch upstreaming the plugins part of libomptarget (CUDA, generic-elf-64). Differential Revision: https://reviews.llvm.org/D14253 llvm-svn: 293724
1 parent bdd59e6 commit 3de4cd1

File tree

10 files changed

+1249
-0
lines changed

10 files changed

+1249
-0
lines changed
 

‎openmp/libomptarget/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ if(LIBOMPTARGET_HAVE_STD_CPP11_FLAG)
107107
set(LIBOMPTARGET_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
108108
endif()
109109

110+
# Build offloading plugins and device RTLs if they are available.
111+
add_subdirectory(plugins)
112+
110113
# Add tests.
111114
add_subdirectory(test)
112115

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
##===----------------------------------------------------------------------===##
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+
# Build plugins for the user system if available.
11+
#
12+
##===----------------------------------------------------------------------===##
13+
14+
# void build_generic_elf64(string tmachine, string tmachine_name, string tmachine_libname, string elf_machine_id);
15+
# - build a plugin for an ELF based generic 64-bit target based on libffi.
16+
# - tmachine: name of the machine processor as used in the cmake build system.
17+
# - tmachine_name: name of the machine to be printed with the debug messages.
18+
# - tmachine_libname: machine name to be appended to the plugin library name.
19+
macro(build_generic_elf64 tmachine tmachine_name tmachine_libname tmachine_triple elf_machine_id)
20+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "${tmachine}$")
21+
if(LIBOMPTARGET_DEP_LIBELF_FOUND)
22+
if(LIBOMPTARGET_DEP_LIBFFI_FOUND)
23+
24+
libomptarget_say("Building ${tmachine_name} offloading plugin.")
25+
26+
include_directories(${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR})
27+
include_directories(${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR})
28+
29+
# Define macro to be used as prefix of the runtime messages for this target.
30+
add_definitions("-DTARGET_NAME=${tmachine_name}")
31+
32+
# Define macro with the ELF ID for this target.
33+
add_definitions("-DTARGET_ELF_ID=${elf_machine_id}")
34+
35+
add_library("omptarget.rtl.${tmachine_libname}" SHARED
36+
${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp)
37+
38+
# Install plugin under the lib destination folder.
39+
install(TARGETS "omptarget.rtl.${tmachine_libname}"
40+
LIBRARY DESTINATION lib${LIBOMPTARGET_LIBDIR_SUFFIX})
41+
42+
target_link_libraries(
43+
"omptarget.rtl.${tmachine_libname}"
44+
${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES}
45+
${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
46+
dl
47+
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports")
48+
49+
# Report to the parent scope that we are building a plugin.
50+
set(LIBOMPTARGET_SYSTEM_TARGETS
51+
"${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple}" PARENT_SCOPE)
52+
53+
else(LIBOMPTARGET_DEP_LIBFFI_FOUND)
54+
libomptarget_say("Not building ${tmachine_name} offloading plugin: libffi dependency not found.")
55+
endif(LIBOMPTARGET_DEP_LIBFFI_FOUND)
56+
else(LIBOMPTARGET_DEP_LIBELF_FOUND)
57+
libomptarget_say("Not building ${tmachine_name} offloading plugin: libelf dependency not found.")
58+
endif(LIBOMPTARGET_DEP_LIBELF_FOUND)
59+
else()
60+
libomptarget_say("Not building ${tmachine_name} offloading plugin: machine not found in the system.")
61+
endif()
62+
endmacro()
63+
64+
add_subdirectory(cuda)
65+
add_subdirectory(ppc64)
66+
add_subdirectory(ppc64le)
67+
add_subdirectory(x86_64)
68+
69+
# Make sure the parent scope can see the plugins that will be created.
70+
set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS}" PARENT_SCOPE)
71+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//===-- elf_common.c - Common ELF functionality -------------------*- C -*-===//
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+
// Common ELF functionality for target plugins.
11+
// Must be included in the plugin source file AFTER omptarget.h has been
12+
// included and macro DP(...) has been defined.
13+
// .
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#if !(defined(_OMPTARGET_H_) && defined(DP))
18+
#error Include elf_common.c in the plugin source AFTER omptarget.h has been\
19+
included and macro DP(...) has been defined.
20+
#endif
21+
22+
#include <elf.h>
23+
#include <libelf.h>
24+
25+
// Check whether an image is valid for execution on target_id
26+
static inline int32_t elf_check_machine(__tgt_device_image *image,
27+
uint16_t target_id) {
28+
29+
// Is the library version incompatible with the header file?
30+
if (elf_version(EV_CURRENT) == EV_NONE) {
31+
DP("Incompatible ELF library!\n");
32+
return 0;
33+
}
34+
35+
char *img_begin = (char *)image->ImageStart;
36+
char *img_end = (char *)image->ImageEnd;
37+
size_t img_size = img_end - img_begin;
38+
39+
// Obtain elf handler
40+
Elf *e = elf_memory(img_begin, img_size);
41+
if (!e) {
42+
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
43+
return 0;
44+
}
45+
46+
// Check if ELF is the right kind.
47+
if (elf_kind(e) != ELF_K_ELF) {
48+
DP("Unexpected ELF type!\n");
49+
return 0;
50+
}
51+
Elf64_Ehdr *eh64 = elf64_getehdr(e);
52+
Elf32_Ehdr *eh32 = elf32_getehdr(e);
53+
54+
if (!eh64 && !eh32) {
55+
DP("Unable to get machine ID from ELF file!\n");
56+
elf_end(e);
57+
return 0;
58+
}
59+
60+
uint16_t MachineID;
61+
if (eh64 && !eh32)
62+
MachineID = eh64->e_machine;
63+
else if (eh32 && !eh64)
64+
MachineID = eh32->e_machine;
65+
else {
66+
DP("Ambiguous ELF header!\n");
67+
elf_end(e);
68+
return 0;
69+
}
70+
71+
elf_end(e);
72+
return MachineID == target_id;
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
##===----------------------------------------------------------------------===##
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+
# Build a plugin for a CUDA machine if available.
11+
#
12+
##===----------------------------------------------------------------------===##
13+
if(LIBOMPTARGET_DEP_LIBELF_FOUND)
14+
if(LIBOMPTARGET_DEP_CUDA_FOUND)
15+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(ppc64le)$" AND CMAKE_SYSTEM_NAME MATCHES "Linux")
16+
17+
libomptarget_say("Building CUDA offloading plugin.")
18+
19+
# Define the suffix for the runtime messaging dumps.
20+
add_definitions(-DTARGET_NAME=CUDA)
21+
22+
if(LIBOMPTARGET_CMAKE_BUILD_TYPE MATCHES debug)
23+
add_definitions(-DCUDA_ERROR_REPORT)
24+
endif()
25+
26+
include_directories(${LIBOMPTARGET_DEP_CUDA_INCLUDE_DIRS})
27+
28+
add_library(omptarget.rtl.cuda SHARED src/rtl.cpp)
29+
30+
# Install plugin under the lib destination folder.
31+
install(TARGETS omptarget.rtl.cuda LIBRARY DESTINATION lib${LIBOMPTARGET_LIBDIR_SUFFIX})
32+
33+
target_link_libraries(omptarget.rtl.cuda
34+
${LIBOMPTARGET_DEP_CUDA_LIBRARIES}
35+
cuda
36+
${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
37+
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports")
38+
39+
# Report to the parent scope that we are building a plugin for CUDA.
40+
set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS} nvptx64-nvidia-cuda" PARENT_SCOPE)
41+
else()
42+
libomptarget_say("Not building CUDA offloading plugin: only support CUDA in Linux x86_64 or ppc64le hosts.")
43+
endif()
44+
else()
45+
libomptarget_say("Not building CUDA offloading plugin: CUDA not found in system.")
46+
endif()
47+
else(LIBOMPTARGET_DEP_LIBELF_FOUND)
48+
libomptarget_say("Not building CUDA offloading plugin: libelf dependency not found.")
49+
endif(LIBOMPTARGET_DEP_LIBELF_FOUND)

‎openmp/libomptarget/plugins/cuda/src/rtl.cpp

+670
Large diffs are not rendered by default.

‎openmp/libomptarget/plugins/exports

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
VERS1.0 {
2+
global:
3+
__tgt_rtl_is_valid_binary;
4+
__tgt_rtl_number_of_devices;
5+
__tgt_rtl_init_device;
6+
__tgt_rtl_load_binary;
7+
__tgt_rtl_data_alloc;
8+
__tgt_rtl_data_submit;
9+
__tgt_rtl_data_retrieve;
10+
__tgt_rtl_data_delete;
11+
__tgt_rtl_run_target_team_region;
12+
__tgt_rtl_run_target_region;
13+
local:
14+
*;
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
//===-RTLs/generic-64bit/src/rtl.cpp - Target RTLs Implementation - C++ -*-===//
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+
// RTL for generic 64-bit machine
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include <cassert>
15+
#include <cstdio>
16+
#include <cstring>
17+
#include <cstdlib>
18+
#include <dlfcn.h>
19+
#include <ffi.h>
20+
#include <gelf.h>
21+
#include <link.h>
22+
#include <list>
23+
#include <vector>
24+
25+
#include "omptarget.h"
26+
27+
#ifndef TARGET_NAME
28+
#define TARGET_NAME Generic ELF - 64bit
29+
#endif
30+
31+
#ifndef TARGET_ELF_ID
32+
#define TARGET_ELF_ID 0
33+
#endif
34+
35+
#define GETNAME2(name) #name
36+
#define GETNAME(name) GETNAME2(name)
37+
#define DP(...) DEBUGP("Target " GETNAME(TARGET_NAME) " RTL", __VA_ARGS__)
38+
39+
#include "../../common/elf_common.c"
40+
41+
#define NUMBER_OF_DEVICES 4
42+
#define OFFLOADSECTIONNAME ".omp_offloading.entries"
43+
44+
/// Array of Dynamic libraries loaded for this target.
45+
struct DynLibTy {
46+
char *FileName;
47+
void *Handle;
48+
};
49+
50+
/// Keep entries table per device.
51+
struct FuncOrGblEntryTy {
52+
__tgt_target_table Table;
53+
};
54+
55+
/// Class containing all the device information.
56+
class RTLDeviceInfoTy {
57+
std::vector<FuncOrGblEntryTy> FuncGblEntries;
58+
59+
public:
60+
std::list<DynLibTy> DynLibs;
61+
62+
// Record entry point associated with device.
63+
void createOffloadTable(int32_t device_id, __tgt_offload_entry *begin,
64+
__tgt_offload_entry *end) {
65+
assert(device_id < (int32_t)FuncGblEntries.size() &&
66+
"Unexpected device id!");
67+
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
68+
69+
E.Table.EntriesBegin = begin;
70+
E.Table.EntriesEnd = end;
71+
}
72+
73+
// Return true if the entry is associated with device.
74+
bool findOffloadEntry(int32_t device_id, void *addr) {
75+
assert(device_id < (int32_t)FuncGblEntries.size() &&
76+
"Unexpected device id!");
77+
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
78+
79+
for (__tgt_offload_entry *i = E.Table.EntriesBegin, *e = E.Table.EntriesEnd;
80+
i < e; ++i) {
81+
if (i->addr == addr)
82+
return true;
83+
}
84+
85+
return false;
86+
}
87+
88+
// Return the pointer to the target entries table.
89+
__tgt_target_table *getOffloadEntriesTable(int32_t device_id) {
90+
assert(device_id < (int32_t)FuncGblEntries.size() &&
91+
"Unexpected device id!");
92+
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
93+
94+
return &E.Table;
95+
}
96+
97+
RTLDeviceInfoTy(int32_t num_devices) { FuncGblEntries.resize(num_devices); }
98+
99+
~RTLDeviceInfoTy() {
100+
// Close dynamic libraries
101+
for (auto &lib : DynLibs) {
102+
if (lib.Handle) {
103+
dlclose(lib.Handle);
104+
remove(lib.FileName);
105+
}
106+
}
107+
}
108+
};
109+
110+
static RTLDeviceInfoTy DeviceInfo(NUMBER_OF_DEVICES);
111+
112+
#ifdef __cplusplus
113+
extern "C" {
114+
#endif
115+
116+
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) {
117+
// If we don't have a valid ELF ID we can just fail.
118+
#if TARGET_ELF_ID < 1
119+
return 0;
120+
#else
121+
return elf_check_machine(image, TARGET_ELF_ID);
122+
#endif
123+
}
124+
125+
int32_t __tgt_rtl_number_of_devices() { return NUMBER_OF_DEVICES; }
126+
127+
int32_t __tgt_rtl_init_device(int32_t device_id) { return OFFLOAD_SUCCESS; }
128+
129+
__tgt_target_table *__tgt_rtl_load_binary(int32_t device_id,
130+
__tgt_device_image *image) {
131+
132+
DP("Dev %d: load binary from " DPxMOD " image\n", device_id,
133+
DPxPTR(image->ImageStart));
134+
135+
assert(device_id >= 0 && device_id < NUMBER_OF_DEVICES && "bad dev id");
136+
137+
size_t ImageSize = (size_t)image->ImageEnd - (size_t)image->ImageStart;
138+
size_t NumEntries = (size_t)(image->EntriesEnd - image->EntriesBegin);
139+
DP("Expecting to have %zd entries defined.\n", NumEntries);
140+
141+
// Is the library version incompatible with the header file?
142+
if (elf_version(EV_CURRENT) == EV_NONE) {
143+
DP("Incompatible ELF library!\n");
144+
return NULL;
145+
}
146+
147+
// Obtain elf handler
148+
Elf *e = elf_memory((char *)image->ImageStart, ImageSize);
149+
if (!e) {
150+
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
151+
return NULL;
152+
}
153+
154+
if (elf_kind(e) != ELF_K_ELF) {
155+
DP("Invalid Elf kind!\n");
156+
elf_end(e);
157+
return NULL;
158+
}
159+
160+
// Find the entries section offset
161+
Elf_Scn *section = 0;
162+
Elf64_Off entries_offset = 0;
163+
164+
size_t shstrndx;
165+
166+
if (elf_getshdrstrndx(e, &shstrndx)) {
167+
DP("Unable to get ELF strings index!\n");
168+
elf_end(e);
169+
return NULL;
170+
}
171+
172+
while ((section = elf_nextscn(e, section))) {
173+
GElf_Shdr hdr;
174+
gelf_getshdr(section, &hdr);
175+
176+
if (!strcmp(elf_strptr(e, shstrndx, hdr.sh_name), OFFLOADSECTIONNAME)) {
177+
entries_offset = hdr.sh_addr;
178+
break;
179+
}
180+
}
181+
182+
if (!entries_offset) {
183+
DP("Entries Section Offset Not Found\n");
184+
elf_end(e);
185+
return NULL;
186+
}
187+
188+
DP("Offset of entries section is (" DPxMOD ").\n", DPxPTR(entries_offset));
189+
190+
// load dynamic library and get the entry points. We use the dl library
191+
// to do the loading of the library, but we could do it directly to avoid the
192+
// dump to the temporary file.
193+
//
194+
// 1) Create tmp file with the library contents.
195+
// 2) Use dlopen to load the file and dlsym to retrieve the symbols.
196+
char tmp_name[] = "/tmp/tmpfile_XXXXXX";
197+
int tmp_fd = mkstemp(tmp_name);
198+
199+
if (tmp_fd == -1) {
200+
elf_end(e);
201+
return NULL;
202+
}
203+
204+
FILE *ftmp = fdopen(tmp_fd, "wb");
205+
206+
if (!ftmp) {
207+
elf_end(e);
208+
return NULL;
209+
}
210+
211+
fwrite(image->ImageStart, ImageSize, 1, ftmp);
212+
fclose(ftmp);
213+
214+
DynLibTy Lib = {tmp_name, dlopen(tmp_name, RTLD_LAZY)};
215+
216+
if (!Lib.Handle) {
217+
DP("Target library loading error: %s\n", dlerror());
218+
elf_end(e);
219+
return NULL;
220+
}
221+
222+
DeviceInfo.DynLibs.push_back(Lib);
223+
224+
struct link_map *libInfo = (struct link_map *)Lib.Handle;
225+
226+
// The place where the entries info is loaded is the library base address
227+
// plus the offset determined from the ELF file.
228+
Elf64_Addr entries_addr = libInfo->l_addr + entries_offset;
229+
230+
DP("Pointer to first entry to be loaded is (" DPxMOD ").\n",
231+
DPxPTR(entries_addr));
232+
233+
// Table of pointers to all the entries in the target.
234+
__tgt_offload_entry *entries_table = (__tgt_offload_entry *)entries_addr;
235+
236+
__tgt_offload_entry *entries_begin = &entries_table[0];
237+
__tgt_offload_entry *entries_end = entries_begin + NumEntries;
238+
239+
if (!entries_begin) {
240+
DP("Can't obtain entries begin\n");
241+
elf_end(e);
242+
return NULL;
243+
}
244+
245+
DP("Entries table range is (" DPxMOD ")->(" DPxMOD ")\n",
246+
DPxPTR(entries_begin), DPxPTR(entries_end));
247+
DeviceInfo.createOffloadTable(device_id, entries_begin, entries_end);
248+
249+
elf_end(e);
250+
251+
return DeviceInfo.getOffloadEntriesTable(device_id);
252+
}
253+
254+
void *__tgt_rtl_data_alloc(int32_t device_id, int64_t size) {
255+
void *ptr = malloc(size);
256+
return ptr;
257+
}
258+
259+
int32_t __tgt_rtl_data_submit(int32_t device_id, void *tgt_ptr, void *hst_ptr,
260+
int64_t size) {
261+
memcpy(tgt_ptr, hst_ptr, size);
262+
return OFFLOAD_SUCCESS;
263+
}
264+
265+
int32_t __tgt_rtl_data_retrieve(int32_t device_id, void *hst_ptr, void *tgt_ptr,
266+
int64_t size) {
267+
memcpy(hst_ptr, tgt_ptr, size);
268+
return OFFLOAD_SUCCESS;
269+
}
270+
271+
int32_t __tgt_rtl_data_delete(int32_t device_id, void *tgt_ptr) {
272+
free(tgt_ptr);
273+
return OFFLOAD_SUCCESS;
274+
}
275+
276+
int32_t __tgt_rtl_run_target_team_region(int32_t device_id, void *tgt_entry_ptr,
277+
void **tgt_args, int32_t arg_num, int32_t team_num, int32_t thread_limit,
278+
uint64_t loop_tripcount /*not used*/) {
279+
// ignore team num and thread limit.
280+
281+
// Use libffi to launch execution.
282+
ffi_cif cif;
283+
284+
// All args are references.
285+
std::vector<ffi_type *> args_types(arg_num, &ffi_type_pointer);
286+
std::vector<void *> args(arg_num);
287+
288+
for (int32_t i = 0; i < arg_num; ++i)
289+
args[i] = &tgt_args[i];
290+
291+
ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arg_num,
292+
&ffi_type_void, &args_types[0]);
293+
294+
assert(status == FFI_OK && "Unable to prepare target launch!");
295+
296+
if (status != FFI_OK)
297+
return OFFLOAD_FAIL;
298+
299+
DP("Running entry point at " DPxMOD "...\n", DPxPTR(tgt_entry_ptr));
300+
301+
ffi_call(&cif, FFI_FN(tgt_entry_ptr), NULL, &args[0]);
302+
return OFFLOAD_SUCCESS;
303+
}
304+
305+
int32_t __tgt_rtl_run_target_region(int32_t device_id, void *tgt_entry_ptr,
306+
void **tgt_args, int32_t arg_num) {
307+
// use one team and one thread.
308+
return __tgt_rtl_run_target_team_region(device_id, tgt_entry_ptr, tgt_args,
309+
arg_num, 1, 1, 0);
310+
}
311+
312+
#ifdef __cplusplus
313+
}
314+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
##===----------------------------------------------------------------------===##
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+
# Build a plugin for a ppc64 machine if available.
11+
#
12+
##===----------------------------------------------------------------------===##
13+
14+
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
15+
build_generic_elf64("ppc64" "PPC64" "ppc64" "powerpc64-ibm-linux-gnu" "21")
16+
else()
17+
libomptarget_say("Not building ppc64 offloading plugin: machine not found in the system.")
18+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
##===----------------------------------------------------------------------===##
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+
# Build a plugin for a ppc64le machine if available.
11+
#
12+
##===----------------------------------------------------------------------===##
13+
14+
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
15+
build_generic_elf64("ppc64le" "PPC64le" "ppc64" "powerpc64le-ibm-linux-gnu" "21")
16+
else()
17+
libomptarget_say("Not building ppc64le offloading plugin: machine not found in the system.")
18+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
##===----------------------------------------------------------------------===##
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+
# Build a plugin for a x86_64 machine if available.
11+
#
12+
##===----------------------------------------------------------------------===##
13+
14+
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
15+
build_generic_elf64("x86_64" "x86_64" "x86_64" "x86_64-pc-linux-gnu" "62")
16+
else()
17+
libomptarget_say("Not building x86_64 offloading plugin: machine not found in the system.")
18+
endif()

0 commit comments

Comments
 (0)
Please sign in to comment.