[llvm] r277896 - [ORC] Add (partial) weak symbol support to the CompileOnDemand layer.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 5 17:54:44 PDT 2016


Author: lhames
Date: Fri Aug  5 19:54:43 2016
New Revision: 277896

URL: http://llvm.org/viewvc/llvm-project?rev=277896&view=rev
Log:
[ORC] Add (partial) weak symbol support to the CompileOnDemand layer.

This adds partial support for weak functions to the CompileOnDemandLayer by
modifying the addLogicalModule method to check for existing stub definitions
before building a new stub for a weak function. This scheme is sufficient to
support ODR definitions, but fails for general weak definitions if strong
definition is encountered after the first weak definition. (A more extensive
refactor will be required to fully support weak symbols).

This patch does *not* add weak symbol support to RuntimeDyld: I hope to add
that in the near future.


Added:
    llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/
    llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/weak-function-2.ll
    llvm/trunk/test/ExecutionEngine/OrcLazy/weak-function.ll
Modified:
    llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
    llvm/trunk/lib/ExecutionEngine/JITSymbol.cpp
    llvm/trunk/tools/lli/OrcLazyJIT.cpp
    llvm/trunk/tools/lli/OrcLazyJIT.h

Modified: llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h?rev=277896&r1=277895&r2=277896&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h Fri Aug  5 19:54:43 2016
@@ -59,6 +59,10 @@ public:
     return (Flags & Common) == Common;
   }
 
+  bool isStrongDefinition() const {
+    return !isWeak() && !isCommon();
+  }
+
   /// @brief Returns true is the Weak flag is set.
   bool isExported() const {
     return (Flags & Exported) == Exported;

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=277896&r1=277895&r2=277896&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Fri Aug  5 19:54:43 2016
@@ -281,12 +281,20 @@ private:
     // Create stub functions.
     const DataLayout &DL = SrcM.getDataLayout();
     {
+      LMResources.StubsMgr = CreateIndirectStubsManager();
+
       typename IndirectStubsMgrT::StubInitsMap StubInits;
       for (auto &F : SrcM) {
         // Skip declarations.
         if (F.isDeclaration())
           continue;
 
+        // Skip weak functions for which we already have definitions.
+        auto MangledName = mangle(F.getName(), DL);
+        if (F.hasWeakLinkage() || F.hasLinkOnceLinkage())
+          if (auto Sym = LD.findSymbol(MangledName, false))
+            continue;
+
         // Record all functions defined by this module.
         if (CloneStubsIntoPartitions)
           LMResources.StubsToClone.insert(&F);
@@ -295,7 +303,7 @@ private:
         // and set the compile action to compile the partition containing the
         // function.
         auto CCInfo = CompileCallbackMgr.getCompileCallback();
-        StubInits[mangle(F.getName(), DL)] =
+        StubInits[MangledName] =
           std::make_pair(CCInfo.getAddress(),
                          JITSymbolFlags::fromGlobalValue(F));
         CCInfo.setCompileAction([this, &LD, LMH, &F]() {
@@ -303,7 +311,6 @@ private:
         });
       }
 
-      LMResources.StubsMgr = CreateIndirectStubsManager();
       auto EC = LMResources.StubsMgr->createStubs(StubInits);
       (void)EC;
       // FIXME: This should be propagated back to the user. Stub creation may
@@ -383,8 +390,7 @@ private:
     // Build a resolver for the globals module and add it to the base layer.
     auto GVsResolver = createLambdaResolver(
         [&LD, LMH](const std::string &Name) {
-          auto &LMResources = LD.getLogicalModuleResources(LMH);
-          if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
+          if (auto Sym = LD.findSymbol(Name, false))
             return Sym;
           auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
           return LDResolver->findSymbolInLogicalDylib(Name);

Modified: llvm/trunk/lib/ExecutionEngine/JITSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITSymbol.cpp?rev=277896&r1=277895&r2=277896&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JITSymbol.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JITSymbol.cpp Fri Aug  5 19:54:43 2016
@@ -19,7 +19,7 @@ using namespace llvm;
 
 JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
   JITSymbolFlags Flags = JITSymbolFlags::None;
-  if (GV.hasWeakLinkage())
+  if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
     Flags |= JITSymbolFlags::Weak;
   if (GV.hasCommonLinkage())
     Flags |= JITSymbolFlags::Common;

Added: llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/weak-function-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/weak-function-2.ll?rev=277896&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/weak-function-2.ll (added)
+++ llvm/trunk/test/ExecutionEngine/OrcLazy/Inputs/weak-function-2.ll Fri Aug  5 19:54:43 2016
@@ -0,0 +1,13 @@
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+; Function Attrs: nounwind ssp uwtable
+define linkonce_odr i32 @baz() #0 {
+entry:
+  ret i32 0
+}
+
+define i8* @bar() {
+entry:
+  ret i8* bitcast (i32 ()* @baz to i8*)
+}

Added: llvm/trunk/test/ExecutionEngine/OrcLazy/weak-function.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/weak-function.ll?rev=277896&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/OrcLazy/weak-function.ll (added)
+++ llvm/trunk/test/ExecutionEngine/OrcLazy/weak-function.ll Fri Aug  5 19:54:43 2016
@@ -0,0 +1,28 @@
+; RUN: lli -jit-kind=orc-lazy -extra-module %p/Inputs/weak-function-2.ll %s
+;
+; Check that functions in two different modules agree on the address of weak
+; function 'baz'
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+define linkonce_odr i32 @baz() {
+entry:
+  ret i32 0
+}
+
+define i8* @foo() {
+entry:
+  ret i8* bitcast (i32 ()* @baz to i8*)
+}
+
+declare i8* @bar()
+
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+  %call = tail call i8* @foo()
+  %call1 = tail call i8* @bar()
+  %cmp = icmp ne i8* %call, %call1
+  %conv = zext i1 %cmp to i32
+  ret i32 %conv
+}
+

Modified: llvm/trunk/tools/lli/OrcLazyJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/OrcLazyJIT.cpp?rev=277896&r1=277895&r2=277896&view=diff
==============================================================================
--- llvm/trunk/tools/lli/OrcLazyJIT.cpp (original)
+++ llvm/trunk/tools/lli/OrcLazyJIT.cpp Fri Aug  5 19:54:43 2016
@@ -144,8 +144,7 @@ int llvm::runOrcLazyJIT(std::vector<std:
                OrcInlineStubs);
 
   // Add the module, look up main and run it.
-  for (auto &M : Ms)
-    J.addModule(std::move(M));
+  J.addModuleSet(std::move(Ms));
   auto MainSym = J.findSymbol("main");
 
   if (!MainSym) {

Modified: llvm/trunk/tools/lli/OrcLazyJIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/OrcLazyJIT.h?rev=277896&r1=277895&r2=277896&view=diff
==============================================================================
--- llvm/trunk/tools/lli/OrcLazyJIT.h (original)
+++ llvm/trunk/tools/lli/OrcLazyJIT.h Fri Aug  5 19:54:43 2016
@@ -38,7 +38,7 @@ public:
   typedef orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr> CODLayerT;
   typedef CODLayerT::IndirectStubsManagerBuilderT
     IndirectStubsManagerBuilder;
-  typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
+  typedef CODLayerT::ModuleSetHandleT ModuleSetHandleT;
 
   OrcLazyJIT(std::unique_ptr<TargetMachine> TM,
              std::unique_ptr<CompileCallbackMgr> CCMgr,
@@ -62,18 +62,21 @@ public:
       DtorRunner.runViaLayer(CODLayer);
   }
 
-  ModuleHandleT addModule(std::unique_ptr<Module> M) {
-    // Attach a data-layout if one isn't already present.
-    if (M->getDataLayout().isDefault())
-      M->setDataLayout(DL);
+  ModuleSetHandleT addModuleSet(std::vector<std::unique_ptr<Module>> Ms) {
+    // Attach a data-layouts if they aren't already present.
+    for (auto &M : Ms)
+      if (M->getDataLayout().isDefault())
+        M->setDataLayout(DL);
 
     // Record the static constructors and destructors. We have to do this before
     // we hand over ownership of the module to the JIT.
     std::vector<std::string> CtorNames, DtorNames;
-    for (auto Ctor : orc::getConstructors(*M))
-      CtorNames.push_back(mangle(Ctor.Func->getName()));
-    for (auto Dtor : orc::getDestructors(*M))
-      DtorNames.push_back(mangle(Dtor.Func->getName()));
+    for (auto &M : Ms) {
+      for (auto Ctor : orc::getConstructors(*M))
+        CtorNames.push_back(mangle(Ctor.Func->getName()));
+      for (auto Dtor : orc::getDestructors(*M))
+        DtorNames.push_back(mangle(Dtor.Func->getName()));
+    }
 
     // Symbol resolution order:
     //   1) Search the JIT symbols.
@@ -84,24 +87,18 @@ public:
         [this](const std::string &Name) -> JITSymbol {
           if (auto Sym = CODLayer.findSymbol(Name, true))
             return Sym;
-          if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
-            return Sym;
-
+          return CXXRuntimeOverrides.searchOverrides(Name);
+        },
+        [](const std::string &Name) {
           if (auto Addr =
               RTDyldMemoryManager::getSymbolAddressInProcess(Name))
             return JITSymbol(Addr, JITSymbolFlags::Exported);
-
-          return JITSymbol(nullptr);
-        },
-        [](const std::string &Name) {
           return JITSymbol(nullptr);
         }
       );
 
     // Add the module to the JIT.
-    std::vector<std::unique_ptr<Module>> S;
-    S.push_back(std::move(M));
-    auto H = CODLayer.addModuleSet(std::move(S),
+    auto H = CODLayer.addModuleSet(std::move(Ms),
 				   llvm::make_unique<SectionMemoryManager>(),
 				   std::move(Resolver));
 
@@ -119,7 +116,7 @@ public:
     return CODLayer.findSymbol(mangle(Name), true);
   }
 
-  JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
+  JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name) {
     return CODLayer.findSymbolIn(H, mangle(Name), true);
   }
 




More information about the llvm-commits mailing list