Skip to content

Commit 6af564c

Browse files
committed
[SourceManager] Speedup getFileIDLocal with a separate Offset Table.
More cache friendly.
1 parent 650d015 commit 6af564c

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

clang/include/clang/Basic/SourceManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
719719
/// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
720720
/// expansion.
721721
SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
722+
/// An in-parallel offset table, merely used for speeding up FileID lookup.
723+
SmallVector<SourceLocation::UIntTy> LocalLocOffsetTable;
722724

723725
/// The table of SLocEntries that are loaded from other modules.
724726
///

clang/lib/Basic/SourceManager.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ SourceManager::~SourceManager() {
328328
void SourceManager::clearIDTables() {
329329
MainFileID = FileID();
330330
LocalSLocEntryTable.clear();
331+
LocalLocOffsetTable.clear();
331332
LoadedSLocEntryTable.clear();
332333
SLocEntryLoaded.clear();
333334
SLocEntryOffsetLoaded.clear();
@@ -636,9 +637,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
636637
noteSLocAddressSpaceUsage(Diag);
637638
return FileID();
638639
}
640+
assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
639641
LocalSLocEntryTable.push_back(
640642
SLocEntry::get(NextLocalOffset,
641643
FileInfo::get(IncludePos, File, FileCharacter, Filename)));
644+
LocalLocOffsetTable.push_back(NextLocalOffset);
642645
// We do a +1 here because we want a SourceLocation that means "the end of the
643646
// file", e.g. for the "no newline at the end of the file" diagnostic.
644647
NextLocalOffset += FileSize + 1;
@@ -690,7 +693,9 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
690693
SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
691694
return SourceLocation::getMacroLoc(LoadedOffset);
692695
}
696+
assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
693697
LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
698+
LocalLocOffsetTable.push_back(NextLocalOffset);
694699
if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
695700
NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
696701
Diag.Report(diag::err_sloc_space_too_large);
@@ -813,7 +818,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
813818
assert(SLocOffset < NextLocalOffset && "Bad function choice");
814819
assert(SLocOffset >= LocalSLocEntryTable[0].getOffset() &&
815820
"Invalid SLocOffset");
816-
821+
assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
817822
// After the first and second level caches, I see two common sorts of
818823
// behavior: 1) a lot of searched FileID's are "near" the cached file
819824
// location or are "near" the cached expansion location. 2) others are just
@@ -831,10 +836,10 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
831836
// SLocOffset.
832837
unsigned LessIndex = 0;
833838
// upper bound of the search range.
834-
unsigned GreaterIndex = LocalSLocEntryTable.size();
839+
unsigned GreaterIndex = LocalLocOffsetTable.size();
835840
if (LastFileIDLookup.ID >= 0) {
836841
// Use the LastFileIDLookup to prune the search space.
837-
if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset)
842+
if (LocalLocOffsetTable[LastFileIDLookup.ID] < SLocOffset)
838843
LessIndex = LastFileIDLookup.ID;
839844
else
840845
GreaterIndex = LastFileIDLookup.ID;
@@ -844,8 +849,8 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
844849
unsigned NumProbes = 0;
845850
while (true) {
846851
--GreaterIndex;
847-
assert(GreaterIndex < LocalSLocEntryTable.size());
848-
if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) {
852+
assert(GreaterIndex < LocalLocOffsetTable.size());
853+
if (LocalLocOffsetTable[GreaterIndex] <= SLocOffset) {
849854
FileID Res = FileID::get(int(GreaterIndex));
850855
// Remember it. We have good locality across FileID lookups.
851856
LastFileIDLookup = Res;
@@ -860,11 +865,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
860865
++NumBinaryProbes;
861866

862867
unsigned MiddleIndex = LessIndex + (GreaterIndex - LessIndex) / 2;
863-
864-
SourceLocation::UIntTy MidOffset =
865-
LocalSLocEntryTable[MiddleIndex].getOffset();
866-
867-
if (MidOffset <= SLocOffset)
868+
if (LocalLocOffsetTable[MiddleIndex] <= SLocOffset)
868869
LessIndex = MiddleIndex + 1;
869870
else
870871
GreaterIndex = MiddleIndex;

0 commit comments

Comments
 (0)