[clang] [OpenMP] Change `__tgt_device_image` to point to the image (PR #77003)

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 4 13:04:36 PST 2024


https://github.com/jhuber6 created https://github.com/llvm/llvm-project/pull/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.


>From f6516f5e6d9eecdc7ce5710660753acf8a70da99 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Thu, 4 Jan 2024 15:00:15 -0600
Subject: [PATCH] [OpenMP] Change `__tgt_device_image` to point to the image

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.
---
 clang/test/Driver/linker-wrapper-image.c      |  4 ++--
 .../clang-linker-wrapper/OffloadWrapper.cpp   | 24 ++++++++++++++++---
 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 a2a1996f664309..40dde2e0291800 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 f4f500b173572d..161374ae555233 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);
 



More information about the cfe-commits mailing list