diff options
4 files changed, 37 insertions, 4 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/JITSymbolFlags.h b/llvm/include/llvm/ExecutionEngine/JITSymbolFlags.h index 7e1d57dabc8..ba76695c953 100644 --- a/llvm/include/llvm/ExecutionEngine/JITSymbolFlags.h +++ b/llvm/include/llvm/ExecutionEngine/JITSymbolFlags.h @@ -23,7 +23,8 @@ namespace llvm { enum class JITSymbolFlags : char { None = 0, Weak = 1U << 0, - Exported = 1U << 1 + Common = 1U << 1, + Exported = 1U << 2 }; inline JITSymbolFlags operator|(JITSymbolFlags LHS, JITSymbolFlags RHS) { @@ -59,6 +60,10 @@ public: return (Flags & JITSymbolFlags::Weak) == JITSymbolFlags::Weak; } + bool isCommon() const { + return (Flags & JITSymbolFlags::Common) == JITSymbolFlags::Common; + } + bool isExported() const { return (Flags & JITSymbolFlags::Exported) == JITSymbolFlags::Exported; } @@ -67,6 +72,8 @@ public: JITSymbolFlags Flags = JITSymbolFlags::None; if (GV.hasWeakLinkage()) Flags |= JITSymbolFlags::Weak; + if (GV.hasCommonLinkage()) + Flags |= JITSymbolFlags::Common; if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) Flags |= JITSymbolFlags::Exported; return Flags; @@ -77,6 +84,8 @@ public: JITSymbolFlags Flags = JITSymbolFlags::None; if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak) Flags |= JITSymbolFlags::Weak; + if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common) + Flags |= JITSymbolFlags::Common; if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported) Flags |= JITSymbolFlags::Exported; return Flags; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 1435c86326e..0e8b5ca5976 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -122,10 +122,10 @@ private: RTDyld.setProcessAllSections(PFC->ProcessAllSections); PFC->RTDyld = &RTDyld; + this->Finalized = true; PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects), [&]() { this->updateSymbolTable(RTDyld); - this->Finalized = true; }); // Release resources. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 1e0903349ef..1b40329eb19 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -584,13 +584,19 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, return NameOrErr.takeError(); // Skip common symbols already elsewhere. - if (GlobalSymbolTable.count(Name) || - Resolver.findSymbolInLogicalDylib(Name)) { + if (GlobalSymbolTable.count(Name)) { DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name << "'\n"); continue; } + if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) { + if (!Sym.isCommon()) { + DEBUG(dbgs() << "\tSkipping common symbol '" << Name + << "' in favor of stronger definition.\n"); + continue; + } + } uint32_t Align = Sym.getAlignment(); uint64_t Size = Sym.getCommonSize(); diff --git a/llvm/test/ExecutionEngine/OrcLazy/common-symbols.ll b/llvm/test/ExecutionEngine/OrcLazy/common-symbols.ll new file mode 100644 index 00000000000..ece490ae8c8 --- /dev/null +++ b/llvm/test/ExecutionEngine/OrcLazy/common-symbols.ll @@ -0,0 +1,18 @@ +; RUN: lli -jit-kind=orc-lazy %s | FileCheck %s +; +; CHECK: 7 + +@x = common global i32 0, align 4 +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + store i32 7, i32* @x, align 4 + %0 = load i32, i32* @x, align 4 + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0) + ret i32 0 +} + +declare i32 @printf(i8*, ...) |