[PATCH] D129033: [Clang] Use metadata to make identifying embedded objects easier

Joseph Huber via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 1 19:55:26 PDT 2022


jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, JonChesterfield, ABataev, MaskRay, tianshilei1992.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
jhuber6 requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

Currently we use the `embedBufferInModule` function to store binary
strings containing device offloading data inside the host object to
create a fatbinary. In the case of LTO, we need to extract this object
from the LLVM-IR. This patch adds a metadata node for the embedded
objects containing the embedded pointers and the sections they were
stored at. This should create a cleaner interface for identifying these
values.

In the future it may be worthwhile to also encode an `ID` in the
metadata corresponding to the object's special section type if relevant.
This would allow us to extract the data from an object file and LLVM-IR
using the same ID.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129033

Files:
  clang/test/Frontend/embed-object.c
  clang/test/Frontend/embed-object.ll
  clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
  llvm/include/llvm/Transforms/Utils/ModuleUtils.h
  llvm/lib/Transforms/Utils/ModuleUtils.cpp


Index: llvm/lib/Transforms/Utils/ModuleUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -275,5 +275,12 @@
   GV->setSection(SectionName);
   GV->setAlignment(Alignment);
 
+  LLVMContext &Ctx = M.getContext();
+  NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.embedded.object");
+  Metadata *MDVals[] = {ConstantAsMetadata::get(GV),
+                        MDString::get(Ctx, SectionName)};
+
+  MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+
   appendToCompilerUsed(M, GV);
 }
Index: llvm/include/llvm/Transforms/Utils/ModuleUtils.h
===================================================================
--- llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -109,7 +109,8 @@
 std::string getUniqueModuleId(Module *M);
 
 /// Embed the memory buffer \p Buf into the module \p M as a global using the
-/// specified section name.
+/// specified section name. Also provide metadata entry to identify it in the
+/// module using the same section name.
 void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName,
                          Align Alignment = Align(1));
 
Index: clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
===================================================================
--- clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -366,12 +366,23 @@
     return createStringError(inconvertibleErrorCode(),
                              "Failed to create module");
 
-  // Extract offloading data from globals with the `.llvm.offloading` section.
-  for (GlobalVariable &GV : M->globals()) {
-    if (!GV.hasSection() || !GV.getSection().equals(OFFLOAD_SECTION_MAGIC_STR))
+  // Extract offloading data from globals referenced by the
+  // `llvm.embedded.object` metadata with the `.llvm.offloading` section.
+  auto MD = M->getNamedMetadata("llvm.embedded.object");
+  for (const MDNode *Op : MD->operands()) {
+    if (Op->getNumOperands() < 2)
       continue;
 
-    auto *CDS = dyn_cast<ConstantDataSequential>(GV.getInitializer());
+    MDString *SectionID = dyn_cast<MDString>(Op->getOperand(1));
+    if (!SectionID || SectionID->getString() != OFFLOAD_SECTION_MAGIC_STR)
+      continue;
+
+    GlobalVariable *GV =
+        mdconst::dyn_extract_or_null<GlobalVariable>(Op->getOperand(0));
+    if (!GV)
+      continue;
+
+    auto *CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer());
     if (!CDS)
       continue;
 
Index: clang/test/Frontend/embed-object.ll
===================================================================
--- clang/test/Frontend/embed-object.ll
+++ clang/test/Frontend/embed-object.ll
@@ -13,3 +13,7 @@
 define i32 @foo() {
   ret i32 0
 }
+
+; CHECK: !llvm.embedded.object = !{![[METADATA_1:[0-9]+]], ![[METADATA_2:[0-9]+]]}
+; CHECK: ![[METADATA_1]] = !{ptr @[[OBJECT_1]], !".llvm.offloading"}
+; CHECK: ![[METADATA_2]] = !{ptr @[[OBJECT_2]], !".llvm.offloading"}
Index: clang/test/Frontend/embed-object.c
===================================================================
--- clang/test/Frontend/embed-object.c
+++ clang/test/Frontend/embed-object.c
@@ -4,3 +4,6 @@
 // CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @[[OBJECT]]], section "llvm.metadata"
 
 void foo(void) {}
+
+// CHECK: !llvm.embedded.object = !{![[METADATA:[0-9]+]]}
+// CHECK: ![[METADATA]] = !{ptr @[[OBJECT]], !".llvm.offloading"}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129033.441861.patch
Type: text/x-patch
Size: 3560 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220702/61178efb/attachment-0001.bin>


More information about the cfe-commits mailing list