summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ExecutionEngine/JITSymbolFlags.h11
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h2
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp10
-rw-r--r--llvm/test/ExecutionEngine/OrcLazy/common-symbols.ll18
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*, ...)
OpenPOWER on IntegriCloud