Skip to content

Commit 5121e2c

Browse files
authored
[OpenMP] Change __tgt_device_image to point to the image (llvm#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.
1 parent f22dc88 commit 5121e2c

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

clang/test/Driver/linker-wrapper-image.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
// OPENMP-COFF: @__start_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OA"
2020
// OPENMP-COFF-NEXT: @__stop_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OZ"
2121

22-
// OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}"
23-
// 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 }]
22+
// 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
23+
// 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 }]
2424
// 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 }
2525
// OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_reg, ptr null }]
2626
// OPENMP-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_unreg, ptr null }]

clang/tools/clang-linker-wrapper/OffloadWrapper.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "OffloadWrapper.h"
1010
#include "llvm/ADT/ArrayRef.h"
11+
#include "llvm/BinaryFormat/Magic.h"
1112
#include "llvm/Frontend/Offloading/Utility.h"
1213
#include "llvm/IR/Constants.h"
1314
#include "llvm/IR/GlobalVariable.h"
@@ -121,19 +122,36 @@ GlobalVariable *createBinDesc(Module &M, ArrayRef<ArrayRef<char>> Bufs) {
121122
SmallVector<Constant *, 4u> ImagesInits;
122123
ImagesInits.reserve(Bufs.size());
123124
for (ArrayRef<char> Buf : Bufs) {
125+
// We embed the full offloading entry so the binary utilities can parse it.
124126
auto *Data = ConstantDataArray::get(C, Buf);
125-
auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant*/ true,
127+
auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant=*/true,
126128
GlobalVariable::InternalLinkage, Data,
127129
".omp_offloading.device_image");
128130
Image->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
129131
Image->setSection(".llvm.offloading");
130132
Image->setAlignment(Align(object::OffloadBinary::getAlignment()));
131133

132-
auto *Size = ConstantInt::get(getSizeTTy(M), Buf.size());
134+
StringRef Binary(Buf.data(), Buf.size());
135+
assert(identify_magic(Binary) == file_magic::offload_binary &&
136+
"Invalid binary format");
137+
138+
// The device image struct contains the pointer to the beginning and end of
139+
// the image stored inside of the offload binary. There should only be one
140+
// of these for each buffer so we parse it out manually.
141+
const auto *Header =
142+
reinterpret_cast<const object::OffloadBinary::Header *>(
143+
Binary.bytes_begin());
144+
const auto *Entry = reinterpret_cast<const object::OffloadBinary::Entry *>(
145+
Binary.bytes_begin() + Header->EntryOffset);
146+
147+
auto *Begin = ConstantInt::get(getSizeTTy(M), Entry->ImageOffset);
148+
auto *Size =
149+
ConstantInt::get(getSizeTTy(M), Entry->ImageOffset + Entry->ImageSize);
150+
Constant *ZeroBegin[] = {Zero, Begin};
133151
Constant *ZeroSize[] = {Zero, Size};
134152

135153
auto *ImageB =
136-
ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroZero);
154+
ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroBegin);
137155
auto *ImageE =
138156
ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroSize);
139157

0 commit comments

Comments
 (0)