Skip to content

Commit 605a7d6

Browse files
authored
REAPPLY [ORC] Add automatic shared library resolver for unresolved symbols. (attempt 2) (#165360)
This PR reapplies the changes previously introduced in #148410. It introduces a redesigned and rebuilt Cling-based auto-loading workaround that enables scanning libraries and resolving unresolved symbols within those libraries. Fix build failures in LibraryResolverTest and silence symlink warning This commit resolves issues observed in the build bots: 1. Silences the -Wunused-result warning by handling the return value of ::symlink in LibraryResolverTest.cpp. Previously, ignoring the return value triggered compiler warnings. 2. Fixes a linker error in OrcJITTests caused by an undefined symbol: llvm::yaml::convertYAML. The test setup in LibraryResolverTest.cpp now correctly links against the required LLVM YAML library symbols. 3. Fixes persistent build bot failure caused by a path difference issue. This resolves the build failures for PR #148410 on the affected bots.
1 parent 93014e0 commit 605a7d6

File tree

16 files changed

+8325
-0
lines changed

16 files changed

+8325
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
//===- SymbolFilter.h - Utilities for Symbol Filtering ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
10+
#define LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
11+
12+
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
13+
14+
#include <cmath>
15+
#include <type_traits>
16+
#include <vector>
17+
18+
namespace llvm {
19+
namespace orc {
20+
21+
namespace shared {
22+
using SPSBloomFilter =
23+
SPSTuple<bool, uint32_t, uint32_t, uint32_t, SPSSequence<uint64_t>>;
24+
}
25+
26+
class BloomFilter {
27+
public:
28+
using HashFunc = std::function<uint32_t(StringRef)>;
29+
30+
BloomFilter() = default;
31+
BloomFilter(BloomFilter &&) noexcept = default;
32+
BloomFilter &operator=(BloomFilter &&) noexcept = default;
33+
BloomFilter(const BloomFilter &) = delete;
34+
BloomFilter &operator=(const BloomFilter &) = delete;
35+
36+
BloomFilter(uint32_t SymbolCount, float FalsePositiveRate, HashFunc hashFn)
37+
: HashFn(std::move(hashFn)) {
38+
initialize(SymbolCount, FalsePositiveRate);
39+
}
40+
bool isInitialized() const { return Initialized; }
41+
42+
void add(StringRef Sym) {
43+
assert(Initialized);
44+
addHash(HashFn(Sym));
45+
}
46+
47+
bool mayContain(StringRef Sym) const {
48+
return !isEmpty() && testHash(HashFn(Sym));
49+
}
50+
51+
bool isEmpty() const { return SymbolCount == 0; }
52+
53+
private:
54+
friend class shared::SPSSerializationTraits<shared::SPSBloomFilter,
55+
BloomFilter>;
56+
static constexpr uint32_t BitsPerEntry = 64;
57+
58+
bool Initialized = false;
59+
uint32_t SymbolCount = 0;
60+
uint32_t BloomSize = 0;
61+
uint32_t BloomShift = 0;
62+
std::vector<uint64_t> BloomTable;
63+
HashFunc HashFn;
64+
65+
void initialize(uint32_t SymCount, float FalsePositiveRate) {
66+
assert(SymCount > 0);
67+
SymbolCount = SymCount;
68+
Initialized = true;
69+
70+
float ln2 = std::log(2.0f);
71+
float M = -1.0f * SymbolCount * std::log(FalsePositiveRate) / (ln2 * ln2);
72+
BloomSize = static_cast<uint32_t>(std::ceil(M / BitsPerEntry));
73+
BloomShift = std::min(6u, log2ceil(SymbolCount));
74+
BloomTable.resize(BloomSize, 0);
75+
}
76+
77+
void addHash(uint32_t Hash) {
78+
uint32_t Hash2 = Hash >> BloomShift;
79+
uint32_t N = (Hash / BitsPerEntry) % BloomSize;
80+
uint64_t Mask =
81+
(1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
82+
BloomTable[N] |= Mask;
83+
}
84+
85+
bool testHash(uint32_t Hash) const {
86+
uint32_t Hash2 = Hash >> BloomShift;
87+
uint32_t N = (Hash / BitsPerEntry) % BloomSize;
88+
uint64_t Mask =
89+
(1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
90+
return (BloomTable[N] & Mask) == Mask;
91+
}
92+
93+
static constexpr uint32_t log2ceil(uint32_t V) {
94+
return V <= 1 ? 0 : 32 - countl_zero(V - 1);
95+
}
96+
};
97+
98+
class BloomFilterBuilder {
99+
public:
100+
using HashFunc = BloomFilter::HashFunc;
101+
102+
BloomFilterBuilder() = default;
103+
104+
BloomFilterBuilder &setFalsePositiveRate(float Rate) {
105+
assert(Rate > 0.0f && Rate < 1.0f);
106+
FalsePositiveRate = Rate;
107+
return *this;
108+
}
109+
110+
BloomFilterBuilder &setHashFunction(HashFunc Fn) {
111+
HashFn = std::move(Fn);
112+
return *this;
113+
}
114+
115+
BloomFilter build(ArrayRef<StringRef> Symbols) const {
116+
assert(!Symbols.empty() && "Cannot build filter from empty symbol list.");
117+
BloomFilter F(static_cast<uint32_t>(Symbols.size()), FalsePositiveRate,
118+
HashFn);
119+
for (const auto &Sym : Symbols)
120+
F.add(Sym);
121+
122+
return F;
123+
}
124+
125+
private:
126+
float FalsePositiveRate = 0.02f;
127+
HashFunc HashFn = [](StringRef S) -> uint32_t {
128+
uint32_t H = 5381;
129+
for (char C : S)
130+
H = ((H << 5) + H) + static_cast<uint8_t>(C); // H * 33 + C
131+
return H;
132+
};
133+
};
134+
135+
namespace shared {
136+
137+
template <> class SPSSerializationTraits<SPSBloomFilter, BloomFilter> {
138+
public:
139+
static size_t size(const BloomFilter &Filter) {
140+
return SPSBloomFilter::AsArgList::size(
141+
Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
142+
Filter.BloomShift, Filter.BloomTable);
143+
}
144+
145+
static bool serialize(SPSOutputBuffer &OB, const BloomFilter &Filter) {
146+
return SPSBloomFilter::AsArgList::serialize(
147+
OB, Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
148+
Filter.BloomShift, Filter.BloomTable);
149+
}
150+
151+
static bool deserialize(SPSInputBuffer &IB, BloomFilter &Filter) {
152+
bool IsInitialized;
153+
uint32_t SymbolCount = 0, BloomSize = 0, BloomShift = 0;
154+
std::vector<uint64_t> BloomTable;
155+
156+
if (!SPSBloomFilter::AsArgList::deserialize(
157+
IB, IsInitialized, SymbolCount, BloomSize, BloomShift, BloomTable))
158+
return false;
159+
160+
Filter.Initialized = IsInitialized;
161+
Filter.SymbolCount = SymbolCount;
162+
Filter.BloomSize = BloomSize;
163+
Filter.BloomShift = BloomShift;
164+
Filter.BloomTable = std::move(BloomTable);
165+
166+
return true;
167+
}
168+
};
169+
170+
} // end namespace shared
171+
} // end namespace orc
172+
} // end namespace llvm
173+
#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H

0 commit comments

Comments
 (0)