Skip to content

Commit fa88419

Browse files
ChuanqiXu9AlexisPerry
authored andcommitted
[HeaderSearch] Introduce LazyIdentifierInfoPtr for Controlling Macro in HeaderFileInfo
This patch is helpful to reduce 32 bits for HeaderFileInfo by combining a uint32_t and pointer into a tagged pointer. This is reviewed as part of llvm#92085 and required to be split as a separate commit
1 parent aa2141a commit fa88419

File tree

5 files changed

+76
-30
lines changed

5 files changed

+76
-30
lines changed

clang/include/clang/Lex/ExternalPreprocessorSource.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,58 @@ class ExternalPreprocessorSource {
4242
virtual Module *getModule(unsigned ModuleID) = 0;
4343
};
4444

45+
// Either a pointer to an IdentifierInfo of the controlling macro or the ID
46+
// number of the controlling macro.
47+
class LazyIdentifierInfoPtr {
48+
// If the low bit is clear, a pointer to the IdentifierInfo. If the low
49+
// bit is set, the upper 63 bits are the ID number.
50+
mutable uint64_t Ptr = 0;
51+
52+
public:
53+
LazyIdentifierInfoPtr() = default;
54+
55+
explicit LazyIdentifierInfoPtr(const IdentifierInfo *Ptr)
56+
: Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
57+
58+
explicit LazyIdentifierInfoPtr(uint64_t ID) : Ptr((ID << 1) | 0x01) {
59+
assert((ID << 1 >> 1) == ID && "ID must require < 63 bits");
60+
if (ID == 0)
61+
Ptr = 0;
62+
}
63+
64+
LazyIdentifierInfoPtr &operator=(const IdentifierInfo *Ptr) {
65+
this->Ptr = reinterpret_cast<uint64_t>(Ptr);
66+
return *this;
67+
}
68+
69+
LazyIdentifierInfoPtr &operator=(uint64_t ID) {
70+
assert((ID << 1 >> 1) == ID && "IDs must require < 63 bits");
71+
if (ID == 0)
72+
Ptr = 0;
73+
else
74+
Ptr = (ID << 1) | 0x01;
75+
76+
return *this;
77+
}
78+
79+
/// Whether this pointer is non-NULL.
80+
///
81+
/// This operation does not require the AST node to be deserialized.
82+
bool isValid() const { return Ptr != 0; }
83+
84+
/// Whether this pointer is currently stored as ID.
85+
bool isID() const { return Ptr & 0x01; }
86+
87+
IdentifierInfo *getPtr() const {
88+
assert(!isID());
89+
return reinterpret_cast<IdentifierInfo *>(Ptr);
90+
}
91+
92+
uint64_t getID() const {
93+
assert(isID());
94+
return Ptr >> 1;
95+
}
96+
};
4597
}
4698

4799
#endif

clang/include/clang/Lex/HeaderSearch.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "clang/Basic/SourceLocation.h"
1717
#include "clang/Basic/SourceManager.h"
1818
#include "clang/Lex/DirectoryLookup.h"
19+
#include "clang/Lex/ExternalPreprocessorSource.h"
1920
#include "clang/Lex/HeaderMap.h"
2021
#include "clang/Lex/ModuleMap.h"
2122
#include "llvm/ADT/ArrayRef.h"
@@ -121,13 +122,6 @@ struct HeaderFileInfo {
121122
LLVM_PREFERRED_TYPE(bool)
122123
unsigned IsValid : 1;
123124

124-
/// The ID number of the controlling macro.
125-
///
126-
/// This ID number will be non-zero when there is a controlling
127-
/// macro whose IdentifierInfo may not yet have been loaded from
128-
/// external storage.
129-
unsigned ControllingMacroID = 0;
130-
131125
/// If this file has a \#ifndef XXX (or equivalent) guard that
132126
/// protects the entire contents of the file, this is the identifier
133127
/// for the macro that controls whether or not it has any effect.
@@ -136,7 +130,7 @@ struct HeaderFileInfo {
136130
/// the controlling macro of this header, since
137131
/// getControllingMacro() is able to load a controlling macro from
138132
/// external storage.
139-
const IdentifierInfo *ControllingMacro = nullptr;
133+
LazyIdentifierInfoPtr LazyControllingMacro;
140134

141135
/// If this header came from a framework include, this is the name
142136
/// of the framework.
@@ -582,7 +576,7 @@ class HeaderSearch {
582576
/// no-op \#includes.
583577
void SetFileControllingMacro(FileEntryRef File,
584578
const IdentifierInfo *ControllingMacro) {
585-
getFileInfo(File).ControllingMacro = ControllingMacro;
579+
getFileInfo(File).LazyControllingMacro = ControllingMacro;
586580
}
587581

588582
/// Determine whether this file is intended to be safe from

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,21 @@ ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
6060

6161
const IdentifierInfo *
6262
HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
63-
if (ControllingMacro) {
64-
if (ControllingMacro->isOutOfDate()) {
65-
assert(External && "We must have an external source if we have a "
66-
"controlling macro that is out of date.");
67-
External->updateOutOfDateIdentifier(*ControllingMacro);
68-
}
69-
return ControllingMacro;
70-
}
63+
if (LazyControllingMacro.isID()) {
64+
if (!External)
65+
return nullptr;
7166

72-
if (!ControllingMacroID || !External)
73-
return nullptr;
67+
LazyControllingMacro =
68+
External->GetIdentifier(LazyControllingMacro.getID());
69+
return LazyControllingMacro.getPtr();
70+
}
7471

75-
ControllingMacro = External->GetIdentifier(ControllingMacroID);
72+
IdentifierInfo *ControllingMacro = LazyControllingMacro.getPtr();
73+
if (ControllingMacro && ControllingMacro->isOutOfDate()) {
74+
assert(External && "We must have an external source if we have a "
75+
"controlling macro that is out of date.");
76+
External->updateOutOfDateIdentifier(*ControllingMacro);
77+
}
7678
return ControllingMacro;
7779
}
7880

@@ -1348,10 +1350,8 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
13481350
mergeHeaderFileInfoModuleBits(HFI, OtherHFI.isModuleHeader,
13491351
OtherHFI.isTextualModuleHeader);
13501352

1351-
if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
1352-
HFI.ControllingMacro = OtherHFI.ControllingMacro;
1353-
HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
1354-
}
1353+
if (!HFI.LazyControllingMacro.isValid())
1354+
HFI.LazyControllingMacro = OtherHFI.LazyControllingMacro;
13551355

13561356
HFI.DirInfo = OtherHFI.DirInfo;
13571357
HFI.External = (!HFI.IsValid || HFI.External);
@@ -1426,8 +1426,7 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(FileEntryRef File) const {
14261426
// once. Note that we dor't check for #import, because that's not a property
14271427
// of the file itself.
14281428
if (auto *HFI = getExistingFileInfo(File))
1429-
return HFI->isPragmaOnce || HFI->ControllingMacro ||
1430-
HFI->ControllingMacroID;
1429+
return HFI->isPragmaOnce || HFI->LazyControllingMacro.isValid();
14311430
return false;
14321431
}
14331432

clang/lib/Serialization/ASTReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
20922092
HFI.isPragmaOnce |= (Flags >> 4) & 0x01;
20932093
HFI.DirInfo = (Flags >> 1) & 0x07;
20942094
HFI.IndexHeaderMapHeader = Flags & 0x01;
2095-
HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
2095+
HFI.LazyControllingMacro = Reader.getGlobalIdentifierID(
20962096
M, endian::readNext<uint32_t, llvm::endianness::little>(d));
20972097
if (unsigned FrameworkOffset =
20982098
endian::readNext<uint32_t, llvm::endianness::little>(d)) {

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,10 +2028,11 @@ namespace {
20282028
| Data.HFI.IndexHeaderMapHeader;
20292029
LE.write<uint8_t>(Flags);
20302030

2031-
if (!Data.HFI.ControllingMacro)
2032-
LE.write<uint32_t>(Data.HFI.ControllingMacroID);
2031+
if (Data.HFI.LazyControllingMacro.isID())
2032+
LE.write<IdentifierID>(Data.HFI.LazyControllingMacro.getID());
20332033
else
2034-
LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro));
2034+
LE.write<IdentifierID>(
2035+
Writer.getIdentifierRef(Data.HFI.LazyControllingMacro.getPtr()));
20352036

20362037
unsigned Offset = 0;
20372038
if (!Data.HFI.Framework.empty()) {

0 commit comments

Comments
 (0)