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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to