Skip to content

Commit 1585db4

Browse files
authored
[IR] Optimize CFI in writeCombinedGlobalValueSummary (llvm#130382)
Before the patch, `writeCombinedGlobalValueSummary` traversed entire `cfiFunction*` for each module, just to pick a few symbols from `DefOrUseGUIDs`. Now we change internals of `cfiFunctionDefs` and `cfiFunctionDecls` to maintain a map from GUID to StringSet. So now we iterate `DefOrUseGUIDs`, usually small, and pick exact subset of symbols. Sorting is not strictly necessary, but it preserves the order of emitted values.
1 parent bf2d1c4 commit 1585db4

File tree

2 files changed

+56
-33
lines changed

2 files changed

+56
-33
lines changed

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,52 +1291,69 @@ 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()));
1313-
}
1311+
GlobalValue::GUID operator*() const { return this->wrapped()->first; }
13141312
};
13151313

13161314
CfiFunctionIndex() = default;
1317-
template <typename It> CfiFunctionIndex(It B, It E) : Index(B, E) {}
1318-
1319-
std::set<std::string, std::less<>>::const_iterator begin() const {
1320-
return Index.begin();
1315+
template <typename It> CfiFunctionIndex(It B, It E) {
1316+
for (; B != E; ++B)
1317+
emplace(*B);
13211318
}
13221319

1323-
std::set<std::string, std::less<>>::const_iterator end() const {
1324-
return Index.end();
1320+
std::vector<StringRef> symbols() const {
1321+
std::vector<StringRef> Symbols;
1322+
for (auto &[GUID, Syms] : Index)
1323+
Symbols.insert(Symbols.end(), Syms.begin(), Syms.end());
1324+
return Symbols;
13251325
}
13261326

1327-
std::vector<StringRef> symbols() const { return {begin(), end()}; }
1328-
13291327
GUIDIterator guid_begin() const { return GUIDIterator(Index.begin()); }
13301328
GUIDIterator guid_end() const { return GUIDIterator(Index.end()); }
13311329
iterator_range<GUIDIterator> guids() const {
13321330
return make_range(guid_begin(), guid_end());
13331331
}
13341332

1333+
iterator_range<NestedIterator> forGuid(GlobalValue::GUID GUID) const {
1334+
auto I = Index.find(GUID);
1335+
if (I == Index.end())
1336+
return make_range(NestedIterator{}, NestedIterator{});
1337+
return make_range(I->second.begin(), I->second.end());
1338+
}
1339+
13351340
template <typename... Args> void emplace(Args &&...A) {
1336-
Index.emplace(std::forward<Args>(A)...);
1341+
StringRef S(std::forward<Args>(A)...);
1342+
GlobalValue::GUID GUID =
1343+
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S));
1344+
Index[GUID].emplace(S);
1345+
}
1346+
1347+
size_t count(StringRef S) const {
1348+
GlobalValue::GUID GUID =
1349+
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S));
1350+
auto I = Index.find(GUID);
1351+
if (I == Index.end())
1352+
return 0;
1353+
return I->second.count(S);
13371354
}
13381355

1339-
size_t count(StringRef S) const { return Index.count(S); }
1356+
bool empty() const { return Index.empty(); }
13401357
};
13411358

13421359
/// 160 bits SHA1

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,19 +5064,25 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
50645064
getReferencedTypeIds(FS, ReferencedTypeIds);
50655065
}
50665066

5067+
SmallVector<StringRef, 4> Functions;
50675068
auto EmitCfiFunctions = [&](const CfiFunctionIndex &CfiIndex,
50685069
bitc::GlobalValueSummarySymtabCodes Code) {
5069-
for (auto &S : CfiIndex) {
5070-
if (DefOrUseGUIDs.contains(
5071-
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
5072-
NameVals.push_back(StrtabBuilder.add(S));
5073-
NameVals.push_back(S.size());
5074-
}
5070+
if (CfiIndex.empty())
5071+
return;
5072+
for (GlobalValue::GUID GUID : DefOrUseGUIDs) {
5073+
auto Defs = CfiIndex.forGuid(GUID);
5074+
Functions.insert(Functions.end(), Defs.begin(), Defs.end());
50755075
}
5076-
if (!NameVals.empty()) {
5077-
Stream.EmitRecord(Code, NameVals);
5078-
NameVals.clear();
5076+
if (Functions.empty())
5077+
return;
5078+
llvm::sort(Functions);
5079+
for (const auto &S : Functions) {
5080+
NameVals.push_back(StrtabBuilder.add(S));
5081+
NameVals.push_back(S.size());
50795082
}
5083+
Stream.EmitRecord(Code, NameVals);
5084+
NameVals.clear();
5085+
Functions.clear();
50805086
};
50815087

50825088
EmitCfiFunctions(Index.cfiFunctionDefs(), bitc::FS_CFI_FUNCTION_DEFS);

0 commit comments

Comments
 (0)