JIT: find existing weak symbol without materializer:
m_JIT.getSymbolAddress() invokes the symbol materializers, which compile (which is sort of okay) but also try autoloading (which totally is not okay). Instead, implement a function to search existing JIT symbols. This can be accelerated by looking up the whole set of symbols, instead of doing it symbol by symbol. I leave that refactoring for later...
This commit is contained in:
parent
1b6158779e
commit
8a87d1f8d6
@ -267,9 +267,17 @@ namespace {
|
||||
if (!GV.isDiscardableIfUnused(LT) || !GV.isWeakForLinker(LT))
|
||||
return false;
|
||||
|
||||
// Find the symbol as existing, previously compiled symbol in the JIT,
|
||||
// or in shared libraries (without auto-loading).
|
||||
return (m_JIT.getSymbolAddress(GV.getName(), /*IncludeHostSyms*/ true));
|
||||
// Find the symbol as existing, previously compiled symbol in the JIT...
|
||||
if (m_JIT.doesSymbolAlreadyExist(GV.getName()))
|
||||
return true;
|
||||
|
||||
// ...or in shared libraries (without auto-loading).
|
||||
std::string Name = GV.getName().str();
|
||||
#if !defined(_WIN32)
|
||||
return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(Name);
|
||||
#else
|
||||
return platform::DLSym(Name);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool runOnVar(GlobalVariable& GV) {
|
||||
@ -310,6 +318,7 @@ namespace {
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
bool ret = false;
|
||||
// FIXME: use SymbolLookupSet, rather than looking up symbol by symbol.
|
||||
for (auto &&F: M)
|
||||
ret |= runOnFunc(F);
|
||||
for (auto &&G: M.globals())
|
||||
|
@ -504,6 +504,10 @@ llvm::Error IncrementalJIT::removeModule(const Transaction& T) {
|
||||
m_ResourceTrackers.erase(&T);
|
||||
if (Error Err = RT->remove())
|
||||
return Err;
|
||||
auto iMod = m_CompiledModules.find(T.m_CompiledModule);
|
||||
if (iMod != m_CompiledModules.end())
|
||||
m_CompiledModules.erase(iMod);
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
@ -550,7 +554,7 @@ IncrementalJIT::addOrReplaceDefinition(StringRef Name,
|
||||
return KnownAddr;
|
||||
}
|
||||
|
||||
void* IncrementalJIT::getSymbolAddress(StringRef Name, bool IncludeHostSymbols) {
|
||||
void* IncrementalJIT::getSymbolAddress(StringRef Name, bool IncludeHostSymbols){
|
||||
std::unique_lock<SharedAtomicFlag> G(SkipHostProcessLookup, std::defer_lock);
|
||||
if (!IncludeHostSymbols)
|
||||
G.lock();
|
||||
@ -577,4 +581,13 @@ void* IncrementalJIT::getSymbolAddress(StringRef Name, bool IncludeHostSymbols)
|
||||
return jitTargetAddressToPointer<void*>(Symbol->getAddress());
|
||||
}
|
||||
|
||||
bool IncrementalJIT::doesSymbolAlreadyExist(StringRef UnmangledName) {
|
||||
auto Name = Jit->mangle(UnmangledName);
|
||||
for (auto &&M: m_CompiledModules) {
|
||||
if (M.first->getNamedValue(Name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace cling
|
||||
|
@ -78,6 +78,10 @@ public:
|
||||
/// should include symbols from the host process (via dlsym) or not.
|
||||
void* getSymbolAddress(llvm::StringRef Name, bool IncludeHostSymbols);
|
||||
|
||||
/// @brief Check whether the JIT already has emitted or knows how to emit
|
||||
/// a symbol based on its IR name (as coming from clang's mangler).
|
||||
bool doesSymbolAlreadyExist(llvm::StringRef UnmangledName);
|
||||
|
||||
/// Inject a symbol with a known address. Name is not linker mangled, i.e.
|
||||
/// as known by the IR.
|
||||
llvm::JITTargetAddress addOrReplaceDefinition(llvm::StringRef Name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user