LLVM 24.0.0git
SymbolLookupSet.h
Go to the documentation of this file.
1//===------ SymbolLookupSet.h - Symbol set for ORC lookups ------*- 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// SymbolLookupSet class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
14#define LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/STLExtras.h"
23#include "llvm/Support/Error.h"
24
25#include <initializer_list>
26#include <optional>
27#include <type_traits>
28#include <utility>
29#include <vector>
30
31namespace llvm::orc {
32
33/// Lookup flags that apply to each symbol in a lookup.
34///
35/// If RequiredSymbol is used (the default) for a given symbol then that symbol
36/// must be found during the lookup or the lookup will fail returning a
37/// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
38/// symbol is not found then the query will continue, and no result for the
39/// missing symbol will be present in the result (assuming the rest of the
40/// lookup succeeds).
42
43/// A set of symbols to look up, each associated with a SymbolLookupFlags
44/// value.
45///
46/// This class is backed by a vector and optimized for fast insertion,
47/// deletion and iteration. It does not guarantee a stable order between
48/// operations, and will not automatically detect duplicate elements (they
49/// can be manually checked by calling the validate method).
51public:
52 using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
53 using UnderlyingVector = std::vector<value_type>;
54 using iterator = UnderlyingVector::iterator;
55 using const_iterator = UnderlyingVector::const_iterator;
56
57 SymbolLookupSet() = default;
58
59 SymbolLookupSet(std::initializer_list<value_type> Elems) {
60 for (auto &E : Elems)
61 Symbols.push_back(std::move(E));
62 }
63
65 SymbolStringPtr Name,
67 add(std::move(Name), Flags);
68 }
69
70 /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
72 std::initializer_list<SymbolStringPtr> Names,
74 Symbols.reserve(Names.size());
75 for (const auto &Name : Names)
76 add(std::move(Name), Flags);
77 }
78
79 /// Construct a SymbolLookupSet from a SymbolNameSet with the given
80 /// Flags used for each value.
82 const SymbolNameSet &Names,
84 Symbols.reserve(Names.size());
85 for (const auto &Name : Names)
86 add(Name, Flags);
87 }
88
89 /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
90 /// used for each value.
91 /// If the ArrayRef contains duplicates it is up to the client to remove these
92 /// before using this instance for lookup.
96 Symbols.reserve(Names.size());
97 for (const auto &Name : Names)
98 add(Name, Flags);
99 }
100
101 /// Construct a SymbolLookupSet from DenseMap keys.
102 template <typename ValT>
103 static SymbolLookupSet
107 Result.Symbols.reserve(M.size());
108 for (const auto &[Name, Val] : M)
109 Result.add(Name, Flags);
110 return Result;
111 }
112
113 /// Add an element to the set. The client is responsible for checking that
114 /// duplicates are not added.
118 Symbols.push_back(std::make_pair(std::move(Name), Flags));
119 return *this;
120 }
121
122 /// Quickly append one lookup set to another.
124 Symbols.reserve(Symbols.size() + Other.size());
125 for (auto &KV : Other)
126 Symbols.push_back(std::move(KV));
127 return *this;
128 }
129
130 bool empty() const { return Symbols.empty(); }
131 UnderlyingVector::size_type size() const { return Symbols.size(); }
132 iterator begin() { return Symbols.begin(); }
133 iterator end() { return Symbols.end(); }
134 const_iterator begin() const { return Symbols.begin(); }
135 const_iterator end() const { return Symbols.end(); }
136
137 /// Removes the Ith element of the vector, replacing it with the last element.
138 void remove(UnderlyingVector::size_type I) {
139 std::swap(Symbols[I], Symbols.back());
140 Symbols.pop_back();
141 }
142
143 /// Removes the element pointed to by the given iterator. This iterator and
144 /// all subsequent ones (including end()) are invalidated.
145 void remove(iterator I) { remove(I - begin()); }
146
147 /// Removes all elements matching the given predicate, which must be callable
148 /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
149 template <typename PredFn> void remove_if(PredFn &&Pred) {
150 UnderlyingVector::size_type I = 0;
151 while (I != Symbols.size()) {
152 const auto &Name = Symbols[I].first;
153 auto Flags = Symbols[I].second;
154 if (Pred(Name, Flags))
155 remove(I);
156 else
157 ++I;
158 }
159 }
160
161 /// Loop over the elements of this SymbolLookupSet, applying the Body function
162 /// to each one. Body must be callable as
163 /// bool(const SymbolStringPtr &, SymbolLookupFlags).
164 /// If Body returns true then the element just passed in is removed from the
165 /// set. If Body returns false then the element is retained.
166 template <typename BodyFn>
167 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
168 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
169 std::declval<SymbolLookupFlags>())),
170 bool>::value> {
171 UnderlyingVector::size_type I = 0;
172 while (I != Symbols.size()) {
173 const auto &Name = Symbols[I].first;
174 auto Flags = Symbols[I].second;
175 if (Body(Name, Flags))
176 remove(I);
177 else
178 ++I;
179 }
180 }
181
182 /// Loop over the elements of this SymbolLookupSet, applying the Body function
183 /// to each one. Body must be callable as
184 /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
185 /// If Body returns a failure value, the loop exits immediately. If Body
186 /// returns true then the element just passed in is removed from the set. If
187 /// Body returns false then the element is retained.
188 template <typename BodyFn>
189 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
190 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
191 std::declval<SymbolLookupFlags>())),
192 Expected<bool>>::value,
193 Error> {
194 UnderlyingVector::size_type I = 0;
195 while (I != Symbols.size()) {
196 const auto &Name = Symbols[I].first;
197 auto Flags = Symbols[I].second;
198 auto Remove = Body(Name, Flags);
199 if (!Remove)
200 return Remove.takeError();
201 if (*Remove)
202 remove(I);
203 else
204 ++I;
205 }
206 return Error::success();
207 }
208
209 /// Construct a SymbolNameVector from this instance by dropping the Flags
210 /// values.
212 SymbolNameVector Names;
213 Names.reserve(Symbols.size());
214 for (const auto &KV : Symbols)
215 Names.push_back(KV.first);
216 return Names;
217 }
218
219 /// Sort the lookup set by pointer value. This sort is fast but sensitive to
220 /// allocation order and so should not be used where a consistent order is
221 /// required.
223
224 /// Sort the lookup set lexicographically. This sort is slow but the order
225 /// is unaffected by allocation order.
226 void sortByName() {
227 llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
228 return *LHS.first < *RHS.first;
229 });
230 }
231
232 /// Merge entries that share a name, so that each name appears exactly once.
233 /// If a SymbolLookupSet is not duplicate-free by construction, this method
234 /// can be used to turn it into a proper set.
235 ///
236 /// Entries sharing a name need not agree on their flags. Where they differ
237 /// the strongest requirement wins: if any entry required the symbol then the
238 /// merged entry requires it too, so that a missing definition still fails the
239 /// lookup.
241 if (Symbols.size() < 2)
242 return;
244
245 auto Out = Symbols.begin();
246 for (auto In = Out + 1; In != Symbols.end(); ++In) {
247 if (In->first == Out->first) {
248 // Same name: keep the stronger requirement.
249 if (In->second == SymbolLookupFlags::RequiredSymbol)
251 } else {
252 // New name: compact it down next to the previous survivor.
253 ++Out;
254 if (Out != In)
255 *Out = std::move(*In);
256 }
257 }
258 Symbols.erase(std::next(Out), Symbols.end());
259 }
260
261#ifndef NDEBUG
262 /// Returns true if this set contains any duplicates. This should only be used
263 /// in assertions.
265 if (Symbols.size() < 2)
266 return false;
268 for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
269 if (Symbols[I].first == Symbols[I - 1].first)
270 return true;
271 return false;
272 }
273#endif
274
275private:
276 UnderlyingVector Symbols;
277};
278
279/// The result of looking up a SymbolLookupSet in the executor: one entry per
280/// element of the set, in the same order.
281///
282/// An empty optional indicates that a required symbol was not found. A missing
283/// weakly referenced symbol is reported as a present optional holding a null
284/// address.
285using SymbolLookupResult = std::vector<std::optional<ExecutorAddr>>;
286
287} // namespace llvm::orc
288
289// SPS serialization for SymbolLookupSet. This lives here rather than in
290// Shared/SymbolLookupSetSPS.h because that header is shared with
291// OrcTargetProcess, which doesn't depend on ORC's core types.
292namespace llvm::orc::shared {
293
294// Serialize a SymbolLookupSet directly as an SPSSymbolLookupSet, avoiding a
295// std::string copy of each (potentially large) symbol name.
296template <>
299public:
300 static size_t size(const SymbolLookupSet::value_type &V) {
302 *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
303 }
304
305 static bool serialize(SPSOutputBuffer &OB,
308 OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
309 }
310};
311
312template <>
315public:
316 static constexpr bool available = true;
317};
318
319} // namespace llvm::orc::shared
320
321#endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLLOOKUPSET_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some templates that are useful if you are working with the STL at all.
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
size_type size() const
Definition DenseSet.h:84
A set of symbols to look up, each associated with a SymbolLookupFlags value.
std::pair< SymbolStringPtr, SymbolLookupFlags > value_type
const_iterator begin() const
void mergeEntries()
Merge entries that share a name, so that each name appears exactly once.
UnderlyingVector::const_iterator const_iterator
void sortByAddress()
Sort the lookup set by pointer value.
SymbolLookupSet(std::initializer_list< SymbolStringPtr > Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
UnderlyingVector::size_type size() const
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
static SymbolLookupSet fromMapKeys(const DenseMap< SymbolStringPtr, ValT > &M, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from DenseMap keys.
SymbolLookupSet & append(SymbolLookupSet Other)
Quickly append one lookup set to another.
SymbolLookupSet(ArrayRef< SymbolStringPtr > Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from a vector of symbols with the given Flags used for each value.
SymbolLookupSet(std::initializer_list< value_type > Elems)
void sortByName()
Sort the lookup set lexicographically.
void remove(iterator I)
Removes the element pointed to by the given iterator.
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< std::is_same< decltype(Body(std::declval< const SymbolStringPtr & >(), std::declval< SymbolLookupFlags >())), bool >::value >
Loop over the elements of this SymbolLookupSet, applying the Body function to each one.
bool containsDuplicates()
Returns true if this set contains any duplicates.
UnderlyingVector::iterator iterator
void remove_if(PredFn &&Pred)
Removes all elements matching the given predicate, which must be callable as bool(const SymbolStringP...
SymbolLookupSet(const SymbolNameSet &Names, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from a SymbolNameSet with the given Flags used for each value.
SymbolLookupSet(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
SymbolNameVector getSymbolNames() const
Construct a SymbolNameVector from this instance by dropping the Flags values.
const_iterator end() const
auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t< std::is_same< decltype(Body(std::declval< const SymbolStringPtr & >(), std::declval< SymbolLookupFlags >())), Expected< bool > >::value, Error >
Loop over the elements of this SymbolLookupSet, applying the Body function to each one.
void remove(UnderlyingVector::size_type I)
Removes the Ith element of the vector, replacing it with the last element.
std::vector< value_type > UnderlyingVector
Pointer to a pooled string representing a symbol name.
A utility class for serializing to a blob from a variadic list.
Output char buffer with overflow check.
static bool serialize(SPSOutputBuffer &OB, const SymbolLookupSet::value_type &V)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
Specialize this to implement 'trivial' sequence serialization for a concrete sequence type.
SPSTuple< SPSString, bool > SPSSymbolLookupSetElement
A symbol name, and whether the symbol is required (true) or weakly referenced (false).
std::vector< std::optional< ExecutorAddr > > SymbolLookupResult
The result of looking up a SymbolLookupSet in the executor: one entry per element of the set,...
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
@ Other
Any other memory.
Definition ModRef.h:68
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
Function object to check whether the first component of a container supported by std::get (like std::...
Definition STLExtras.h:1455