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"
22#include "llvm/Support/Error.h"
23
24#include <initializer_list>
25#include <type_traits>
26#include <utility>
27#include <vector>
28
29namespace llvm::orc {
30
31/// Lookup flags that apply to each symbol in a lookup.
32///
33/// If RequiredSymbol is used (the default) for a given symbol then that symbol
34/// must be found during the lookup or the lookup will fail returning a
35/// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
36/// symbol is not found then the query will continue, and no result for the
37/// missing symbol will be present in the result (assuming the rest of the
38/// lookup succeeds).
40
41/// A set of symbols to look up, each associated with a SymbolLookupFlags
42/// value.
43///
44/// This class is backed by a vector and optimized for fast insertion,
45/// deletion and iteration. It does not guarantee a stable order between
46/// operations, and will not automatically detect duplicate elements (they
47/// can be manually checked by calling the validate method).
49public:
50 using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
51 using UnderlyingVector = std::vector<value_type>;
52 using iterator = UnderlyingVector::iterator;
53 using const_iterator = UnderlyingVector::const_iterator;
54
55 SymbolLookupSet() = default;
56
57 SymbolLookupSet(std::initializer_list<value_type> Elems) {
58 for (auto &E : Elems)
59 Symbols.push_back(std::move(E));
60 }
61
63 SymbolStringPtr Name,
65 add(std::move(Name), Flags);
66 }
67
68 /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
70 std::initializer_list<SymbolStringPtr> Names,
72 Symbols.reserve(Names.size());
73 for (const auto &Name : Names)
74 add(std::move(Name), Flags);
75 }
76
77 /// Construct a SymbolLookupSet from a SymbolNameSet with the given
78 /// Flags used for each value.
80 const SymbolNameSet &Names,
82 Symbols.reserve(Names.size());
83 for (const auto &Name : Names)
84 add(Name, Flags);
85 }
86
87 /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
88 /// used for each value.
89 /// If the ArrayRef contains duplicates it is up to the client to remove these
90 /// before using this instance for lookup.
94 Symbols.reserve(Names.size());
95 for (const auto &Name : Names)
96 add(Name, Flags);
97 }
98
99 /// Construct a SymbolLookupSet from DenseMap keys.
100 template <typename ValT>
101 static SymbolLookupSet
105 Result.Symbols.reserve(M.size());
106 for (const auto &[Name, Val] : M)
107 Result.add(Name, Flags);
108 return Result;
109 }
110
111 /// Add an element to the set. The client is responsible for checking that
112 /// duplicates are not added.
116 Symbols.push_back(std::make_pair(std::move(Name), Flags));
117 return *this;
118 }
119
120 /// Quickly append one lookup set to another.
122 Symbols.reserve(Symbols.size() + Other.size());
123 for (auto &KV : Other)
124 Symbols.push_back(std::move(KV));
125 return *this;
126 }
127
128 bool empty() const { return Symbols.empty(); }
129 UnderlyingVector::size_type size() const { return Symbols.size(); }
130 iterator begin() { return Symbols.begin(); }
131 iterator end() { return Symbols.end(); }
132 const_iterator begin() const { return Symbols.begin(); }
133 const_iterator end() const { return Symbols.end(); }
134
135 /// Removes the Ith element of the vector, replacing it with the last element.
136 void remove(UnderlyingVector::size_type I) {
137 std::swap(Symbols[I], Symbols.back());
138 Symbols.pop_back();
139 }
140
141 /// Removes the element pointed to by the given iterator. This iterator and
142 /// all subsequent ones (including end()) are invalidated.
143 void remove(iterator I) { remove(I - begin()); }
144
145 /// Removes all elements matching the given predicate, which must be callable
146 /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
147 template <typename PredFn> void remove_if(PredFn &&Pred) {
148 UnderlyingVector::size_type I = 0;
149 while (I != Symbols.size()) {
150 const auto &Name = Symbols[I].first;
151 auto Flags = Symbols[I].second;
152 if (Pred(Name, Flags))
153 remove(I);
154 else
155 ++I;
156 }
157 }
158
159 /// Loop over the elements of this SymbolLookupSet, applying the Body function
160 /// to each one. Body must be callable as
161 /// bool(const SymbolStringPtr &, SymbolLookupFlags).
162 /// If Body returns true then the element just passed in is removed from the
163 /// set. If Body returns false then the element is retained.
164 template <typename BodyFn>
165 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
166 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
167 std::declval<SymbolLookupFlags>())),
168 bool>::value> {
169 UnderlyingVector::size_type I = 0;
170 while (I != Symbols.size()) {
171 const auto &Name = Symbols[I].first;
172 auto Flags = Symbols[I].second;
173 if (Body(Name, Flags))
174 remove(I);
175 else
176 ++I;
177 }
178 }
179
180 /// Loop over the elements of this SymbolLookupSet, applying the Body function
181 /// to each one. Body must be callable as
182 /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
183 /// If Body returns a failure value, the loop exits immediately. If Body
184 /// returns true then the element just passed in is removed from the set. If
185 /// Body returns false then the element is retained.
186 template <typename BodyFn>
187 auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
188 std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
189 std::declval<SymbolLookupFlags>())),
190 Expected<bool>>::value,
191 Error> {
192 UnderlyingVector::size_type I = 0;
193 while (I != Symbols.size()) {
194 const auto &Name = Symbols[I].first;
195 auto Flags = Symbols[I].second;
196 auto Remove = Body(Name, Flags);
197 if (!Remove)
198 return Remove.takeError();
199 if (*Remove)
200 remove(I);
201 else
202 ++I;
203 }
204 return Error::success();
205 }
206
207 /// Construct a SymbolNameVector from this instance by dropping the Flags
208 /// values.
210 SymbolNameVector Names;
211 Names.reserve(Symbols.size());
212 for (const auto &KV : Symbols)
213 Names.push_back(KV.first);
214 return Names;
215 }
216
217 /// Sort the lookup set by pointer value. This sort is fast but sensitive to
218 /// allocation order and so should not be used where a consistent order is
219 /// required.
221
222 /// Sort the lookup set lexicographically. This sort is slow but the order
223 /// is unaffected by allocation order.
224 void sortByName() {
225 llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
226 return *LHS.first < *RHS.first;
227 });
228 }
229
230 /// Merge entries that share a name, so that each name appears exactly once.
231 /// If a SymbolLookupSet is not duplicate-free by construction, this method
232 /// can be used to turn it into a proper set.
233 ///
234 /// Entries sharing a name need not agree on their flags. Where they differ
235 /// the strongest requirement wins: if any entry required the symbol then the
236 /// merged entry requires it too, so that a missing definition still fails the
237 /// lookup.
239 if (Symbols.size() < 2)
240 return;
242
243 auto Out = Symbols.begin();
244 for (auto In = Out + 1; In != Symbols.end(); ++In) {
245 if (In->first == Out->first) {
246 // Same name: keep the stronger requirement.
247 if (In->second == SymbolLookupFlags::RequiredSymbol)
249 } else {
250 // New name: compact it down next to the previous survivor.
251 ++Out;
252 if (Out != In)
253 *Out = std::move(*In);
254 }
255 }
256 Symbols.erase(std::next(Out), Symbols.end());
257 }
258
259#ifndef NDEBUG
260 /// Returns true if this set contains any duplicates. This should only be used
261 /// in assertions.
263 if (Symbols.size() < 2)
264 return false;
266 for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
267 if (Symbols[I].first == Symbols[I - 1].first)
268 return true;
269 return false;
270 }
271#endif
272
273private:
274 UnderlyingVector Symbols;
275};
276
277} // namespace llvm::orc
278
279// SPS serialization for SymbolLookupSet. This lives here rather than in
280// Shared/SymbolLookupSetSPS.h because that header is shared with
281// OrcTargetProcess, which doesn't depend on ORC's core types.
282namespace llvm::orc::shared {
283
284// Serialize a SymbolLookupSet directly as an SPSSymbolLookupSet, avoiding a
285// std::string copy of each (potentially large) symbol name.
286template <>
289public:
290 static size_t size(const SymbolLookupSet::value_type &V) {
292 *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
293 }
294
295 static bool serialize(SPSOutputBuffer &OB,
298 OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
299 }
300};
301
302template <>
305public:
306 static constexpr bool available = true;
307};
308
309} // namespace llvm::orc::shared
310
311#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).
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