Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions clang/test/Driver/linker-wrapper-image.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// REQUIRES: x86-registered-target
// REQUIRES: nvptx-registered-target
// REQUIRES: amdgpu-registered-target
// REQUIRES: spirv-registered-target

// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.elf.o

Expand Down Expand Up @@ -263,3 +264,31 @@
// HIP: while.end:
// HIP-NEXT: ret void
// HIP-NEXT: }

// RUN: clang-offload-packager -o %t.out --image=file=%t.elf.o,kind=sycl,triple=spirv64-unknown-unknown,arch=generic
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
// RUN: -fembed-offload-object=%t.out
// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu \
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=SYCL
// RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-linux-gnu -r \
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=SYCL

// SYCL: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }
// SYCL-NEXT: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr }

// SYCL: @.sycl_offloading.device_images = internal unnamed_addr constant [0 x %__sycl.tgt_device_image] zeroinitializer
// SYCL-NEXT: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 0, ptr @.sycl_offloading.device_images, ptr null, ptr null }
// SYCL-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_reg, ptr null }]
// SYCL-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @sycl.descriptor_unreg, ptr null }]

// SYCL: define internal void @sycl.descriptor_reg() section ".text.startup" {
// SYCL-NEXT: entry:
// SYCL-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor)
// SYCL-NEXT: ret void
// SYCL-NEXT: }

// SYCL: define internal void @sycl.descriptor_unreg() section ".text.startup" {
// SYCL-NEXT: entry:
// SYCL-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor)
// SYCL-NEXT: ret void
// SYCL-NEXT: }
2 changes: 1 addition & 1 deletion clang/test/Driver/linker-wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ __attribute__((visibility("protected"), used)) int x;
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.spirv.bc,kind=sycl,triple=spirv64-unknown-unknown,arch=generic
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
// RUN: not clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=SPIRV-LINK

// SPIRV-LINK: clang{{.*}} -o {{.*}}.img -dumpdir a.out.spirv64..img. --target=spirv64-unknown-unknown {{.*}}.o --sycl-link -Xlinker -triple=spirv64-unknown-unknown -Xlinker -arch=
Expand Down
24 changes: 23 additions & 1 deletion clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,14 @@ wrapDeviceImages(ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
M, BuffersToWrap.front(), offloading::getOffloadEntryArray(M)))
return std::move(Err);
break;
case OFK_SYCL: {
// TODO: fill these options once the Driver supports them.
offloading::SYCLJITOptions Options;
if (Error Err =
offloading::wrapSYCLBinaries(M, BuffersToWrap.front(), Options))
return std::move(Err);
break;
}
default:
return createStringError(getOffloadKindName(Kind) +
" wrapping is not supported");
Expand Down Expand Up @@ -754,6 +762,19 @@ bundleOpenMP(ArrayRef<OffloadingImage> Images) {
return std::move(Buffers);
}

Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleSYCL(ArrayRef<OffloadingImage> Images) {
SmallVector<std::unique_ptr<MemoryBuffer>> Buffers;
for (const OffloadingImage &Image : Images) {
// clang-sycl-linker packs outputs into one binary blob. Therefore, it is
// passed to Offload Wrapper as is.
StringRef S(Image.Image->getBufferStart(), Image.Image->getBufferSize());
Buffers.emplace_back(MemoryBuffer::getMemBufferCopy(S));
}

return std::move(Buffers);
}

Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleCuda(ArrayRef<OffloadingImage> Images, const ArgList &Args) {
SmallVector<std::pair<StringRef, StringRef>, 4> InputFiles;
Expand Down Expand Up @@ -806,8 +827,9 @@ bundleLinkedOutput(ArrayRef<OffloadingImage> Images, const ArgList &Args,
llvm::TimeTraceScope TimeScope("Bundle linked output");
switch (Kind) {
case OFK_OpenMP:
case OFK_SYCL:
return bundleOpenMP(Images);
case OFK_SYCL:
return bundleSYCL(Images);
case OFK_Cuda:
return bundleCuda(Images, Args);
case OFK_HIP:
Expand Down
19 changes: 19 additions & 0 deletions llvm/include/llvm/Frontend/Offloading/OffloadWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/Compiler.h"

#include <string>

namespace llvm {
namespace offloading {
using EntryArrayTy = std::pair<GlobalVariable *, GlobalVariable *>;
Expand Down Expand Up @@ -52,6 +54,23 @@ LLVM_ABI llvm::Error wrapHIPBinary(llvm::Module &M, llvm::ArrayRef<char> Images,
EntryArrayTy EntryArray,
llvm::StringRef Suffix = "",
bool EmitSurfacesAndTextures = true);

struct SYCLJITOptions {
// Target/compiler specific options that are suggested to use to "compile"
// program at runtime.
Comment on lines +59 to +60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit that can be addressed in follow-up pr, this comment might be clearer, these options arent really a suggestion, they must be passed to the gpu driver

Suggested change
// Target/compiler specific options that are suggested to use to "compile"
// program at runtime.
// Target/compiler specific options that are passed to the device compiler
// at runtime.

std::string CompileOptions;
// Target/compiler specific options that are suggested to use to "link"
// program at runtime.
std::string LinkOptions;
};

/// Wraps OffloadBinaries in the given \p Buffers into the module \p M
/// as global symbols and registers the images with the SYCL Runtime.
/// \param Options Data that needs to be encoded for the later use in a runtime.
LLVM_ABI llvm::Error
wrapSYCLBinaries(llvm::Module &M, llvm::ArrayRef<char> Buffer,
SYCLJITOptions Options = SYCLJITOptions());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit that can be addressed in follow-up: are there any cases where a caller wouldnt want to pass SYCLJitOptions? AOT mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, AOT mode is a case when it is too late to pass any options.


} // namespace offloading
} // namespace llvm

Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Frontend/Offloading/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ LLVM_ABI StructType *getEntryTy(Module &M);
/// \param Data Extra data storage associated with the entry.
/// \param SectionName The section this entry will be placed at.
/// \param AuxAddr An extra pointer if needed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we explain what this means more? when do we need it

LLVM_ABI void
/// \return The emitted global variable containing the offloading entry.
LLVM_ABI GlobalVariable *
emitOffloadingEntry(Module &M, object::OffloadKind Kind, Constant *Addr,
StringRef Name, uint64_t Size, uint32_t Flags,
uint64_t Data, Constant *AuxAddr = nullptr,
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/Object/OffloadBinary.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum ImageKind : uint16_t {
IMG_Cubin,
IMG_Fatbinary,
IMG_PTX,
IMG_SPIRV,
IMG_LAST,
};

Expand All @@ -70,9 +71,9 @@ class OffloadBinary : public Binary {

/// The offloading metadata that will be serialized to a memory buffer.
struct OffloadingImage {
ImageKind TheImageKind;
OffloadKind TheOffloadKind;
uint32_t Flags;
ImageKind TheImageKind = ImageKind::IMG_None;
OffloadKind TheOffloadKind = OffloadKind::OFK_None;
uint32_t Flags = 0;
MapVector<StringRef, StringRef> StringData;
std::unique_ptr<MemoryBuffer> Image;
};
Expand Down
Loading
Loading