aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Frontend
diff options
context:
space:
mode:
authorJoseph Huber <huberjn@outlook.com>2023-11-21 06:48:34 -0600
committerGitHub <noreply@github.com>2023-11-21 06:48:34 -0600
commit52204a29aba2ca8a10f0bd1b5d5c3b8e0b8fa082 (patch)
treecdd0900d5b092b320852864e451dd921ae20461e /llvm/lib/Frontend
parent72d3bf2b87ff7fab1a189d76f516bc03eac3271d (diff)
downloadllvm-52204a29aba2ca8a10f0bd1b5d5c3b8e0b8fa082.zip
llvm-52204a29aba2ca8a10f0bd1b5d5c3b8e0b8fa082.tar.gz
llvm-52204a29aba2ca8a10f0bd1b5d5c3b8e0b8fa082.tar.bz2
[Offload] Initial support for registering offloading entries on COFF targets (#72697)
Summary: This patch provides the initial support to allow handling the new driver's offloading entries. Normally, the ELF target can emit varibles at C-identifier named sections and the linker will provide a pointer to the section. For COFF target, instead the linker merges sections containing a `$` in alphabetical order. We thus can emit these variables at sections and then emit two variables that are guaranteed to be sorted before and after the others to traverse it. Previous patches consolidated the handling of offloading entries so that this patch more easily can handle mapping them to the appropriate section. Ideally, the only remaining step to allow the new driver to run on Windows targets is to accurately map the following `ld.lld` arguments to their `llvm-link` equivalents. These are used inside the linker-wrapper, so we should simply need to remap the arguments to the same functionality if possible. ``` -o, -output -l, --library -L, --library-path -v, --version -rpath -whole-archive, -no-whole-archive ``` I have not tested this at runtime as I do not have access to a windows machine. This patch was adapted from some initial efforts in https://reviews.llvm.org/D137470.
Diffstat (limited to 'llvm/lib/Frontend')
-rw-r--r--llvm/lib/Frontend/Offloading/CMakeLists.txt1
-rw-r--r--llvm/lib/Frontend/Offloading/Utility.cpp68
2 files changed, 42 insertions, 27 deletions
diff --git a/llvm/lib/Frontend/Offloading/CMakeLists.txt b/llvm/lib/Frontend/Offloading/CMakeLists.txt
index 25eb247..2d0117c 100644
--- a/llvm/lib/Frontend/Offloading/CMakeLists.txt
+++ b/llvm/lib/Frontend/Offloading/CMakeLists.txt
@@ -11,4 +11,5 @@ add_llvm_component_library(LLVMFrontendOffloading
Core
Support
TransformUtils
+ TargetParser
)
diff --git a/llvm/lib/Frontend/Offloading/Utility.cpp b/llvm/lib/Frontend/Offloading/Utility.cpp
index 340d146..1c08f02 100644
--- a/llvm/lib/Frontend/Offloading/Utility.cpp
+++ b/llvm/lib/Frontend/Offloading/Utility.cpp
@@ -15,7 +15,6 @@
using namespace llvm;
using namespace llvm::offloading;
-// TODO: Export this to the linker wrapper code registration.
StructType *offloading::getEntryTy(Module &M) {
LLVMContext &C = M.getContext();
StructType *EntryTy =
@@ -32,6 +31,8 @@ StructType *offloading::getEntryTy(Module &M) {
void offloading::emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
uint64_t Size, int32_t Flags,
StringRef SectionName) {
+ llvm::Triple Triple(M.getTargetTriple());
+
Type *Int8PtrTy = PointerType::getUnqual(M.getContext());
Type *Int32Ty = Type::getInt32Ty(M.getContext());
Type *SizeTy = M.getDataLayout().getIntPtrType(M.getContext());
@@ -39,11 +40,10 @@ void offloading::emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
// Create the constant string used to look up the symbol in the device.
- auto *Str =
- new llvm::GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
- llvm::GlobalValue::InternalLinkage, AddrName,
- ".omp_offloading.entry_name");
- Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+ auto *Str = new GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
+ GlobalValue::InternalLinkage, AddrName,
+ ".omp_offloading.entry_name");
+ Str->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
// Construct the offloading entry.
Constant *EntryData[] = {
@@ -62,35 +62,49 @@ void offloading::emitOffloadingEntry(Module &M, Constant *Addr, StringRef Name,
M.getDataLayout().getDefaultGlobalsAddressSpace());
// The entry has to be created in the section the linker expects it to be.
- Entry->setSection(SectionName);
+ if (Triple.isOSBinFormatCOFF())
+ Entry->setSection((SectionName + "$OE").str());
+ else
+ Entry->setSection(SectionName);
Entry->setAlignment(Align(1));
}
std::pair<GlobalVariable *, GlobalVariable *>
offloading::getOffloadEntryArray(Module &M, StringRef SectionName) {
- auto *EntriesB =
- new GlobalVariable(M, ArrayType::get(getEntryTy(M), 0),
- /*isConstant=*/true, GlobalValue::ExternalLinkage,
- /*Initializer=*/nullptr, "__start_" + SectionName);
+ llvm::Triple Triple(M.getTargetTriple());
+
+ auto *ZeroInitilaizer =
+ ConstantAggregateZero::get(ArrayType::get(getEntryTy(M), 0u));
+ auto *EntryInit = Triple.isOSBinFormatCOFF() ? ZeroInitilaizer : nullptr;
+ auto *EntryType = ArrayType::get(getEntryTy(M), 0);
+
+ auto *EntriesB = new GlobalVariable(M, EntryType, /*isConstant=*/true,
+ GlobalValue::ExternalLinkage, EntryInit,
+ "__start_" + SectionName);
EntriesB->setVisibility(GlobalValue::HiddenVisibility);
- auto *EntriesE =
- new GlobalVariable(M, ArrayType::get(getEntryTy(M), 0),
- /*isConstant=*/true, GlobalValue::ExternalLinkage,
- /*Initializer=*/nullptr, "__stop_" + SectionName);
+ auto *EntriesE = new GlobalVariable(M, EntryType, /*isConstant=*/true,
+ GlobalValue::ExternalLinkage, EntryInit,
+ "__stop_" + SectionName);
EntriesE->setVisibility(GlobalValue::HiddenVisibility);
- // We assume that external begin/end symbols that we have created above will
- // be defined by the linker. But linker will do that only if linker inputs
- // have section with "omp_offloading_entries" name which is not guaranteed.
- // So, we just create dummy zero sized object in the offload entries section
- // to force linker to define those symbols.
- auto *DummyInit =
- ConstantAggregateZero::get(ArrayType::get(getEntryTy(M), 0u));
- auto *DummyEntry = new GlobalVariable(M, DummyInit->getType(), true,
- GlobalVariable::ExternalLinkage,
- DummyInit, "__dummy." + SectionName);
- DummyEntry->setSection(SectionName);
- DummyEntry->setVisibility(GlobalValue::HiddenVisibility);
+ if (Triple.isOSBinFormatELF()) {
+ // We assume that external begin/end symbols that we have created above will
+ // be defined by the linker. This is done whenever a section name with a
+ // valid C-identifier is present. We define a dummy variable here to force
+ // the linker to always provide these symbols.
+ auto *DummyEntry = new GlobalVariable(
+ M, ZeroInitilaizer->getType(), true, GlobalVariable::ExternalLinkage,
+ ZeroInitilaizer, "__dummy." + SectionName);
+ DummyEntry->setSection(SectionName);
+ DummyEntry->setVisibility(GlobalValue::HiddenVisibility);
+ } else {
+ // The COFF linker will merge sections containing a '$' together into a
+ // single section. The order of entries in this section will be sorted
+ // alphabetically by the characters following the '$' in the name. Set the
+ // sections here to ensure that the beginning and end symbols are sorted.
+ EntriesB->setSection((SectionName + "$OA").str());
+ EntriesE->setSection((SectionName + "$OZ").str());
+ }
return std::make_pair(EntriesB, EntriesE);
}