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:
Axel Naumann 2023-01-12 16:20:40 +01:00 committed by jenkins
parent 1b6158779e
commit 8a87d1f8d6
3 changed files with 30 additions and 4 deletions

View File

@ -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())

View File

@ -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

View File

@ -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,