File indexing completed on 2026-05-10 08:44:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #ifndef LLVM_IR_VALUEMAP_H
0026 #define LLVM_IR_VALUEMAP_H
0027
0028 #include "llvm/ADT/DenseMap.h"
0029 #include "llvm/ADT/DenseMapInfo.h"
0030 #include "llvm/IR/TrackingMDRef.h"
0031 #include "llvm/IR/ValueHandle.h"
0032 #include "llvm/Support/Casting.h"
0033 #include "llvm/Support/Mutex.h"
0034 #include <algorithm>
0035 #include <cassert>
0036 #include <cstddef>
0037 #include <iterator>
0038 #include <mutex>
0039 #include <optional>
0040 #include <type_traits>
0041 #include <utility>
0042
0043 namespace llvm {
0044
0045 template<typename KeyT, typename ValueT, typename Config>
0046 class ValueMapCallbackVH;
0047 template<typename DenseMapT, typename KeyT>
0048 class ValueMapIterator;
0049 template<typename DenseMapT, typename KeyT>
0050 class ValueMapConstIterator;
0051
0052
0053
0054
0055 template<typename KeyT, typename MutexT = sys::Mutex>
0056 struct ValueMapConfig {
0057 using mutex_type = MutexT;
0058
0059
0060
0061 enum { FollowRAUW = true };
0062
0063
0064
0065
0066
0067 struct ExtraData {};
0068
0069 template<typename ExtraDataT>
0070 static void onRAUW(const ExtraDataT & , KeyT , KeyT ) {}
0071 template<typename ExtraDataT>
0072 static void onDelete(const ExtraDataT &, KeyT ) {}
0073
0074
0075
0076
0077
0078 template<typename ExtraDataT>
0079 static mutex_type *getMutex(const ExtraDataT &) { return nullptr; }
0080 };
0081
0082
0083 template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT>>
0084 class ValueMap {
0085 friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
0086
0087 using ValueMapCVH = ValueMapCallbackVH<KeyT, ValueT, Config>;
0088 using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>;
0089 using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;
0090 using ExtraData = typename Config::ExtraData;
0091
0092 MapT Map;
0093 std::optional<MDMapT> MDMap;
0094 ExtraData Data;
0095
0096 public:
0097 using key_type = KeyT;
0098 using mapped_type = ValueT;
0099 using value_type = std::pair<KeyT, ValueT>;
0100 using size_type = unsigned;
0101
0102 explicit ValueMap(unsigned NumInitBuckets = 64)
0103 : Map(NumInitBuckets), Data() {}
0104 explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
0105 : Map(NumInitBuckets), Data(Data) {}
0106
0107
0108 ValueMap(const ValueMap &) = delete;
0109 ValueMap(ValueMap &&) = delete;
0110 ValueMap &operator=(const ValueMap &) = delete;
0111 ValueMap &operator=(ValueMap &&) = delete;
0112
0113 bool hasMD() const { return bool(MDMap); }
0114 MDMapT &MD() {
0115 if (!MDMap)
0116 MDMap.emplace();
0117 return *MDMap;
0118 }
0119 std::optional<MDMapT> &getMDMap() { return MDMap; }
0120
0121
0122 std::optional<Metadata *> getMappedMD(const Metadata *MD) const {
0123 if (!MDMap)
0124 return std::nullopt;
0125 auto Where = MDMap->find(MD);
0126 if (Where == MDMap->end())
0127 return std::nullopt;
0128 return Where->second.get();
0129 }
0130
0131 using iterator = ValueMapIterator<MapT, KeyT>;
0132 using const_iterator = ValueMapConstIterator<MapT, KeyT>;
0133
0134 inline iterator begin() { return iterator(Map.begin()); }
0135 inline iterator end() { return iterator(Map.end()); }
0136 inline const_iterator begin() const { return const_iterator(Map.begin()); }
0137 inline const_iterator end() const { return const_iterator(Map.end()); }
0138
0139 bool empty() const { return Map.empty(); }
0140 size_type size() const { return Map.size(); }
0141
0142
0143 void reserve(size_t Size) { Map.reserve(Size); }
0144
0145 void clear() {
0146 Map.clear();
0147 MDMap.reset();
0148 }
0149
0150
0151 size_type count(const KeyT &Val) const {
0152 return Map.find_as(Val) == Map.end() ? 0 : 1;
0153 }
0154
0155 iterator find(const KeyT &Val) {
0156 return iterator(Map.find_as(Val));
0157 }
0158 const_iterator find(const KeyT &Val) const {
0159 return const_iterator(Map.find_as(Val));
0160 }
0161
0162
0163
0164 ValueT lookup(const KeyT &Val) const {
0165 typename MapT::const_iterator I = Map.find_as(Val);
0166 return I != Map.end() ? I->second : ValueT();
0167 }
0168
0169
0170
0171
0172 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
0173 auto MapResult = Map.insert(std::make_pair(Wrap(KV.first), KV.second));
0174 return std::make_pair(iterator(MapResult.first), MapResult.second);
0175 }
0176
0177 std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
0178 auto MapResult =
0179 Map.insert(std::make_pair(Wrap(KV.first), std::move(KV.second)));
0180 return std::make_pair(iterator(MapResult.first), MapResult.second);
0181 }
0182
0183
0184 template<typename InputIt>
0185 void insert(InputIt I, InputIt E) {
0186 for (; I != E; ++I)
0187 insert(*I);
0188 }
0189
0190 bool erase(const KeyT &Val) {
0191 typename MapT::iterator I = Map.find_as(Val);
0192 if (I == Map.end())
0193 return false;
0194
0195 Map.erase(I);
0196 return true;
0197 }
0198 void erase(iterator I) {
0199 return Map.erase(I.base());
0200 }
0201
0202 value_type& FindAndConstruct(const KeyT &Key) {
0203 return Map.FindAndConstruct(Wrap(Key));
0204 }
0205
0206 ValueT &operator[](const KeyT &Key) {
0207 return Map[Wrap(Key)];
0208 }
0209
0210
0211
0212
0213 bool isPointerIntoBucketsArray(const void *Ptr) const {
0214 return Map.isPointerIntoBucketsArray(Ptr);
0215 }
0216
0217
0218
0219
0220 const void *getPointerIntoBucketsArray() const {
0221 return Map.getPointerIntoBucketsArray();
0222 }
0223
0224 private:
0225
0226
0227
0228 ValueMapCVH Wrap(KeyT key) const {
0229
0230
0231
0232
0233 return ValueMapCVH(key, const_cast<ValueMap*>(this));
0234 }
0235 };
0236
0237
0238
0239 template <typename KeyT, typename ValueT, typename Config>
0240 class ValueMapCallbackVH final : public CallbackVH {
0241 friend class ValueMap<KeyT, ValueT, Config>;
0242 friend struct DenseMapInfo<ValueMapCallbackVH>;
0243
0244 using ValueMapT = ValueMap<KeyT, ValueT, Config>;
0245 using KeySansPointerT = std::remove_pointer_t<KeyT>;
0246
0247 ValueMapT *Map;
0248
0249 ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
0250 : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
0251 Map(Map) {}
0252
0253
0254 ValueMapCallbackVH(Value *V) : CallbackVH(V), Map(nullptr) {}
0255
0256 public:
0257 KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
0258
0259 void deleted() override {
0260
0261 ValueMapCallbackVH Copy(*this);
0262 typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
0263 std::unique_lock<typename Config::mutex_type> Guard;
0264 if (M)
0265 Guard = std::unique_lock<typename Config::mutex_type>(*M);
0266 Config::onDelete(Copy.Map->Data, Copy.Unwrap());
0267 Copy.Map->Map.erase(Copy);
0268 }
0269
0270 void allUsesReplacedWith(Value *new_key) override {
0271 assert(isa<KeySansPointerT>(new_key) &&
0272 "Invalid RAUW on key of ValueMap<>");
0273
0274 ValueMapCallbackVH Copy(*this);
0275 typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
0276 std::unique_lock<typename Config::mutex_type> Guard;
0277 if (M)
0278 Guard = std::unique_lock<typename Config::mutex_type>(*M);
0279
0280 KeyT typed_new_key = cast<KeySansPointerT>(new_key);
0281
0282 Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
0283 if (Config::FollowRAUW) {
0284 typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
0285
0286
0287 if (I != Copy.Map->Map.end()) {
0288 ValueT Target(std::move(I->second));
0289 Copy.Map->Map.erase(I);
0290 Copy.Map->insert(std::make_pair(typed_new_key, std::move(Target)));
0291 }
0292 }
0293 }
0294 };
0295
0296 template<typename KeyT, typename ValueT, typename Config>
0297 struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config>> {
0298 using VH = ValueMapCallbackVH<KeyT, ValueT, Config>;
0299
0300 static inline VH getEmptyKey() {
0301 return VH(DenseMapInfo<Value *>::getEmptyKey());
0302 }
0303
0304 static inline VH getTombstoneKey() {
0305 return VH(DenseMapInfo<Value *>::getTombstoneKey());
0306 }
0307
0308 static unsigned getHashValue(const VH &Val) {
0309 return DenseMapInfo<KeyT>::getHashValue(Val.Unwrap());
0310 }
0311
0312 static unsigned getHashValue(const KeyT &Val) {
0313 return DenseMapInfo<KeyT>::getHashValue(Val);
0314 }
0315
0316 static bool isEqual(const VH &LHS, const VH &RHS) {
0317 return LHS == RHS;
0318 }
0319
0320 static bool isEqual(const KeyT &LHS, const VH &RHS) {
0321 return LHS == RHS.getValPtr();
0322 }
0323 };
0324
0325 template <typename DenseMapT, typename KeyT> class ValueMapIterator {
0326 using BaseT = typename DenseMapT::iterator;
0327 using ValueT = typename DenseMapT::mapped_type;
0328
0329 BaseT I;
0330
0331 public:
0332 using iterator_category = std::forward_iterator_tag;
0333 using value_type = std::pair<KeyT, typename DenseMapT::mapped_type>;
0334 using difference_type = std::ptrdiff_t;
0335 using pointer = value_type *;
0336 using reference = value_type &;
0337
0338 ValueMapIterator() : I() {}
0339 ValueMapIterator(BaseT I) : I(I) {}
0340
0341 BaseT base() const { return I; }
0342
0343 struct ValueTypeProxy {
0344 const KeyT first;
0345 ValueT& second;
0346
0347 ValueTypeProxy *operator->() { return this; }
0348
0349 operator std::pair<KeyT, ValueT>() const {
0350 return std::make_pair(first, second);
0351 }
0352 };
0353
0354 ValueTypeProxy operator*() const {
0355 ValueTypeProxy Result = {I->first.Unwrap(), I->second};
0356 return Result;
0357 }
0358
0359 ValueTypeProxy operator->() const {
0360 return operator*();
0361 }
0362
0363 bool operator==(const ValueMapIterator &RHS) const {
0364 return I == RHS.I;
0365 }
0366 bool operator!=(const ValueMapIterator &RHS) const {
0367 return I != RHS.I;
0368 }
0369
0370 inline ValueMapIterator& operator++() {
0371 ++I;
0372 return *this;
0373 }
0374 ValueMapIterator operator++(int) {
0375 ValueMapIterator tmp = *this; ++*this; return tmp;
0376 }
0377 };
0378
0379 template <typename DenseMapT, typename KeyT> class ValueMapConstIterator {
0380 using BaseT = typename DenseMapT::const_iterator;
0381 using ValueT = typename DenseMapT::mapped_type;
0382
0383 BaseT I;
0384
0385 public:
0386 using iterator_category = std::forward_iterator_tag;
0387 using value_type = std::pair<KeyT, typename DenseMapT::mapped_type>;
0388 using difference_type = std::ptrdiff_t;
0389 using pointer = value_type *;
0390 using reference = value_type &;
0391
0392 ValueMapConstIterator() : I() {}
0393 ValueMapConstIterator(BaseT I) : I(I) {}
0394 ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
0395 : I(Other.base()) {}
0396
0397 BaseT base() const { return I; }
0398
0399 struct ValueTypeProxy {
0400 const KeyT first;
0401 const ValueT& second;
0402 ValueTypeProxy *operator->() { return this; }
0403 operator std::pair<KeyT, ValueT>() const {
0404 return std::make_pair(first, second);
0405 }
0406 };
0407
0408 ValueTypeProxy operator*() const {
0409 ValueTypeProxy Result = {I->first.Unwrap(), I->second};
0410 return Result;
0411 }
0412
0413 ValueTypeProxy operator->() const {
0414 return operator*();
0415 }
0416
0417 bool operator==(const ValueMapConstIterator &RHS) const {
0418 return I == RHS.I;
0419 }
0420 bool operator!=(const ValueMapConstIterator &RHS) const {
0421 return I != RHS.I;
0422 }
0423
0424 inline ValueMapConstIterator& operator++() {
0425 ++I;
0426 return *this;
0427 }
0428 ValueMapConstIterator operator++(int) {
0429 ValueMapConstIterator tmp = *this; ++*this; return tmp;
0430 }
0431 };
0432
0433 }
0434
0435 #endif