Skip to content

Commit 09246d1

Browse files
committed
[clang][modules] Shrink the size of Module::Headers
This patch shrinks the size of the `Module` class from 2112B to 1624B. I wasn't able to get a good data on the actual impact on memory usage, but given my `clang-scan-deps` workload at hand (with tens of thousands of instances), I think there should be some win here. This also speeds up my benchmark by under 0.1%.
1 parent 2e0506f commit 09246d1

File tree

5 files changed

+31
-15
lines changed

5 files changed

+31
-15
lines changed

clang/include/clang/Basic/Module.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,22 @@ class alignas(8) Module {
271271
DirectoryEntryRef Entry;
272272
};
273273

274-
/// The headers that are part of this module.
275-
SmallVector<Header, 2> Headers[5];
274+
private:
275+
unsigned HeaderKindBeginIndex[6] = {};
276+
SmallVector<Header, 2> HeadersStorage;
277+
278+
public:
279+
ArrayRef<Header> getHeaders(HeaderKind HK) const {
280+
auto BeginIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK];
281+
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
282+
return {BeginIt, EndIt};
283+
}
284+
void addHeader(HeaderKind HK, Header H) {
285+
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
286+
HeadersStorage.insert(EndIt, std::move(H));
287+
for (unsigned HKI = HK + 1; HKI != 6; ++HKI)
288+
++HeaderKindBeginIndex[HKI];
289+
}
276290

277291
/// Stored information about a header directive that was found in the
278292
/// module map file but has not been resolved to a file.

clang/lib/Basic/Module.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
528528

529529
for (auto &K : Kinds) {
530530
assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
531-
for (auto &H : Headers[K.Kind]) {
531+
for (auto &H : getHeaders(K.Kind)) {
532532
OS.indent(Indent + 2);
533533
OS << K.Prefix << "header \"";
534534
OS.write_escaped(H.NameAsWritten);

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ static std::error_code collectModuleHeaderIncludes(
358358

359359
// Add includes for each of these headers.
360360
for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
361-
for (Module::Header &H : Module->Headers[HK]) {
361+
for (const Module::Header &H : Module->getHeaders(HK)) {
362362
Module->addTopHeader(H.Entry);
363363
// Use the path as specified in the module map file. We'll look for this
364364
// file relative to the module build directory (the directory containing

clang/lib/Lex/ModuleMap.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,12 @@ static bool violatesPrivateInclude(Module *RequestingModule,
472472
// as obtained from the lookup and as obtained from the module.
473473
// This check is not cheap, so enable it only for debugging.
474474
bool IsPrivate = false;
475-
SmallVectorImpl<Module::Header> *HeaderList[] = {
476-
&Header.getModule()->Headers[Module::HK_Private],
477-
&Header.getModule()->Headers[Module::HK_PrivateTextual]};
478-
for (auto *Hs : HeaderList)
475+
ArrayRef<Module::Header> HeaderList[] = {
476+
Header.getModule()->getHeaders(Module::HK_Private),
477+
Header.getModule()->getHeaders(Module::HK_PrivateTextual)};
478+
for (auto Hs : HeaderList)
479479
IsPrivate |= llvm::any_of(
480-
*Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
480+
Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
481481
assert(IsPrivate && "inconsistent headers and roles");
482482
}
483483
#endif
@@ -1296,27 +1296,29 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
12961296
ModuleHeaderRole Role, bool Imported) {
12971297
KnownHeader KH(Mod, Role);
12981298

1299+
FileEntryRef HeaderEntry = Header.Entry;
1300+
12991301
// Only add each header to the headers list once.
13001302
// FIXME: Should we diagnose if a header is listed twice in the
13011303
// same module definition?
1302-
auto &HeaderList = Headers[Header.Entry];
1304+
auto &HeaderList = Headers[HeaderEntry];
13031305
if (llvm::is_contained(HeaderList, KH))
13041306
return;
13051307

13061308
HeaderList.push_back(KH);
1307-
Mod->Headers[headerRoleToKind(Role)].push_back(Header);
1309+
Mod->addHeader(headerRoleToKind(Role), std::move(Header));
13081310

13091311
bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
13101312
if (!Imported || isCompilingModuleHeader) {
13111313
// When we import HeaderFileInfo, the external source is expected to
13121314
// set the isModuleHeader flag itself.
1313-
HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1315+
HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role,
13141316
isCompilingModuleHeader);
13151317
}
13161318

13171319
// Notify callbacks that we just added a new header.
13181320
for (const auto &Cb : Callbacks)
1319-
Cb->moduleMapAddHeader(Header.Entry.getName());
1321+
Cb->moduleMapAddHeader(HeaderEntry.getName());
13201322
}
13211323

13221324
FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,9 +3070,9 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
30703070
Module::HK_PrivateTextual},
30713071
{SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Module::HK_Excluded}
30723072
};
3073-
for (auto &HL : HeaderLists) {
3073+
for (const auto &HL : HeaderLists) {
30743074
RecordData::value_type Record[] = {HL.RecordKind};
3075-
for (auto &H : Mod->Headers[HL.HeaderKind])
3075+
for (const auto &H : Mod->getHeaders(HL.HeaderKind))
30763076
Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten);
30773077
}
30783078

0 commit comments

Comments
 (0)