14#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
15#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
23#include <shared_mutex>
24#include <unordered_map>
44 std::optional<BloomFilter> Filter = std::nullopt)
45 : FilePath(
std::
move(FilePath)), S(S), K(K), Filter(
std::
move(Filter)) {
54 std::lock_guard<std::shared_mutex> Lock(Mtx);
57 Filter.emplace(std::move(
F));
62 std::lock_guard<std::shared_mutex> Lock(Mtx);
65 Filter.emplace(FB.
build(Symbols));
70 std::shared_lock<std::shared_mutex> Lock(Mtx);
71 return Filter->mayContain(Symbol);
75 std::shared_lock<std::shared_mutex> Lock(Mtx);
76 return Filter.has_value();
85 return FilePath == other.FilePath;
90 std::atomic<LibState> S;
92 std::optional<BloomFilter>
Filter;
93 mutable std::shared_mutex Mtx;
107 : it(it_), end(end_), S(S), K(K) {
112 return it != other.it;
127 for (; it !=
end; ++it)
128 if (it->second->getState() == S && it->second->getKind() == K)
137 : mapBegin(
begin), mapEnd(
end), state(s), kind(k) {}
156 mutable std::shared_mutex Mtx;
165 std::optional<BloomFilter>
Filter = std::nullopt) {
166 std::unique_lock<std::shared_mutex> Lock(Mtx);
167 if (Libraries.count(Path) > 0)
169 Libraries.insert({std::move(Path),
171 Kind, std::move(
Filter))});
176 std::shared_lock<std::shared_mutex> Lock(Mtx);
177 if (Libraries.count(Path) > 0)
183 std::unique_lock<std::shared_mutex> Lock(Mtx);
184 auto I = Libraries.find(Path);
185 if (
I == Libraries.end())
191 std::unique_lock<std::shared_mutex> Lock(Mtx);
192 if (
auto It = Libraries.find(Path); It != Libraries.end())
197 std::unique_lock<std::shared_mutex> Lock(Mtx);
198 if (
auto It = Libraries.find(Path); It != Libraries.end())
203 std::shared_lock<std::shared_mutex> Lock(Mtx);
204 if (
auto It = Libraries.find(Path); It != Libraries.end())
210 std::shared_lock<std::shared_mutex> Lock(Mtx);
211 return FilteredView(Libraries.begin(), Libraries.end(), S, K);
215 std::unique_lock<std::shared_mutex> Lock(Mtx);
216 for (
const auto &[
_, entry] : Libraries) {
217 if (!visitor(*entry))
223 std::unique_lock<std::shared_mutex> Lock(Mtx);
224 if (
auto It = Libraries.find(Path.str()); It != Libraries.end())
230 std::unique_lock<std::shared_mutex> Lock(Mtx);
231 if (
auto It = Libraries.find(Path.str()); It != Libraries.end())
237 std::unique_lock<std::shared_mutex> Lock(Mtx);
250 std::vector<SearchPlanEntry>
Plan;
321 mutable std::shared_mutex Mtx;
323 std::atomic<size_t> ResolvedCount = 0;
327 for (
const auto &s : Symbols) {
328 if (!Results.contains(s))
329 Results.insert({s,
Result{s,
""}});
335 std::shared_lock<std::shared_mutex> Lock(Mtx);
336 for (
const auto &[
name, res] : Results) {
337 if (res.ResolvedLibPath.empty())
344 std::unique_lock<std::shared_mutex> Lock(Mtx);
345 auto It = Results.find(Sym);
346 if (It != Results.end() && It->second.ResolvedLibPath.empty()) {
347 It->second.ResolvedLibPath = LibPath;
348 ResolvedCount.fetch_add(1, std::memory_order_relaxed);
353 return ResolvedCount.load(std::memory_order_relaxed) == Results.size();
357 return ResolvedCount.load(std::memory_order_relaxed) < Results.size();
361 std::shared_lock<std::shared_mutex> Lock(Mtx);
362 auto It = Results.find(Sym);
363 if (It != Results.end() && !It->second.ResolvedLibPath.empty())
364 return StringRef(It->second.ResolvedLibPath);
369 std::shared_lock<std::shared_mutex> Lock(Mtx);
370 auto It = Results.find(Sym.
str());
371 return It != Results.end() && !It->second.ResolvedLibPath.empty();
375 std::shared_lock<std::shared_mutex> Lock(Mtx);
376 std::vector<const Result *> Out;
377 Out.reserve(Results.size());
378 for (
const auto &[
_, res] : Results)
386 std::shared_ptr<LibraryPathCache>
Cache;
399 std::shared_ptr<LibraryPathCache> existingCache =
nullptr,
400 std::shared_ptr<PathResolver> existingResolver =
nullptr,
406 existingCache ? existingCache : std::make_shared<LibraryPathCache>();
408 S.
PResolver = existingResolver ? existingResolver
409 : std::make_shared<PathResolver>(S.
Cache);
411 if (customShouldScan)
427 dbgs() << ++i <<
". Library Path : " <<
Lib.getFullPath() <<
" -> \n\t\t:"
429 << (
Lib.getKind() == PathType::User ?
"User" :
"System")
444 bool scanLibrariesIfNeeded(
PathType K,
size_t BatchSize = 0);
449 std::vector<std::string> *MatchedSymbols =
nullptr);
452 std::vector<std::string> *AllSymbols,
455 std::shared_ptr<LibraryPathCache> LibPathCache;
456 std::shared_ptr<PathResolver> LibPathResolver;
461 size_t scanBatchSize;
468class LibraryResolutionDriver {
470 static std::unique_ptr<LibraryResolutionDriver>
477 return LR->LibMgr.isLoaded(Path);
482 LR->ScanHelper.resetToScan();
483 LR->LibPathCache->clear();
487 LR->scanLibrariesIfNeeded(PathType::User, BatchSize);
488 LR->scanLibrariesIfNeeded(PathType::System, BatchSize);
492 LR->scanLibrariesIfNeeded(PK, BatchSize);
502 LibraryResolutionDriver(std::unique_ptr<LibraryResolver> L)
505 std::unique_ptr<LibraryResolver> LR;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringMapIterBase< std::shared_ptr< LibraryInfo >, true > const_iterator
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
BloomFilter build(ArrayRef< StringRef > Symbols) const
bool operator!=(const FilterIterator &other) const
const std::shared_ptr< LibraryInfo > & operator*() const
FilterIterator & operator++()
FilterIterator(Iterator it_, Iterator end_, LibState S, PathType K)
A read-only view of libraries filtered by state and kind.
FilterIterator begin() const
StringMap< std::shared_ptr< LibraryInfo > > Map
typename Map::const_iterator Iterator
FilteredView(Iterator begin, Iterator end, LibState s, PathType k)
FilterIterator end() const
std::string getFullPath() const
LibState getState() const
bool mayContain(StringRef Symbol) const
LibraryInfo(const LibraryInfo &)=delete
void ensureFilterBuilt(const BloomFilterBuilder &FB, ArrayRef< StringRef > Symbols)
void setState(LibState s)
StringRef getBasePath() const
StringRef getFileName() const
LibraryInfo & operator=(const LibraryInfo &)=delete
void setFilter(BloomFilter F)
bool operator==(const LibraryInfo &other) const
LibraryInfo(std::string FilePath, LibState S, PathType K, std::optional< BloomFilter > Filter=std::nullopt)
Manages library metadata and state for symbol resolution.
std::shared_ptr< LibraryInfo > getLibrary(StringRef Path)
bool hasLibrary(StringRef Path) const
bool isLoaded(StringRef Path) const
void markLoaded(StringRef Path)
FilteredView getView(LibState S, PathType K) const
void removeLibrary(StringRef Path)
void forEachLibrary(const LibraryVisitor &visitor) const
std::function< bool(const LibraryInfo &)> LibraryVisitor
bool addLibrary(std::string Path, PathType Kind, std::optional< BloomFilter > Filter=std::nullopt)
bool isQueried(StringRef Path) const
~LibraryManager()=default
void markQueried(StringRef Path)
void resolveSymbols(std::vector< std::string > Symbols, LibraryResolver::OnSearchComplete OnCompletion, const SearchConfig &Config=SearchConfig())
void addScanPath(const std::string &Path, PathType Kind)
~LibraryResolutionDriver()=default
void scan(PathType PK, size_t BatchSize=0)
void scanAll(size_t BatchSize=0)
bool isLibraryLoaded(StringRef Path) const
bool markLibraryLoaded(StringRef Path)
static std::unique_ptr< LibraryResolutionDriver > create(const LibraryResolver::Setup &S)
bool markLibraryUnLoaded(StringRef Path)
std::function< EnumerateResult(StringRef Sym)> OnEachSymbolFn
static bool enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach, const SymbolEnumeratorOptions &Opts)
Tracks a set of symbols and the libraries where they are resolved.
SymbolQuery(const std::vector< std::string > &Symbols)
std::optional< StringRef > getResolvedLib(StringRef Sym) const
bool hasUnresolved() const
bool isResolved(StringRef Sym) const
SmallVector< StringRef > getUnresolvedSymbols() const
std::vector< const Result * > getAllResults() const
void resolve(StringRef Sym, const std::string &LibPath)
~LibraryResolver()=default
unique_function< void(SymbolQuery &)> OnSearchComplete
friend class LibraryResolutionDriver
void searchSymbolsInLibraries(std::vector< std::string > &SymList, OnSearchComplete OnComplete, const SearchConfig &Config=SearchConfig())
Scans and tracks libraries for symbol resolution.
std::function< bool(StringRef)> ShouldScanFn
unique_function is a type-erasing functor similar to std::function.
LibraryManager::LibraryInfo LibraryInfo
SymbolEnumerator::EnumerateResult EnumerateResult
LibraryResolver::SymbolEnumerator SymbolEnumerator
LibraryResolver::SymbolQuery SymbolQuery
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
static Setup create(std::vector< std::string > BasePaths, std::shared_ptr< LibraryPathCache > existingCache=nullptr, std::shared_ptr< PathResolver > existingResolver=nullptr, LibraryScanner::ShouldScanFn customShouldScan=nullptr)
BloomFilterBuilder FilterBuilder
LibraryScanner::ShouldScanFn ShouldScanCall
std::vector< std::string > BasePaths
std::shared_ptr< PathResolver > PResolver
std::shared_ptr< LibraryPathCache > Cache
Holds the result for a single symbol.
std::string ResolvedLibPath
SymbolEnumeratorOptions Options
LibraryManager::LibState State
static SearchPolicy defaultPlan()
std::vector< SearchPlanEntry > Plan
static SymbolEnumeratorOptions defaultOptions()