diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2025-07-04 22:11:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-04 22:11:59 +0200 |
commit | e2510b189dae1a18c1e84ea69c99ff417950e03a (patch) | |
tree | 3a81b6b58ad7ab6525e6d33d5604816955e7d49f /clang/lib/Basic/SourceManager.cpp | |
parent | 372752c2ddd0919a305d6019e30077829dea2858 (diff) | |
download | llvm-e2510b189dae1a18c1e84ea69c99ff417950e03a.zip llvm-e2510b189dae1a18c1e84ea69c99ff417950e03a.tar.gz llvm-e2510b189dae1a18c1e84ea69c99ff417950e03a.tar.bz2 |
[clang] SourceManager: Cache offsets for LastFileIDLookup to speed up getFileID (#146782)
`getFileID` is a hot method. By caching the offset range in
`LastFileIDLookup`, we can more quickly check whether a given offset
falls within it, avoiding calling `isOffsetInFileID`.
https://llvm-compile-time-tracker.com/compare.php?from=0588e8188c647460b641b09467fe6b13a8d510d5&to=64843a500f0191b79a8109da9acd7e80d961c7a3&stat=instructions:u
Diffstat (limited to 'clang/lib/Basic/SourceManager.cpp')
-rw-r--r-- | clang/lib/Basic/SourceManager.cpp | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 1b4be14..7d1b23b 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -335,6 +335,7 @@ void SourceManager::clearIDTables() { LastLineNoFileIDQuery = FileID(); LastLineNoContentCache = nullptr; LastFileIDLookup = FileID(); + LastLookupStartOffset = LastLookupEndOffset = 0; IncludedLocMap.clear(); if (LineTable) @@ -630,9 +631,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, LocalSLocEntryTable.push_back( SLocEntry::get(NextLocalOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename))); + 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. NextLocalOffset += FileSize + 1; + LastLookupEndOffset = NextLocalOffset; updateSlocUsageStats(); // Set LastFileIDLookup to the newly created file. The next getFileID call is @@ -802,8 +805,9 @@ FileID SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset) const { /// loaded one. FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { assert(SLocOffset < NextLocalOffset && "Bad function choice"); - assert(SLocOffset >= LocalSLocEntryTable[0].getOffset() && + assert(SLocOffset >= LocalSLocEntryTable[0].getOffset() && SLocOffset > 0 && "Invalid SLocOffset"); + assert(LastFileIDLookup.ID >= 0 && "Only cache local file sloc entry"); // After the first and second level caches, I see two common sorts of // behavior: 1) a lot of searched FileID's are "near" the cached file @@ -823,13 +827,11 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { unsigned LessIndex = 0; // upper bound of the search range. unsigned GreaterIndex = LocalSLocEntryTable.size(); - if (LastFileIDLookup.ID >= 0) { - // Use the LastFileIDLookup to prune the search space. - if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) - LessIndex = LastFileIDLookup.ID; - else - GreaterIndex = LastFileIDLookup.ID; - } + // Use the LastFileIDLookup to prune the search space. + if (LastLookupStartOffset < SLocOffset) + LessIndex = LastFileIDLookup.ID; + else + GreaterIndex = LastFileIDLookup.ID; // Find the FileID that contains this. unsigned NumProbes = 0; @@ -840,7 +842,12 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { FileID Res = FileID::get(int(GreaterIndex)); // Remember it. We have good locality across FileID lookups. LastFileIDLookup = Res; - NumLinearScans += NumProbes+1; + LastLookupStartOffset = LocalSLocEntryTable[GreaterIndex].getOffset(); + LastLookupEndOffset = + GreaterIndex + 1 >= LocalSLocEntryTable.size() + ? NextLocalOffset + : LocalSLocEntryTable[GreaterIndex + 1].getOffset(); + NumLinearScans += NumProbes + 1; return Res; } if (++NumProbes == 8) @@ -864,6 +871,8 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { // At this point, LessIndex is the index of the *first element greater than* // SLocOffset. The element we are actually looking for is the one immediately // before it. + LastLookupStartOffset = LocalSLocEntryTable[LessIndex - 1].getOffset(); + LastLookupEndOffset = LocalSLocEntryTable[LessIndex].getOffset(); return LastFileIDLookup = FileID::get(LessIndex - 1); } |