Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clang/include/clang/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// LastFileIDLookup records the last FileID looked up or created, because it
/// is very common to look up many tokens from the same file.
mutable FileID LastFileIDLookup;
mutable SourceLocation::UIntTy LastLookupStartOffset;
mutable SourceLocation::UIntTy LastLookupEndOffset; // exclude

/// Holds information for \#line directives.
///
Expand Down Expand Up @@ -1903,7 +1905,6 @@ class SourceManager : public RefCountedBase<SourceManager> {
// If our one-entry cache covers this offset, just return it.
if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
return LastFileIDLookup;

return getFileIDSlow(SLocOffset);
}

Expand All @@ -1926,6 +1927,10 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// specified SourceLocation offset. This is a very hot method.
inline bool isOffsetInFileID(FileID FID,
SourceLocation::UIntTy SLocOffset) const {
if (FID == LastFileIDLookup)
return SLocOffset >= LastLookupStartOffset &&
SLocOffset < LastLookupEndOffset;

const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
// If the entry is after the offset, it can't contain it.
if (SLocOffset < Entry.getOffset()) return false;
Expand Down
27 changes: 18 additions & 9 deletions clang/lib/Basic/SourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ void SourceManager::clearIDTables() {
LastLineNoFileIDQuery = FileID();
LastLineNoContentCache = nullptr;
LastFileIDLookup = FileID();
LastLookupStartOffset = LastLookupEndOffset = 0;

IncludedLocMap.clear();
if (LineTable)
Expand Down Expand Up @@ -639,9 +640,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
Expand Down Expand Up @@ -811,8 +814,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
Expand All @@ -832,13 +836,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;
Expand All @@ -849,7 +851,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)
Expand All @@ -873,6 +880,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);
}

Expand Down