[ORC] Promote and rename private symbols inside the CompileOnDemand layer,
authorLang Hames <lhames@gmail.com>
Tue, 9 Oct 2018 20:44:32 +0000 (20:44 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 9 Oct 2018 20:44:32 +0000 (20:44 +0000)
rather than require them to have been promoted before being passed in.

Dropping this precondition is better for layer composition (CompileOnDemandLayer
was the only one that placed pre-conditions on the modules that could be added).
It also means that the promoted private symbols do not show up in the target
JITDylib's symbol table. Instead, they are confined to the hidden implementation
dylib that contains the actual definitions.

For the 403.gcc testcase this cut down the public symbol table size from ~15,000
symbols to ~4000, substantially reducing symbol dependence tracking costs.

llvm-svn: 344078

llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

index a5de16b..2003f8e 100644 (file)
@@ -129,6 +129,7 @@ private:
   IndirectStubsManagerBuilder BuildIndirectStubsManager;
   PerDylibResourcesMap DylibResources;
   PartitionFunction Partition = compileRequested;
+  SymbolLinkagePromoter PromoteSymbols;
 };
 
 /// Compile-on-demand layer.
index 22d3332..c252780 100644 (file)
@@ -427,7 +427,9 @@ void makeStub(Function &F, Value &ImplPointer);
 /// used for all symbols to be added to a single JITDylib.
 class SymbolLinkagePromoter {
 public:
-  void operator()(Module &M);
+  /// Promote symbols in the given module. Returns the set of global values
+  /// that have been renamed/promoted.
+  std::vector<GlobalValue *> operator()(Module &M);
 
 private:
   unsigned NextId = 0;
index 01dae53..400d4cb 100644 (file)
@@ -182,7 +182,6 @@ private:
 
   IRTransformLayer2 TransformLayer;
   CompileOnDemandLayer2 CODLayer;
-  SymbolLinkagePromoter PromoteSymbols;
 };
 
 } // End namespace orc
index 368969b..ae1c7e8 100644 (file)
@@ -134,10 +134,7 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
   SymbolAliasMap NonCallables;
   SymbolAliasMap Callables;
   for (auto &GV : M.global_values()) {
-    assert(GV.hasName() && !GV.hasLocalLinkage() &&
-           "GlobalValues must have been promoted before adding to "
-           "CompileOnDemandLayer");
-    if (GV.isDeclaration() || GV.hasAppendingLinkage())
+    if (GV.isDeclaration() || GV.hasLocalLinkage() || GV.hasAppendingLinkage())
       continue;
 
     auto Name = Mangle(GV.getName());
@@ -259,6 +256,25 @@ void CompileOnDemandLayer2::emitPartition(
     return;
   }
 
+  // Ok -- we actually need to partition the symbols. Promote the symbol
+  // linkages/names.
+  // FIXME: We apply this once per partitioning. It's safe, but overkill.
+  {
+    auto PromotedGlobals = PromoteSymbols(*TSM.getModule());
+    if (!PromotedGlobals.empty()) {
+      MangleAndInterner Mangle(ES, TSM.getModule()->getDataLayout());
+      SymbolFlagsMap SymbolFlags;
+      for (auto &GV : PromotedGlobals)
+        SymbolFlags[Mangle(GV->getName())] =
+            JITSymbolFlags::fromGlobalValue(*GV);
+      if (auto Err = R.defineMaterializing(SymbolFlags)) {
+        ES.reportError(std::move(Err));
+        R.failMaterialization();
+        return;
+      }
+    }
+  }
+
   expandPartition(*GVsToExtract);
 
   // Extract the requested partiton (plus any necessary aliases) and
@@ -268,7 +284,6 @@ void CompileOnDemandLayer2::emitPartition(
   };
 
   auto ExtractedTSM = extractSubModule(TSM, ".submodule", ShouldExtract);
-
   R.replace(llvm::make_unique<PartitioningIRMaterializationUnit>(
       ES, std::move(TSM), *this));
 
index 29c3f4e..47cb273 100644 (file)
@@ -99,6 +99,12 @@ void CtorDtorRunner2::add(iterator_range<CtorDtorIterator> CtorDtors) {
     assert(CtorDtor.Func && CtorDtor.Func->hasName() &&
            "Ctor/Dtor function must be named to be runnable under the JIT");
 
+    // FIXME: Maybe use a symbol promoter here instead.
+    if (CtorDtor.Func->hasLocalLinkage()) {
+      CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage);
+      CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility);
+    }
+
     if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) {
       dbgs() << "  Skipping because why now?\n";
       continue;
index 0acc5db..d7fd57b 100644 (file)
@@ -248,8 +248,11 @@ void makeStub(Function &F, Value &ImplPointer) {
     Builder.CreateRet(Call);
 }
 
-void SymbolLinkagePromoter::operator()(Module &M) {
+std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) {
+  std::vector<GlobalValue *> PromotedGlobals;
+
   for (auto &GV : M.global_values()) {
+    bool Promoted = true;
 
     // Rename if necessary.
     if (!GV.hasName())
@@ -258,13 +261,21 @@ void SymbolLinkagePromoter::operator()(Module &M) {
       GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
     else if (GV.hasLocalLinkage())
       GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
+    else
+      Promoted = false;
 
     if (GV.hasLocalLinkage()) {
       GV.setLinkage(GlobalValue::ExternalLinkage);
       GV.setVisibility(GlobalValue::HiddenVisibility);
+      Promoted = true;
     }
     GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
+
+    if (Promoted)
+      PromotedGlobals.push_back(&GV);
   }
+
+  return PromotedGlobals;
 }
 
 Function* cloneFunctionDecl(Module &Dst, const Function &F,
index 89a302c..47baa45 100644 (file)
@@ -185,8 +185,6 @@ Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
   if (auto Err = applyDataLayout(*TSM.getModule()))
     return Err;
 
-  PromoteSymbols(*TSM.getModule());
-
   recordCtorDtors(*TSM.getModule());
 
   auto K = ES->allocateVModule();