diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2025-07-07 09:42:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-07 09:42:38 +0200 |
commit | 784bd61fc497b11a6d8d30abb6157c8a3597ffbf (patch) | |
tree | 5a9b18dc444da797b5c3e2a930efe1c1126ceb24 /clang/lib/Basic/SourceManager.cpp | |
parent | b7d4735a0e2a65c27aa74a56e19020a34de790fe (diff) | |
download | llvm-784bd61fc497b11a6d8d30abb6157c8a3597ffbf.zip llvm-784bd61fc497b11a6d8d30abb6157c8a3597ffbf.tar.gz llvm-784bd61fc497b11a6d8d30abb6157c8a3597ffbf.tar.bz2 |
[clang] Speedup getFileIDLocal with a separate offset table. (#146604)
The `SLocEntry` structure is 24 bytes, and the binary search only needs
the offset. Loading an entry's offset might pull the entire SLocEntry
object into the CPU cache.
To make the binary search much more cache-efficient, we use a separate
offset table.
See
https://llvm-compile-time-tracker.com/compare.php?from=650d0151c623c123e4e9736fe50421624a329260&to=6af564c0d75aff28a2784a8554448c0679877792&stat=instructions:u.
Diffstat (limited to 'clang/lib/Basic/SourceManager.cpp')
-rw-r--r-- | clang/lib/Basic/SourceManager.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 7d1b23b..79a0d9d 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -329,6 +329,7 @@ SourceManager::~SourceManager() { void SourceManager::clearIDTables() { MainFileID = FileID(); LocalSLocEntryTable.clear(); + LocalLocOffsetTable.clear(); LoadedSLocEntryTable.clear(); SLocEntryLoaded.clear(); SLocEntryOffsetLoaded.clear(); @@ -628,9 +629,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, noteSLocAddressSpaceUsage(Diag); return FileID(); } + assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size()); LocalSLocEntryTable.push_back( SLocEntry::get(NextLocalOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename))); + LocalLocOffsetTable.push_back(NextLocalOffset); LastLookupStartOffset = NextLocalOffset; // We do a +1 here because we want a SourceLocation that means "the end of the // file", e.g. for the "no newline at the end of the file" diagnostic. @@ -684,7 +687,9 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info, SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true; return SourceLocation::getMacroLoc(LoadedOffset); } + assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size()); LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info)); + LocalLocOffsetTable.push_back(NextLocalOffset); if (NextLocalOffset + Length + 1 <= NextLocalOffset || NextLocalOffset + Length + 1 > CurrentLoadedOffset) { Diag.Report(diag::err_sloc_space_too_large); @@ -807,6 +812,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { assert(SLocOffset < NextLocalOffset && "Bad function choice"); assert(SLocOffset >= LocalSLocEntryTable[0].getOffset() && SLocOffset > 0 && "Invalid SLocOffset"); + assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size()); assert(LastFileIDLookup.ID >= 0 && "Only cache local file sloc entry"); // After the first and second level caches, I see two common sorts of @@ -837,8 +843,8 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { unsigned NumProbes = 0; while (true) { --GreaterIndex; - assert(GreaterIndex < LocalSLocEntryTable.size()); - if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) { + assert(GreaterIndex < LocalLocOffsetTable.size()); + if (LocalLocOffsetTable[GreaterIndex] <= SLocOffset) { FileID Res = FileID::get(int(GreaterIndex)); // Remember it. We have good locality across FileID lookups. LastFileIDLookup = Res; @@ -858,11 +864,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { ++NumBinaryProbes; unsigned MiddleIndex = LessIndex + (GreaterIndex - LessIndex) / 2; - - SourceLocation::UIntTy MidOffset = - LocalSLocEntryTable[MiddleIndex].getOffset(); - - if (MidOffset <= SLocOffset) + if (LocalLocOffsetTable[MiddleIndex] <= SLocOffset) LessIndex = MiddleIndex + 1; else GreaterIndex = MiddleIndex; |