Skip to content

Commit e5af6e0

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
1 parent 7dd5f23 commit e5af6e0

File tree

2 files changed

+103
-30
lines changed

2 files changed

+103
-30
lines changed

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,37 +1291,86 @@ struct TypeIdSummary {
12911291
};
12921292

12931293
class 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

12961300
public:
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

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,28 +5064,35 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
50645064
getReferencedTypeIds(FS, ReferencedTypeIds);
50655065
}
50665066

5067-
for (auto &S : Index.cfiFunctionDefs()) {
5068-
if (DefOrUseGUIDs.contains(
5069-
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
5067+
SmallVector<StringRef, 4> Functions;
5068+
for (GlobalValue::GUID GUID : DefOrUseGUIDs) {
5069+
auto Defs = Index.cfiFunctionDefs().forGuid(GUID);
5070+
Functions.insert(Functions.end(), Defs.begin(), Defs.end());
5071+
}
5072+
if (!Functions.empty()) {
5073+
std::sort(Functions.begin(), Functions.end());
5074+
for (const auto &S : Functions) {
50705075
NameVals.push_back(StrtabBuilder.add(S));
50715076
NameVals.push_back(S.size());
50725077
}
5073-
}
5074-
if (!NameVals.empty()) {
50755078
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DEFS, NameVals);
50765079
NameVals.clear();
5080+
Functions.clear();
50775081
}
50785082

5079-
for (auto &S : Index.cfiFunctionDecls()) {
5080-
if (DefOrUseGUIDs.contains(
5081-
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
5083+
for (GlobalValue::GUID GUID : DefOrUseGUIDs) {
5084+
auto Decls = Index.cfiFunctionDecls().forGuid(GUID);
5085+
Functions.insert(Functions.end(), Decls.begin(), Decls.end());
5086+
}
5087+
if (!Functions.empty()) {
5088+
std::sort(Functions.begin(), Functions.end());
5089+
for (const auto &S : Functions) {
50825090
NameVals.push_back(StrtabBuilder.add(S));
50835091
NameVals.push_back(S.size());
50845092
}
5085-
}
5086-
if (!NameVals.empty()) {
50875093
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DECLS, NameVals);
50885094
NameVals.clear();
5095+
Functions.clear();
50895096
}
50905097

50915098
// Walk the GUIDs that were referenced, and write the

0 commit comments

Comments
 (0)