forked from OSchip/llvm-project
[ORC] Coalesce all of ORC's symbol renaming / linkage-promotion utilities into
one SymbolLinkagePromoter utility. SymbolLinkagePromoter renames anonymous and private symbols, and bumps all linkages to at least global/hidden-visibility. Modules whose symbols have been promoted by this utility can be decomposed into sub-modules without introducing link errors. This is used by the CompileOnDemandLayer to extract single-function modules for lazy compilation. llvm-svn: 343257
This commit is contained in:
parent
3ac3c0d717
commit
c5192f751a
|
@ -167,25 +167,6 @@ private:
|
||||||
return llvm::make_unique<RO>(std::move(ResourcePtr));
|
return llvm::make_unique<RO>(std::move(ResourcePtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
class StaticGlobalRenamer {
|
|
||||||
public:
|
|
||||||
StaticGlobalRenamer() = default;
|
|
||||||
StaticGlobalRenamer(StaticGlobalRenamer &&) = default;
|
|
||||||
StaticGlobalRenamer &operator=(StaticGlobalRenamer &&) = default;
|
|
||||||
|
|
||||||
void rename(Module &M) {
|
|
||||||
for (auto &F : M)
|
|
||||||
if (F.hasLocalLinkage())
|
|
||||||
F.setName("$static." + Twine(NextId++));
|
|
||||||
for (auto &G : M.globals())
|
|
||||||
if (G.hasLocalLinkage())
|
|
||||||
G.setName("$static." + Twine(NextId++));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned NextId = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LogicalDylib {
|
struct LogicalDylib {
|
||||||
struct SourceModuleEntry {
|
struct SourceModuleEntry {
|
||||||
std::unique_ptr<Module> SourceMod;
|
std::unique_ptr<Module> SourceMod;
|
||||||
|
@ -239,7 +220,7 @@ private:
|
||||||
VModuleKey K;
|
VModuleKey K;
|
||||||
std::shared_ptr<SymbolResolver> BackingResolver;
|
std::shared_ptr<SymbolResolver> BackingResolver;
|
||||||
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
|
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
|
||||||
StaticGlobalRenamer StaticRenamer;
|
SymbolLinkagePromoter PromoteSymbols;
|
||||||
SourceModulesList SourceModules;
|
SourceModulesList SourceModules;
|
||||||
std::vector<VModuleKey> BaseLayerVModuleKeys;
|
std::vector<VModuleKey> BaseLayerVModuleKeys;
|
||||||
};
|
};
|
||||||
|
@ -361,14 +342,9 @@ public:
|
||||||
private:
|
private:
|
||||||
Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
|
Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
|
||||||
|
|
||||||
// Rename all static functions / globals to $static.X :
|
// Rename anonymous globals and promote linkage to ensure that everything
|
||||||
// This will unique the names across all modules in the logical dylib,
|
// will resolve properly after we partition SrcM.
|
||||||
// simplifying symbol lookup.
|
LD.PromoteSymbols(*SrcMPtr);
|
||||||
LD.StaticRenamer.rename(*SrcMPtr);
|
|
||||||
|
|
||||||
// Bump the linkage and rename any anonymous/private members in SrcM to
|
|
||||||
// ensure that everything will resolve properly after we partition SrcM.
|
|
||||||
makeAllSymbolsExternallyAccessible(*SrcMPtr);
|
|
||||||
|
|
||||||
// Create a logical module handle for SrcM within the logical dylib.
|
// Create a logical module handle for SrcM within the logical dylib.
|
||||||
Module &SrcM = *SrcMPtr;
|
Module &SrcM = *SrcMPtr;
|
||||||
|
|
|
@ -413,12 +413,16 @@ GlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name,
|
||||||
/// indirect call using the given function pointer.
|
/// indirect call using the given function pointer.
|
||||||
void makeStub(Function &F, Value &ImplPointer);
|
void makeStub(Function &F, Value &ImplPointer);
|
||||||
|
|
||||||
/// Raise linkage types and rename as necessary to ensure that all
|
/// Promotes private symbols to global hidden, and renames to prevent clashes
|
||||||
/// symbols are accessible for other modules.
|
/// with other promoted symbols. The same SymbolPromoter instance should be
|
||||||
///
|
/// used for all symbols to be added to a single JITDylib.
|
||||||
/// This should be called before partitioning a module to ensure that the
|
class SymbolLinkagePromoter {
|
||||||
/// partitions retain access to each other's symbols.
|
public:
|
||||||
void makeAllSymbolsExternallyAccessible(Module &M);
|
void operator()(Module &M);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned NextId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/// Clone a function declaration into a new module.
|
/// Clone a function declaration into a new module.
|
||||||
///
|
///
|
||||||
|
|
|
@ -173,6 +173,7 @@ private:
|
||||||
|
|
||||||
IRTransformLayer2 TransformLayer;
|
IRTransformLayer2 TransformLayer;
|
||||||
CompileOnDemandLayer2 CODLayer;
|
CompileOnDemandLayer2 CODLayer;
|
||||||
|
SymbolLinkagePromoter PromoteSymbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End namespace orc
|
} // End namespace orc
|
||||||
|
|
|
@ -246,57 +246,23 @@ void makeStub(Function &F, Value &ImplPointer) {
|
||||||
Builder.CreateRet(Call);
|
Builder.CreateRet(Call);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility class for renaming global values and functions during partitioning.
|
void SymbolLinkagePromoter::operator()(Module &M) {
|
||||||
class GlobalRenamer {
|
for (auto &GV : M.global_values()) {
|
||||||
public:
|
|
||||||
|
|
||||||
static bool needsRenaming(const Value &New) {
|
// Rename if necessary.
|
||||||
return !New.hasName() || New.getName().startswith("\01L");
|
if (!GV.hasName())
|
||||||
}
|
GV.setName("__orc_anon." + Twine(NextId++));
|
||||||
|
else if (GV.getName().startswith("\01L"))
|
||||||
|
GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
|
||||||
|
else if (GV.hasLocalLinkage())
|
||||||
|
GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
|
||||||
|
|
||||||
const std::string& getRename(const Value &Orig) {
|
if (GV.hasLocalLinkage()) {
|
||||||
// See if we have a name for this global.
|
GV.setLinkage(GlobalValue::ExternalLinkage);
|
||||||
{
|
GV.setVisibility(GlobalValue::HiddenVisibility);
|
||||||
auto I = Names.find(&Orig);
|
|
||||||
if (I != Names.end())
|
|
||||||
return I->second;
|
|
||||||
}
|
}
|
||||||
|
GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
|
||||||
// Nope. Create a new one.
|
|
||||||
// FIXME: Use a more robust uniquing scheme. (This may blow up if the user
|
|
||||||
// writes a "__orc_anon[[:digit:]]* method).
|
|
||||||
unsigned ID = Names.size();
|
|
||||||
std::ostringstream NameStream;
|
|
||||||
NameStream << "__orc_anon" << ID++;
|
|
||||||
auto I = Names.insert(std::make_pair(&Orig, NameStream.str()));
|
|
||||||
return I.first->second;
|
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
DenseMap<const Value*, std::string> Names;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
|
|
||||||
if (V.hasLocalLinkage()) {
|
|
||||||
if (R.needsRenaming(V))
|
|
||||||
V.setName(R.getRename(V));
|
|
||||||
V.setLinkage(GlobalValue::ExternalLinkage);
|
|
||||||
V.setVisibility(GlobalValue::HiddenVisibility);
|
|
||||||
}
|
|
||||||
V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
|
|
||||||
assert(!R.needsRenaming(V) && "Invalid global name.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeAllSymbolsExternallyAccessible(Module &M) {
|
|
||||||
GlobalRenamer Renamer;
|
|
||||||
|
|
||||||
for (auto &F : M)
|
|
||||||
raiseVisibilityOnValue(F, Renamer);
|
|
||||||
|
|
||||||
for (auto &GV : M.globals())
|
|
||||||
raiseVisibilityOnValue(GV, Renamer);
|
|
||||||
|
|
||||||
for (auto &A : M.aliases())
|
|
||||||
raiseVisibilityOnValue(A, Renamer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Function* cloneFunctionDecl(Module &Dst, const Function &F,
|
Function* cloneFunctionDecl(Module &Dst, const Function &F,
|
||||||
|
|
|
@ -181,7 +181,7 @@ Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
|
||||||
if (auto Err = applyDataLayout(*TSM.getModule()))
|
if (auto Err = applyDataLayout(*TSM.getModule()))
|
||||||
return Err;
|
return Err;
|
||||||
|
|
||||||
makeAllSymbolsExternallyAccessible(*TSM.getModule());
|
PromoteSymbols(*TSM.getModule());
|
||||||
|
|
||||||
recordCtorDtors(*TSM.getModule());
|
recordCtorDtors(*TSM.getModule());
|
||||||
|
|
||||||
|
|
|
@ -816,7 +816,6 @@ int runOrcLazyJIT(const char *ProgName) {
|
||||||
if (!M)
|
if (!M)
|
||||||
reportError(Err, ProgName);
|
reportError(Err, ProgName);
|
||||||
|
|
||||||
orc::makeAllSymbolsExternallyAccessible(*M);
|
|
||||||
ExitOnErr(J->addLazyIRModule(orc::ThreadSafeModule(std::move(M), TSCtx)));
|
ExitOnErr(J->addLazyIRModule(orc::ThreadSafeModule(std::move(M), TSCtx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue