dexonsmith updated this revision to Diff 300722.
dexonsmith edited the summary of this revision.
dexonsmith added a comment.

Made the planned changes to SourceManager, wrapping the index in 
`LoadedSLocEntryIndex` which acts like an `Optional<unsigned>` (but still using 
0 for a sentinel to allow zero-initialization).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89749/new/

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
@@ -331,7 +331,7 @@
   MainFileID = FileID();
   LocalSLocEntryTable.clear();
   LoadedSLocEntryTable.clear();
-  SLocEntryLoaded.clear();
+  SLocEntryIndices.clear();
   LastLineNoFileIDQuery = FileID();
   LastLineNoContentCache = nullptr;
   LastFileIDLookup = FileID();
@@ -367,8 +367,8 @@
   };
 
   // Ensure all SLocEntries are loaded from the external source.
-  for (unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
-    if (!Old.SLocEntryLoaded[I])
+  for (unsigned I = 0, N = Old.SLocEntryIndices.size(); I != N; ++I)
+    if (!Old.SLocEntryIndices[I])
       Old.loadSLocEntry(I, nullptr);
 
   // Inherit any content cache data from the old source manager.
@@ -429,12 +429,12 @@
 
 const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
                                                       bool *Invalid) const {
-  assert(!SLocEntryLoaded[Index]);
+  assert(!SLocEntryIndices[Index]);
   if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
     if (Invalid)
       *Invalid = true;
     // If the file of the SLocEntry changed we could still have loaded it.
-    if (!SLocEntryLoaded[Index]) {
+    if (!SLocEntryIndices[Index]) {
       // Try to recover; create a SLocEntry so the rest of clang can handle it.
       if (!FakeSLocEntryForRecovery)
         FakeSLocEntryForRecovery = std::make_unique<SLocEntry>(
@@ -445,7 +445,8 @@
     }
   }
 
-  return LoadedSLocEntryTable[Index];
+  assert(SLocEntryIndices[Index] && "Failed to load but returned success");
+  return LoadedSLocEntryTable[*SLocEntryIndices[Index]];
 }
 
 std::pair<int, unsigned>
@@ -455,10 +456,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());
+  SLocEntryIndices.resize(SLocEntryIndices.size() + NumSLocEntries);
   CurrentLoadedOffset -= TotalSize;
-  int ID = LoadedSLocEntryTable.size();
+  int ID = SLocEntryIndices.size();
   return std::make_pair(-ID - 1, CurrentLoadedOffset);
 }
 
@@ -497,7 +497,7 @@
   if (ID > 0) {
     if (ID-1 == 0)
       return FileID();
-  } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
+  } else if (unsigned(-(ID - 1) - 2) >= SLocEntryIndices.size()) {
     return FileID();
   }
 
@@ -598,11 +598,12 @@
   if (LoadedID < 0) {
     assert(LoadedID != -1 && "Loading sentinel FileID");
     unsigned Index = unsigned(-LoadedID) - 2;
-    assert(Index < LoadedSLocEntryTable.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;
+    assert(Index < SLocEntryIndices.size() && "FileID out of range");
+    assert(!SLocEntryIndices[Index] && "FileID already loaded");
+    SLocEntryIndices[Index] = LoadedSLocEntryTable.size();
+    LoadedSLocEntryTable.push_back(
+        SLocEntry::get(LoadedOffset, FileInfo::get(IncludePos, File,
+                                                   FileCharacter, Filename)));
     return FileID::get(LoadedID);
   }
   unsigned FileSize = File.getSize();
@@ -664,10 +665,10 @@
   if (LoadedID < 0) {
     assert(LoadedID != -1 && "Loading sentinel FileID");
     unsigned Index = unsigned(-LoadedID) - 2;
-    assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
-    assert(!SLocEntryLoaded[Index] && "FileID already loaded");
-    LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
-    SLocEntryLoaded[Index] = true;
+    assert(Index < SLocEntryIndices.size() && "FileID out of range");
+    assert(!SLocEntryIndices[Index] && "FileID already loaded");
+    SLocEntryIndices[Index] = LoadedSLocEntryTable.size();
+    LoadedSLocEntryTable.push_back(SLocEntry::get(LoadedOffset, Info));
     return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
@@ -899,7 +900,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 = SLocEntryIndices.size();
   NumProbes = 0;
   while (true) {
     ++NumProbes;
@@ -2090,8 +2091,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() << SLocEntryIndices.size() << " loaded SLocEntries ("
+               << LoadedSLocEntryTable.size() << " allocated), "
                << MaxLoadedOffset - CurrentLoadedOffset
                << "B of Sloc address space used.\n";
 
@@ -2155,11 +2156,11 @@
   }
   // Dump loaded SLocEntries.
   llvm::Optional<unsigned> NextStart;
-  for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
+  for (unsigned Index = 0; Index != SLocEntryIndices.size(); ++Index) {
     int ID = -(int)Index - 2;
-    if (SLocEntryLoaded[Index]) {
-      DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
-      NextStart = LoadedSLocEntryTable[Index].getOffset();
+    if (auto I = SLocEntryIndices[Index]) {
+      DumpSLocEntry(ID, LoadedSLocEntryTable[*I], NextStart);
+      NextStart = LoadedSLocEntryTable[*I].getOffset();
     } else {
       NextStart = None;
     }
@@ -2192,7 +2193,7 @@
   size_t size = llvm::capacity_in_bytes(MemBufferInfos)
     + llvm::capacity_in_bytes(LocalSLocEntryTable)
     + llvm::capacity_in_bytes(LoadedSLocEntryTable)
-    + llvm::capacity_in_bytes(SLocEntryLoaded)
+    + llvm::capacity_in_bytes(SLocEntryIndices)
     + llvm::capacity_in_bytes(FileInfos);
 
   if (OverriddenFilesInfo)
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -69,6 +69,33 @@
 /// SourceManager implementation.
 namespace SrcMgr {
 
+  /// Optional index for loadable SLoc entries. Semantics of Optional<unsigned>
+  /// but without storage overhead.
+  class LoadedSLocEntryIndex {
+  public:
+    explicit operator bool() const { return Data; }
+    unsigned operator*() const {
+      assert(*this && "Dereferencing None?");
+      return Data - 1;
+    }
+
+    LoadedSLocEntryIndex &operator=(llvm::NoneType) {
+      return *this = LoadedSLocEntryIndex(None);
+    }
+    LoadedSLocEntryIndex &operator=(unsigned I) {
+      return *this = LoadedSLocEntryIndex(I);
+    }
+    LoadedSLocEntryIndex(llvm::NoneType = None) : Data(0) {}
+    LoadedSLocEntryIndex(unsigned I) : Data(I + 1) {
+      assert(*this && "Index too big");
+    }
+
+  private:
+    /// Index stored off-by-one with 0 as a sentinel to enable
+    /// zero-initialization.
+    unsigned Data;
+  };
+
   /// Indicates whether a file or directory holds normal user code,
   /// system code, or system code which is implicitly 'extern "C"' in C++ mode.
   ///
@@ -677,8 +704,8 @@
 
   /// 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 LoadedSLocEntryIndices, which contains the
+  /// index into this table.
   SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
 
   /// The starting offset of the next local SLocEntry.
@@ -688,19 +715,20 @@
 
   /// 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[SLocEntryIndices.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 optional index into LoadedSLocEntryTable, where None indicates that an
+  /// SLocEntry has not yet been allocated.
   ///
-  /// 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<SrcMgr::LoadedSLocEntryIndex, 0> SLocEntryIndices;
 
   /// An external source for source location entries.
   ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
@@ -1659,14 +1687,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 SLocEntryIndices.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 < SLocEntryIndices.size() && "Invalid index");
+    if (auto I = SLocEntryIndices[Index])
+      return LoadedSLocEntryTable[*I];
     return loadSLocEntry(Index, Invalid);
   }
 
@@ -1682,8 +1710,7 @@
   unsigned getNextLocalOffset() const { return NextLocalOffset; }
 
   void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
-    assert(LoadedSLocEntryTable.empty() &&
-           "Invalidating existing loaded entries");
+    assert(SLocEntryIndices.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