summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Huber <huberjn@outlook.com>2024-01-05 14:29:34 -0600
committerGitHub <noreply@github.com>2024-01-05 14:29:34 -0600
commit5121e2cffd23751360e71a8ac69b7462dae23aa8 (patch)
tree4db991f1a056c30d4ae2760237a7e1eb273ce7c3
parentf22dc88759a53d4224c17d3833a359ef5674b4ea (diff)
[OpenMP] Change `__tgt_device_image` to point to the image (#77003)
Summary: We use the OffloadBinary to contain bundled offloading objects used to support many images / targets at the same time. The `__tgt_device_info` struct used to contain a pointer to this underlying binary format, which contains information about the triple and architecture. We used to parse this in the runtime to do image verification. Recent changes removed the need for this to be used internally, as we just parse it out of the ELF directly. This patch sets the pointers up so they point to the ELF without requiring any further parsing.
-rw-r--r--clang/test/Driver/linker-wrapper-image.c4
-rw-r--r--clang/tools/clang-linker-wrapper/OffloadWrapper.cpp24
2 files changed, 23 insertions, 5 deletions
diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c
index a2a1996f6643..40dde2e02918 100644
--- a/clang/test/Driver/linker-wrapper-image.c
+++ b/clang/test/Driver/linker-wrapper-image.c
@@ -19,8 +19,8 @@
// OPENMP-COFF: @__start_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OA"
// OPENMP-COFF-NEXT: @__stop_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OZ"
-// OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}"
-// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr @.omp_offloading.device_image, ptr getelementptr inbounds ([[[SIZE]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }]
+// OPENMP-NEXT: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD\01{{.*}}", section ".llvm.offloading", align 8
+// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr inbounds ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr getelementptr inbounds ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }]
// OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }
// OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_reg, ptr null }]
// OPENMP-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_unreg, ptr null }]
diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index f4f500b17357..161374ae5552 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -8,6 +8,7 @@
#include "OffloadWrapper.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalVariable.h"
@@ -121,19 +122,36 @@ GlobalVariable *createBinDesc(Module &M, ArrayRef<ArrayRef<char>> Bufs) {
SmallVector<Constant *, 4u> ImagesInits;
ImagesInits.reserve(Bufs.size());
for (ArrayRef<char> Buf : Bufs) {
+ // We embed the full offloading entry so the binary utilities can parse it.
auto *Data = ConstantDataArray::get(C, Buf);
- auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant*/ true,
+ auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant=*/true,
GlobalVariable::InternalLinkage, Data,
".omp_offloading.device_image");
Image->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
Image->setSection(".llvm.offloading");
Image->setAlignment(Align(object::OffloadBinary::getAlignment()));
- auto *Size = ConstantInt::get(getSizeTTy(M), Buf.size());
+ StringRef Binary(Buf.data(), Buf.size());
+ assert(identify_magic(Binary) == file_magic::offload_binary &&
+ "Invalid binary format");
+
+ // The device image struct contains the pointer to the beginning and end of
+ // the image stored inside of the offload binary. There should only be one
+ // of these for each buffer so we parse it out manually.
+ const auto *Header =
+ reinterpret_cast<const object::OffloadBinary::Header *>(
+ Binary.bytes_begin());
+ const auto *Entry = reinterpret_cast<const object::OffloadBinary::Entry *>(
+ Binary.bytes_begin() + Header->EntryOffset);
+
+ auto *Begin = ConstantInt::get(getSizeTTy(M), Entry->ImageOffset);
+ auto *Size =
+ ConstantInt::get(getSizeTTy(M), Entry->ImageOffset + Entry->ImageSize);
+ Constant *ZeroBegin[] = {Zero, Begin};
Constant *ZeroSize[] = {Zero, Size};
auto *ImageB =
- ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroZero);
+ ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroBegin);
auto *ImageE =
ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroSize);