diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 161a30e44616..26f77acd91fc 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -214,8 +214,9 @@ public: Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { // Add passes to mark duplicate defs as should-discard, and to walk the // link graph to build the symbol dependence graph. - Config.PrePrunePasses.push_back( - [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); + Config.PrePrunePasses.push_back([this](LinkGraph &G) { + return claimOrExternalizeWeakAndCommonSymbols(G); + }); Layer.modifyPassConfig(*MR, TT, Config); @@ -233,19 +234,38 @@ private: using LocalSymbolNamedDependenciesMap = DenseMap; - Error externalizeWeakAndCommonSymbols(LinkGraph &G) { + Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) { auto &ES = Layer.getExecutionSession(); - for (auto *Sym : G.defined_symbols()) - if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR->getSymbols().count(ES.intern(Sym->getName()))) - G.makeExternal(*Sym); - } - for (auto *Sym : G.absolute_symbols()) + SymbolFlagsMap NewSymbolsToClaim; + std::vector> NameToSym; + + auto ProcessSymbol = [&](Symbol *Sym) { if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR->getSymbols().count(ES.intern(Sym->getName()))) - G.makeExternal(*Sym); + auto Name = ES.intern(Sym->getName()); + if (!MR->getSymbols().count(ES.intern(Sym->getName()))) { + JITSymbolFlags SF = JITSymbolFlags::Weak; + if (Sym->getScope() == Scope::Default) + SF |= JITSymbolFlags::Exported; + NewSymbolsToClaim[Name] = SF; + NameToSym.push_back(std::make_pair(std::move(Name), Sym)); + } } + }; + + for (auto *Sym : G.defined_symbols()) + ProcessSymbol(Sym); + for (auto *Sym : G.absolute_symbols()) + ProcessSymbol(Sym); + + // Attempt to claim all weak defs that we're not already responsible for. + // This cannot fail -- any clashes will just result in rejection of our + // claim, at which point we'll externalize that symbol. + cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim))); + + for (auto &KV : NameToSym) + if (!MR->getSymbols().count(KV.first)) + G.makeExternal(*KV.second); return Error::success(); }