dexonsmith created this revision.
dexonsmith added reviewers: teemperor, Bigcheese.
Herald added a subscriber: ributzka.
dexonsmith requested review of this revision.
Convert `SLocEntryLoaded` into an index vector into
`LoadedSLocEntryTable`, where 0 indicates "not loaded", and change
`LoadedSLocEntryTable` to only include an `SLocEntry` if it has been
loaded. This makes the allocation for an unloaded `SLocEntry` 6x smaller
(24B => 4B), dramatically improving memory usage with large / many
modules.
This increases memory usage for a *loaded* `SLocEntry` slightly.
https://reviews.llvm.org/D89749
Files:
clang/include/clang/Basic/SourceManager.h
clang/lib/Basic/SourceManager.cpp
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -365,7 +365,7 @@
};
// Ensure all SLocEntries are loaded from the external source.
- for (unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
+ for (unsigned I = 0, N = Old.SLocEntryLoaded.size(); I != N; ++I)
if (!Old.SLocEntryLoaded[I])
Old.loadSLocEntry(I, nullptr);
@@ -443,7 +443,8 @@
}
}
- return LoadedSLocEntryTable[Index];
+ assert(SLocEntryLoaded[Index] && "Failed to load but returned success");
+ return LoadedSLocEntryTable[SLocEntryLoaded[Index] - 1];
}
std::pair<int, unsigned>
@@ -453,10 +454,9 @@
// Make sure we're not about to run out of source locations.
if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
return std::make_pair(0, 0);
- LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
- SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
+ SLocEntryLoaded.resize(SLocEntryLoaded.size() + NumSLocEntries);
CurrentLoadedOffset -= TotalSize;
- int ID = LoadedSLocEntryTable.size();
+ int ID = SLocEntryLoaded.size();
return std::make_pair(-ID - 1, CurrentLoadedOffset);
}
@@ -495,7 +495,7 @@
if (ID > 0) {
if (ID-1 == 0)
return FileID();
- } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
+ } else if (unsigned(-(ID - 1) - 2) >= SLocEntryLoaded.size()) {
return FileID();
}
@@ -596,11 +596,12 @@
if (LoadedID < 0) {
assert(LoadedID != -1 && "Loading sentinel FileID");
unsigned Index = unsigned(-LoadedID) - 2;
- assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
+ assert(Index < SLocEntryLoaded.size() && "FileID out of range");
assert(!SLocEntryLoaded[Index] && "FileID already loaded");
- LoadedSLocEntryTable[Index] = SLocEntry::get(
- LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename));
- SLocEntryLoaded[Index] = true;
+ LoadedSLocEntryTable.push_back(
+ SLocEntry::get(LoadedOffset, FileInfo::get(IncludePos, File,
+ FileCharacter, Filename)));
+ SLocEntryLoaded[Index] = LoadedSLocEntryTable.size();
return FileID::get(LoadedID);
}
unsigned FileSize = File.getSize();
@@ -662,10 +663,10 @@
if (LoadedID < 0) {
assert(LoadedID != -1 && "Loading sentinel FileID");
unsigned Index = unsigned(-LoadedID) - 2;
- assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
+ assert(Index < SLocEntryLoaded.size() && "FileID out of range");
assert(!SLocEntryLoaded[Index] && "FileID already loaded");
- LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
- SLocEntryLoaded[Index] = true;
+ LoadedSLocEntryTable.push_back(SLocEntry::get(LoadedOffset, Info));
+ SLocEntryLoaded[Index] = LoadedSLocEntryTable.size();
return SourceLocation::getMacroLoc(LoadedOffset);
}
LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
@@ -897,7 +898,7 @@
// table: GreaterIndex is the one where the offset is greater, which is
// actually a lower index!
unsigned GreaterIndex = I;
- unsigned LessIndex = LoadedSLocEntryTable.size();
+ unsigned LessIndex = SLocEntryLoaded.size();
NumProbes = 0;
while (true) {
++NumProbes;
@@ -2093,8 +2094,8 @@
<< llvm::capacity_in_bytes(LocalSLocEntryTable)
<< " bytes of capacity), "
<< NextLocalOffset << "B of Sloc address space used.\n";
- llvm::errs() << LoadedSLocEntryTable.size()
- << " loaded SLocEntries allocated, "
+ llvm::errs() << SLocEntryLoaded.size() << " loaded SLocEntries ("
+ << LoadedSLocEntryTable.size() << " allocated), "
<< MaxLoadedOffset - CurrentLoadedOffset
<< "B of Sloc address space used.\n";
@@ -2158,11 +2159,11 @@
}
// Dump loaded SLocEntries.
llvm::Optional<unsigned> NextStart;
- for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
+ for (unsigned Index = 0; Index != SLocEntryLoaded.size(); ++Index) {
int ID = -(int)Index - 2;
- if (SLocEntryLoaded[Index]) {
- DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
- NextStart = LoadedSLocEntryTable[Index].getOffset();
+ if (auto I = SLocEntryLoaded[Index]) {
+ DumpSLocEntry(ID, LoadedSLocEntryTable[I - 1], NextStart);
+ NextStart = LoadedSLocEntryTable[I - 1].getOffset();
} else {
NextStart = None;
}
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -669,30 +669,31 @@
/// The table of SLocEntries that are loaded from other modules.
///
- /// Negative FileIDs are indexes into this table. To get from ID to an index,
- /// use (-ID - 2).
+ /// Negative FileIDs are indexes into SLocEntryLoaded, which contains the
+ /// index into this table.
SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
/// The starting offset of the next local SLocEntry.
///
- /// This is LocalSLocEntryTable.back().Offset + the size of that entry.
+ /// This is SLocEntryLoaded.back().Offset + the size of that entry.
unsigned NextLocalOffset;
/// The starting offset of the latest batch of loaded SLocEntries.
///
- /// This is LoadedSLocEntryTable.back().Offset, except that that entry might
- /// not have been loaded, so that value would be unknown.
+ /// This is LoadedSLocEntryTable[SLocEntryLoaded.back()].Offset, except that
+ /// that entry might not have been loaded, so that value would be unknown.
unsigned CurrentLoadedOffset;
/// The highest possible offset is 2^31-1, so CurrentLoadedOffset
/// starts at 2^31.
static const unsigned MaxLoadedOffset = 1U << 31U;
- /// A bitmap that indicates whether the entries of LoadedSLocEntryTable
- /// have already been loaded from the external source.
+ /// An off-by-one index into LoadedSLocEntryTable, where a value of 0
+ /// indicates it hasn't been loaded.
///
- /// Same indexing as LoadedSLocEntryTable.
- llvm::BitVector SLocEntryLoaded;
+ /// Negative FileIDs are indexes into this table. To get from ID to an index,
+ /// use (-ID - 2).
+ SmallVector<unsigned, 0> SLocEntryLoaded;
/// An external source for source location entries.
ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
@@ -1651,14 +1652,14 @@
}
/// Get the number of loaded SLocEntries we have.
- unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
+ unsigned loaded_sloc_entry_size() const { return SLocEntryLoaded.size(); }
/// Get a loaded SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
bool *Invalid = nullptr) const {
- assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
- if (SLocEntryLoaded[Index])
- return LoadedSLocEntryTable[Index];
+ assert(Index < SLocEntryLoaded.size() && "Invalid index");
+ if (auto I = SLocEntryLoaded[Index])
+ return LoadedSLocEntryTable[I - 1];
return loadSLocEntry(Index, Invalid);
}
@@ -1674,8 +1675,7 @@
unsigned getNextLocalOffset() const { return NextLocalOffset; }
void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
- assert(LoadedSLocEntryTable.empty() &&
- "Invalidating existing loaded entries");
+ assert(SLocEntryLoaded.empty() && "Invalidating existing loaded entries");
ExternalSLocEntries = Source;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits