[llvm] ed801ad - [Clang] Use metadata to make identifying embedded objects easier
Joseph Huber via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 7 09:20:52 PDT 2022
Author: Joseph Huber
Date: 2022-07-07T12:20:25-04:00
New Revision: ed801ad5e5fef76c4303d04fd8de21662b428bee
URL: https://github.com/llvm/llvm-project/commit/ed801ad5e5fef76c4303d04fd8de21662b428bee
DIFF: https://github.com/llvm/llvm-project/commit/ed801ad5e5fef76c4303d04fd8de21662b428bee.diff
LOG: [Clang] Use metadata to make identifying embedded objects easier
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.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D129033
Added:
Modified:
clang/test/Frontend/embed-object.c
clang/test/Frontend/embed-object.ll
clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
llvm/docs/LangRef.rst
llvm/include/llvm/Transforms/Utils/ModuleUtils.h
llvm/lib/Transforms/Utils/ModuleUtils.cpp
Removed:
################################################################################
diff --git a/clang/test/Frontend/embed-object.c b/clang/test/Frontend/embed-object.c
index ceb3378a60ab..364cb8aad193 100644
--- a/clang/test/Frontend/embed-object.c
+++ b/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.objects = !{![[METADATA:[0-9]+]]}
+// CHECK: ![[METADATA]] = !{ptr @[[OBJECT]], !".llvm.offloading"}
diff --git a/clang/test/Frontend/embed-object.ll b/clang/test/Frontend/embed-object.ll
index 177ecdf7f8a3..bcb56fd55c73 100644
--- a/clang/test/Frontend/embed-object.ll
+++ b/clang/test/Frontend/embed-object.ll
@@ -13,3 +13,7 @@
define i32 @foo() {
ret i32 0
}
+
+; CHECK: !llvm.embedded.objects = !{![[METADATA_1:[0-9]+]], ![[METADATA_2:[0-9]+]]}
+; CHECK: ![[METADATA_1]] = !{ptr @[[OBJECT_1]], !".llvm.offloading"}
+; CHECK: ![[METADATA_2]] = !{ptr @[[OBJECT_2]], !".llvm.offloading"}
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 3e935bcbd30a..e7214ebfde37 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -366,12 +366,26 @@ Error extractFromBitcode(std::unique_ptr<MemoryBuffer> Buffer,
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");
+ if (!MD)
+ return Error::success();
+
+ for (const MDNode *Op : MD->operands()) {
+ if (Op->getNumOperands() < 2)
+ continue;
+
+ 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());
+ auto *CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer());
if (!CDS)
continue;
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 889eca2f438b..e74aaa8d77cf 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -7429,6 +7429,19 @@ Some optimisations are only when the entire LTO unit is present in the current
module. This is represented by the ``LTOPostLink`` module flags metadata, which
will be created with a value of ``1`` when LTO linking occurs.
+Embedded Objects Names Metadata
+===============================
+
+Offloading compilations need to embed device code into the host section table to
+create a fat binary. This metadata node references each global that will be
+embedded in the module. The primary use for this is to make referencing these
+globals more efficient in the IR. The metadata references nodes containing
+pointers to the global to be embedded followed by the section name it will be
+stored at::
+
+ !llvm.embedded.objects = !{!0}
+ !0 = !{ptr @object, !".section"}
+
Automatic Linker Flags Named Metadata
=====================================
diff --git a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
index 85263fc00bc3..335cf7acc2f7 100644
--- a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -109,7 +109,8 @@ void filterDeadComdatFunctions(
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 a 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));
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 5120ade70e16..a3529bfd2e43 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -275,5 +275,12 @@ void llvm::embedBufferInModule(Module &M, MemoryBufferRef Buf,
GV->setSection(SectionName);
GV->setAlignment(Alignment);
+ LLVMContext &Ctx = M.getContext();
+ NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.embedded.objects");
+ Metadata *MDVals[] = {ConstantAsMetadata::get(GV),
+ MDString::get(Ctx, SectionName)};
+
+ MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+
appendToCompilerUsed(M, GV);
}
More information about the llvm-commits
mailing list