@@ -1291,37 +1291,86 @@ struct TypeIdSummary {
12911291};
12921292
12931293class CfiFunctionIndex {
1294- std::set<std::string, std::less<>> Index;
1294+ DenseMap<GlobalValue::GUID, std::set<std::string, std::less<>>> Index;
1295+ using IndexIterator =
1296+ DenseMap<GlobalValue::GUID,
1297+ std::set<std::string, std::less<>>>::const_iterator;
1298+ using NestedIterator = std::set<std::string, std::less<>>::const_iterator;
12951299
12961300public:
1297- class GUIDIterator
1298- : public iterator_adaptor_base<
1299- GUIDIterator, std::set<std::string, std::less<>>::const_iterator,
1300- std::forward_iterator_tag, GlobalValue::GUID> {
1301- using base = iterator_adaptor_base<
1302- GUIDIterator, std::set<std::string, std::less<>>::const_iterator,
1303- std::forward_iterator_tag, GlobalValue::GUID>;
1301+ // Iterates keys of the DenseMap.
1302+ class GUIDIterator : public iterator_adaptor_base <GUIDIterator, IndexIterator,
1303+ std::forward_iterator_tag,
1304+ GlobalValue::GUID> {
1305+ using base = GUIDIterator::iterator_adaptor_base;
13041306
13051307 public:
13061308 GUIDIterator () = default ;
1307- explicit GUIDIterator (std::set<std::string, std::less<>>::const_iterator I)
1308- : base(std::move(I)) {}
1309+ explicit GUIDIterator (IndexIterator I) : base(I) {}
13091310
1310- GlobalValue::GUID operator *() const {
1311- return GlobalValue::getGUID (
1312- GlobalValue::dropLLVMManglingEscape (*this ->wrapped ()));
1311+ GlobalValue::GUID operator *() const { return this ->wrapped ()->first ; }
1312+ };
1313+
1314+ // Iterates merged values of the DenseMap.
1315+ class SymbolIterator
1316+ : public iterator_facade_base<SymbolIterator, std::forward_iterator_tag,
1317+ std::string> {
1318+ using base = SymbolIterator::iterator_facade_base;
1319+
1320+ IndexIterator Outer;
1321+ IndexIterator OuterEnd;
1322+ NestedIterator Inner;
1323+
1324+ public:
1325+ SymbolIterator () = default ;
1326+ SymbolIterator (IndexIterator Outer, IndexIterator OuterEnd)
1327+ : Outer(Outer), OuterEnd(OuterEnd),
1328+ Inner (Outer != OuterEnd ? Outer->second.begin() : NestedIterator{}) {}
1329+ SymbolIterator (SymbolIterator &R) = default ;
1330+
1331+ const std::string &operator *() const { return *Inner; }
1332+
1333+ SymbolIterator &operator ++() {
1334+ // `DenseMap` never contains empty sets. So:
1335+ // 1. `Outer` points to non-empty set, if `Outer` != `OuterEnd`.
1336+ // 2. `Inner` always is valid and dereferenceable, if `Outer` !=
1337+ // `OuterEnd`.
1338+ assert (Outer != OuterEnd);
1339+ assert (!Outer->second .empty ());
1340+ ++Inner;
1341+ if (Inner == Outer->second .end ()) {
1342+ ++Outer;
1343+ Inner = Outer != OuterEnd ? Outer->second .begin () : NestedIterator{};
1344+ }
1345+ return *this ;
1346+ }
1347+
1348+ SymbolIterator &operator =(const SymbolIterator &R) {
1349+ if (this != &R) {
1350+ Outer = R.Outer ;
1351+ OuterEnd = R.OuterEnd ;
1352+ Inner = R.Inner ;
1353+ }
1354+ return *this ;
1355+ }
1356+
1357+ bool operator ==(const SymbolIterator &R) const {
1358+ return Outer == R.Outer && Inner == R.Inner ;
13131359 }
13141360 };
13151361
13161362 CfiFunctionIndex () = default ;
1317- template <typename It> CfiFunctionIndex (It B, It E) : Index(B, E) {}
1363+ template <typename It> CfiFunctionIndex (It B, It E) {
1364+ for (; B != E; ++B)
1365+ emplace (*B);
1366+ }
13181367
1319- std::set<std::string, std::less<>>::const_iterator begin () const {
1320- return Index.begin ();
1368+ SymbolIterator begin () const {
1369+ return SymbolIterator ( Index.begin (), Index. end () );
13211370 }
13221371
1323- std::set<std::string, std::less<>>::const_iterator end () const {
1324- return Index.end ();
1372+ SymbolIterator end () const {
1373+ return SymbolIterator ( Index.end (), Index. end () );
13251374 }
13261375
13271376 GUIDIterator guid_begin () const { return GUIDIterator (Index.begin ()); }
@@ -1330,11 +1379,28 @@ class CfiFunctionIndex {
13301379 return make_range (guid_begin (), guid_end ());
13311380 }
13321381
1382+ iterator_range<NestedIterator> forGuid (GlobalValue::GUID GUID) const {
1383+ auto I = Index.find (GUID);
1384+ if (I == Index.end ())
1385+ return make_range (NestedIterator{}, NestedIterator{});
1386+ return make_range (I->second .begin (), I->second .end ());
1387+ }
1388+
13331389 template <typename ... Args> void emplace (Args &&...A) {
1334- Index.emplace (std::forward<Args>(A)...);
1390+ StringRef S (std::forward<Args>(A)...);
1391+ GlobalValue::GUID GUID =
1392+ GlobalValue::getGUID (GlobalValue::dropLLVMManglingEscape (S));
1393+ Index[GUID].emplace (S);
13351394 }
13361395
1337- size_t count (StringRef S) const { return Index.count (S); }
1396+ size_t count (StringRef S) const {
1397+ GlobalValue::GUID GUID =
1398+ GlobalValue::getGUID (GlobalValue::dropLLVMManglingEscape (S));
1399+ auto I = Index.find (GUID);
1400+ if (I == Index.end ())
1401+ return 0 ;
1402+ return I->second .count (S);
1403+ }
13381404};
13391405
13401406// / 160 bits SHA1
0 commit comments