Skip to content

Commit 0c3ba9b

Browse files
committed
REAPPLY [ORC] Add automatic shared library resolver for unresolved symbols. #148410
1 parent 81de861 commit 0c3ba9b

File tree

16 files changed

+8371
-0
lines changed

16 files changed

+8371
-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)