Skip to content

Commit 549fc30

Browse files
committed
[APINotes] Reduce memory footprint for Obj-C/C++ contexts
We were storing extraneous data for certain Objective-C/C++ entities. Specifically, for declarations that can be nested in another context (such as functions) we were storing the kind of the parent context in addition to its ID. The ID is always sufficient. This removes the logically incorrect usages of `ContextTableKey` that don't actually describe a context, but rather describe a single declaration. This introduces `SingleDeclTableKey` to store that kind of entities in a more compact and reasonable way. (cherry picked from commit c5f402f)
1 parent ecdd17a commit 549fc30

File tree

3 files changed

+84
-51
lines changed

3 files changed

+84
-51
lines changed

clang/lib/APINotes/APINotesFormat.h

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
2424
/// API notes file minor version number.
2525
///
2626
/// When the format changes IN ANY WAY, this number should be incremented.
27-
const uint16_t VERSION_MINOR = 26; // SwiftCopyable
27+
const uint16_t VERSION_MINOR = 27; // SingleDeclTableKey
2828

2929
const uint8_t kSwiftCopyable = 1;
3030
const uint8_t kSwiftNonCopyable = 2;
@@ -269,12 +269,6 @@ struct ContextTableKey {
269269
: parentContextID(parentContextID), contextKind(contextKind),
270270
contextID(contextID) {}
271271

272-
ContextTableKey(std::optional<Context> context, IdentifierID nameID)
273-
: parentContextID(context ? context->id.Value : (uint32_t)-1),
274-
contextKind(context ? static_cast<uint8_t>(context->kind)
275-
: static_cast<uint8_t>(-1)),
276-
contextID(nameID) {}
277-
278272
llvm::hash_code hashValue() const {
279273
return llvm::hash_value(
280274
std::tuple{parentContextID, contextKind, contextID});
@@ -286,6 +280,32 @@ inline bool operator==(const ContextTableKey &lhs, const ContextTableKey &rhs) {
286280
lhs.contextKind == rhs.contextKind && lhs.contextID == rhs.contextID;
287281
}
288282

283+
/// A stored Objective-C or C++ declaration, represented by the ID of its parent
284+
/// context, and the name of the declaration.
285+
struct SingleDeclTableKey {
286+
uint32_t parentContextID;
287+
uint32_t nameID;
288+
289+
SingleDeclTableKey() : parentContextID(-1), nameID(-1) {}
290+
291+
SingleDeclTableKey(uint32_t ParentContextID, uint32_t NameID)
292+
: parentContextID(ParentContextID), nameID(NameID) {}
293+
294+
SingleDeclTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)
295+
: parentContextID(ParentCtx ? ParentCtx->id.Value
296+
: static_cast<uint32_t>(-1)),
297+
nameID(NameID) {}
298+
299+
llvm::hash_code hashValue() const {
300+
return llvm::hash_value(std::make_pair(parentContextID, nameID));
301+
}
302+
};
303+
304+
inline bool operator==(const SingleDeclTableKey &lhs,
305+
const SingleDeclTableKey &rhs) {
306+
return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID;
307+
}
308+
289309
} // namespace api_notes
290310
} // namespace clang
291311

@@ -341,6 +361,29 @@ template <> struct DenseMapInfo<clang::api_notes::ContextTableKey> {
341361
return lhs == rhs;
342362
}
343363
};
364+
365+
template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
366+
static inline clang::api_notes::SingleDeclTableKey getEmptyKey() {
367+
return clang::api_notes::SingleDeclTableKey();
368+
}
369+
370+
static inline clang::api_notes::SingleDeclTableKey getTombstoneKey() {
371+
return clang::api_notes::SingleDeclTableKey{
372+
DenseMapInfo<uint32_t>::getTombstoneKey(),
373+
DenseMapInfo<uint32_t>::getTombstoneKey()};
374+
}
375+
376+
static unsigned
377+
getHashValue(const clang::api_notes::SingleDeclTableKey &value) {
378+
return value.hashValue();
379+
}
380+
381+
static bool isEqual(const clang::api_notes::SingleDeclTableKey &lhs,
382+
const clang::api_notes::SingleDeclTableKey &rhs) {
383+
return lhs == rhs;
384+
}
385+
};
386+
344387
} // namespace llvm
345388

346389
#endif

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -429,15 +429,13 @@ class ObjCSelectorTableInfo {
429429

430430
/// Used to deserialize the on-disk global variable table.
431431
class GlobalVariableTableInfo
432-
: public VersionedTableInfo<GlobalVariableTableInfo, ContextTableKey,
432+
: public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
433433
GlobalVariableInfo> {
434434
public:
435435
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
436436
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
437-
auto ContextKind =
438-
endian::readNext<uint8_t, llvm::endianness::little>(Data);
439437
auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
440-
return {CtxID, ContextKind, NameID};
438+
return {CtxID, NameID};
441439
}
442440

443441
hash_value_type ComputeHash(internal_key_type Key) {
@@ -454,15 +452,13 @@ class GlobalVariableTableInfo
454452

455453
/// Used to deserialize the on-disk global function table.
456454
class GlobalFunctionTableInfo
457-
: public VersionedTableInfo<GlobalFunctionTableInfo, ContextTableKey,
455+
: public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
458456
GlobalFunctionInfo> {
459457
public:
460458
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
461459
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
462-
auto ContextKind =
463-
endian::readNext<uint8_t, llvm::endianness::little>(Data);
464460
auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
465-
return {CtxID, ContextKind, NameID};
461+
return {CtxID, NameID};
466462
}
467463

468464
hash_value_type ComputeHash(internal_key_type Key) {
@@ -501,15 +497,13 @@ class EnumConstantTableInfo
501497

502498
/// Used to deserialize the on-disk tag table.
503499
class TagTableInfo
504-
: public VersionedTableInfo<TagTableInfo, ContextTableKey, TagInfo> {
500+
: public VersionedTableInfo<TagTableInfo, SingleDeclTableKey, TagInfo> {
505501
public:
506502
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
507503
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
508-
auto ContextKind =
509-
endian::readNext<uint8_t, llvm::endianness::little>(Data);
510504
auto NameID =
511505
endian::readNext<IdentifierID, llvm::endianness::little>(Data);
512-
return {CtxID, ContextKind, NameID};
506+
return {CtxID, NameID};
513507
}
514508

515509
hash_value_type ComputeHash(internal_key_type Key) {
@@ -563,16 +557,14 @@ class TagTableInfo
563557

564558
/// Used to deserialize the on-disk typedef table.
565559
class TypedefTableInfo
566-
: public VersionedTableInfo<TypedefTableInfo, ContextTableKey,
560+
: public VersionedTableInfo<TypedefTableInfo, SingleDeclTableKey,
567561
TypedefInfo> {
568562
public:
569563
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
570564
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
571-
auto ContextKind =
572-
endian::readNext<uint8_t, llvm::endianness::little>(Data);
573565
auto nameID =
574566
endian::readNext<IdentifierID, llvm::endianness::little>(Data);
575-
return {CtxID, ContextKind, nameID};
567+
return {CtxID, nameID};
576568
}
577569

578570
hash_value_type ComputeHash(internal_key_type Key) {
@@ -1941,7 +1933,7 @@ auto APINotesReader::lookupGlobalVariable(llvm::StringRef Name,
19411933
if (!NameID)
19421934
return std::nullopt;
19431935

1944-
ContextTableKey Key(Ctx, *NameID);
1936+
SingleDeclTableKey Key(Ctx, *NameID);
19451937

19461938
auto Known = Implementation->GlobalVariableTable->find(Key);
19471939
if (Known == Implementation->GlobalVariableTable->end())
@@ -1960,7 +1952,7 @@ auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name,
19601952
if (!NameID)
19611953
return std::nullopt;
19621954

1963-
ContextTableKey Key(Ctx, *NameID);
1955+
SingleDeclTableKey Key(Ctx, *NameID);
19641956

19651957
auto Known = Implementation->GlobalFunctionTable->find(Key);
19661958
if (Known == Implementation->GlobalFunctionTable->end())
@@ -1994,7 +1986,7 @@ auto APINotesReader::lookupTag(llvm::StringRef Name, std::optional<Context> Ctx)
19941986
if (!NameID)
19951987
return std::nullopt;
19961988

1997-
ContextTableKey Key(Ctx, *NameID);
1989+
SingleDeclTableKey Key(Ctx, *NameID);
19981990

19991991
auto Known = Implementation->TagTable->find(Key);
20001992
if (Known == Implementation->TagTable->end())
@@ -2013,7 +2005,7 @@ auto APINotesReader::lookupTypedef(llvm::StringRef Name,
20132005
if (!NameID)
20142006
return std::nullopt;
20152007

2016-
ContextTableKey Key(Ctx, *NameID);
2008+
SingleDeclTableKey Key(Ctx, *NameID);
20172009

20182010
auto Known = Implementation->TypedefTable->find(Key);
20192011
if (Known == Implementation->TypedefTable->end())

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,17 @@ class APINotesWriter::Implementation {
7777

7878
/// Information about global variables.
7979
///
80-
/// Indexed by the context ID, contextKind, identifier ID.
80+
/// Indexed by the context ID, identifier ID.
8181
llvm::DenseMap<
82-
ContextTableKey,
82+
SingleDeclTableKey,
8383
llvm::SmallVector<std::pair<VersionTuple, GlobalVariableInfo>, 1>>
8484
GlobalVariables;
8585

8686
/// Information about global functions.
8787
///
88-
/// Indexed by the context ID, contextKind, identifier ID.
88+
/// Indexed by the context ID, identifier ID.
8989
llvm::DenseMap<
90-
ContextTableKey,
90+
SingleDeclTableKey,
9191
llvm::SmallVector<std::pair<VersionTuple, GlobalFunctionInfo>, 1>>
9292
GlobalFunctions;
9393

@@ -100,15 +100,15 @@ class APINotesWriter::Implementation {
100100

101101
/// Information about tags.
102102
///
103-
/// Indexed by the context ID, contextKind, identifier ID.
104-
llvm::DenseMap<ContextTableKey,
103+
/// Indexed by the context ID, identifier ID.
104+
llvm::DenseMap<SingleDeclTableKey,
105105
llvm::SmallVector<std::pair<VersionTuple, TagInfo>, 1>>
106106
Tags;
107107

108108
/// Information about typedefs.
109109
///
110-
/// Indexed by the context ID, contextKind, identifier ID.
111-
llvm::DenseMap<ContextTableKey,
110+
/// Indexed by the context ID, identifier ID.
111+
llvm::DenseMap<SingleDeclTableKey,
112112
llvm::SmallVector<std::pair<VersionTuple, TypedefInfo>, 1>>
113113
Typedefs;
114114

@@ -872,18 +872,17 @@ void APINotesWriter::Implementation::writeObjCSelectorBlock(
872872
namespace {
873873
/// Used to serialize the on-disk global variable table.
874874
class GlobalVariableTableInfo
875-
: public VersionedTableInfo<GlobalVariableTableInfo, ContextTableKey,
875+
: public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
876876
GlobalVariableInfo> {
877877
public:
878878
unsigned getKeyLength(key_type_ref) {
879-
return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
879+
return sizeof(uint32_t) + sizeof(uint32_t);
880880
}
881881

882882
void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) {
883883
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
884884
writer.write<uint32_t>(Key.parentContextID);
885-
writer.write<uint8_t>(Key.contextKind);
886-
writer.write<uint32_t>(Key.contextID);
885+
writer.write<uint32_t>(Key.nameID);
887886
}
888887

889888
hash_value_type ComputeHash(key_type_ref Key) {
@@ -986,18 +985,17 @@ void emitFunctionInfo(raw_ostream &OS, const FunctionInfo &FI) {
986985

987986
/// Used to serialize the on-disk global function table.
988987
class GlobalFunctionTableInfo
989-
: public VersionedTableInfo<GlobalFunctionTableInfo, ContextTableKey,
988+
: public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
990989
GlobalFunctionInfo> {
991990
public:
992991
unsigned getKeyLength(key_type_ref) {
993-
return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
992+
return sizeof(uint32_t) + sizeof(uint32_t);
994993
}
995994

996995
void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) {
997996
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
998997
writer.write<uint32_t>(Key.parentContextID);
999-
writer.write<uint8_t>(Key.contextKind);
1000-
writer.write<uint32_t>(Key.contextID);
998+
writer.write<uint32_t>(Key.nameID);
1001999
}
10021000

10031001
hash_value_type ComputeHash(key_type_ref Key) {
@@ -1098,20 +1096,20 @@ void APINotesWriter::Implementation::writeEnumConstantBlock(
10981096
namespace {
10991097
template <typename Derived, typename UnversionedDataType>
11001098
class CommonTypeTableInfo
1101-
: public VersionedTableInfo<Derived, ContextTableKey, UnversionedDataType> {
1099+
: public VersionedTableInfo<Derived, SingleDeclTableKey,
1100+
UnversionedDataType> {
11021101
public:
11031102
using key_type_ref = typename CommonTypeTableInfo::key_type_ref;
11041103
using hash_value_type = typename CommonTypeTableInfo::hash_value_type;
11051104

11061105
unsigned getKeyLength(key_type_ref) {
1107-
return sizeof(uint32_t) + sizeof(uint8_t) + sizeof(IdentifierID);
1106+
return sizeof(uint32_t) + sizeof(IdentifierID);
11081107
}
11091108

11101109
void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) {
11111110
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
11121111
writer.write<uint32_t>(Key.parentContextID);
1113-
writer.write<uint8_t>(Key.contextKind);
1114-
writer.write<IdentifierID>(Key.contextID);
1112+
writer.write<IdentifierID>(Key.nameID);
11151113
}
11161114

11171115
hash_value_type ComputeHash(key_type_ref Key) {
@@ -1358,7 +1356,7 @@ void APINotesWriter::addGlobalVariable(std::optional<Context> Ctx,
13581356
const GlobalVariableInfo &Info,
13591357
VersionTuple SwiftVersion) {
13601358
IdentifierID VariableID = Implementation->getIdentifier(Name);
1361-
ContextTableKey Key(Ctx, VariableID);
1359+
SingleDeclTableKey Key(Ctx, VariableID);
13621360
Implementation->GlobalVariables[Key].push_back({SwiftVersion, Info});
13631361
}
13641362

@@ -1367,7 +1365,7 @@ void APINotesWriter::addGlobalFunction(std::optional<Context> Ctx,
13671365
const GlobalFunctionInfo &Info,
13681366
VersionTuple SwiftVersion) {
13691367
IdentifierID NameID = Implementation->getIdentifier(Name);
1370-
ContextTableKey Key(Ctx, NameID);
1368+
SingleDeclTableKey Key(Ctx, NameID);
13711369
Implementation->GlobalFunctions[Key].push_back({SwiftVersion, Info});
13721370
}
13731371

@@ -1381,15 +1379,15 @@ void APINotesWriter::addEnumConstant(llvm::StringRef Name,
13811379
void APINotesWriter::addTag(std::optional<Context> Ctx, llvm::StringRef Name,
13821380
const TagInfo &Info, VersionTuple SwiftVersion) {
13831381
IdentifierID TagID = Implementation->getIdentifier(Name);
1384-
ContextTableKey Key(Ctx, TagID);
1382+
SingleDeclTableKey Key(Ctx, TagID);
13851383
Implementation->Tags[Key].push_back({SwiftVersion, Info});
13861384
}
13871385

13881386
void APINotesWriter::addTypedef(std::optional<Context> Ctx,
13891387
llvm::StringRef Name, const TypedefInfo &Info,
13901388
VersionTuple SwiftVersion) {
13911389
IdentifierID TypedefID = Implementation->getIdentifier(Name);
1392-
ContextTableKey Key(Ctx, TypedefID);
1390+
SingleDeclTableKey Key(Ctx, TypedefID);
13931391
Implementation->Typedefs[Key].push_back({SwiftVersion, Info});
13941392
}
13951393

0 commit comments

Comments
 (0)