forked from OSchip/llvm-project
[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
This commit is contained in:
parent
23f56132da
commit
ed801ad5e5
|
@ -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"}
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
=====================================
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue