[clang] Improve getFileIDLocal binary search. (#146510)

Avoid reading the `LocalSLocEntryTable` twice per loop iteration. NFC.

https://llvm-compile-time-tracker.com/compare.php?from=0b6ddb02efdcbdac9426e8d857499ea0580303cd&to=1aa335ccfb07ba96177b89b1933aa6b980fa14f6&stat=instructions:u
This commit is contained in:
Haojian Wu
2025-07-01 21:59:09 +02:00
committed by GitHub
parent 777d6b5de9
commit 650d0151c6

View File

@@ -811,6 +811,8 @@ 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() &&
"Invalid SLocOffset");
// 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
@@ -854,35 +856,24 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
break;
}
NumProbes = 0;
while (true) {
unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
while (LessIndex < GreaterIndex) {
++NumBinaryProbes;
unsigned MiddleIndex = LessIndex + (GreaterIndex - LessIndex) / 2;
SourceLocation::UIntTy MidOffset =
getLocalSLocEntry(MiddleIndex).getOffset();
LocalSLocEntryTable[MiddleIndex].getOffset();
++NumProbes;
// If the offset of the midpoint is too large, chop the high side of the
// range to the midpoint.
if (MidOffset > SLocOffset) {
if (MidOffset <= SLocOffset)
LessIndex = MiddleIndex + 1;
else
GreaterIndex = MiddleIndex;
continue;
}
// If the middle index contains the value, succeed and return.
if (MiddleIndex + 1 == LocalSLocEntryTable.size() ||
SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) {
FileID Res = FileID::get(MiddleIndex);
// Remember it. We have good locality across FileID lookups.
LastFileIDLookup = Res;
NumBinaryProbes += NumProbes;
return Res;
}
// Otherwise, move the low-side up to the middle index.
LessIndex = MiddleIndex;
}
// 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.
return LastFileIDLookup = FileID::get(LessIndex - 1);
}
/// Return the FileID for a SourceLocation with a high offset.