Skip to content

Commit 8267d57

Browse files
committed
[clang][Preprocessor] Replace the slow translateFile call by a new, faster isMainFile check
The commit 3c28a2d introduced the check that checks if we're trying to re-enter a main file when building a preamble. Unfortunately this slowed down the preamble compilation by 80-90% in some test cases, as translateFile is really slow. This change checks to see if the FileEntry is the main file without calling translateFile, but by using the new isMainFile check instead. This speeds up preamble building by 1.5-2x for certain test cases that we have. rdar://59361291 Differential Revision: https://reviews.llvm.org/D79834 (cherry picked from commit 11d612a)
1 parent bf6720f commit 8267d57

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

clang/include/clang/Basic/SourceManager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,11 @@ class SourceManager : public RefCountedBase<SourceManager> {
811811
MainFileID = FID;
812812
}
813813

814+
/// Returns true when the given FileEntry corresponds to the main file.
815+
///
816+
/// The main file should be set prior to calling this function.
817+
bool isMainFile(FileEntryRef SourceFile);
818+
814819
/// Set the file ID for the precompiled preamble.
815820
void setPreambleFileID(FileID Preamble) {
816821
assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");

clang/lib/Basic/SourceManager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ void SourceManager::clearIDTables() {
389389
createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1);
390390
}
391391

392+
bool SourceManager::isMainFile(FileEntryRef SourceFile) {
393+
assert(MainFileID.isValid() && "expected initialized SourceManager");
394+
auto FE = getFileEntryRefForID(MainFileID);
395+
if (!FE)
396+
return false;
397+
return FE->getUID() == SourceFile.getUID();
398+
}
399+
392400
void SourceManager::initializeForReplay(const SourceManager &Old) {
393401
assert(MainFileID.isInvalid() && "expected uninitialized SourceManager");
394402

clang/lib/Lex/PPDirectives.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,8 +1937,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
19371937
// some directives (e.g. #endif of a header guard) will never be seen.
19381938
// Since this will lead to confusing errors, avoid the inclusion.
19391939
if (File && PreambleConditionalStack.isRecording() &&
1940-
SourceMgr.translateFile(&File->getFileEntry()) ==
1941-
SourceMgr.getMainFileID()) {
1940+
SourceMgr.isMainFile(*File)) {
19421941
Diag(FilenameTok.getLocation(),
19431942
diag::err_pp_including_mainfile_in_preamble);
19441943
return {ImportAction::None};

clang/unittests/Basic/SourceManagerTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,30 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) {
485485
EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[10].Loc, Macros[11].Loc));
486486
}
487487

488+
TEST_F(SourceManagerTest, isMainFile) {
489+
const char *Source = "int x;";
490+
491+
std::unique_ptr<llvm::MemoryBuffer> Buf =
492+
llvm::MemoryBuffer::getMemBuffer(Source);
493+
const FileEntry *SourceFile =
494+
FileMgr.getVirtualFile("mainFile.cpp", Buf->getBufferSize(), 0);
495+
SourceMgr.overrideFileContents(SourceFile, std::move(Buf));
496+
497+
std::unique_ptr<llvm::MemoryBuffer> Buf2 =
498+
llvm::MemoryBuffer::getMemBuffer(Source);
499+
const FileEntry *SecondFile =
500+
FileMgr.getVirtualFile("file2.cpp", Buf2->getBufferSize(), 0);
501+
SourceMgr.overrideFileContents(SecondFile, std::move(Buf2));
502+
503+
FileID MainFileID = SourceMgr.getOrCreateFileID(SourceFile, SrcMgr::C_User);
504+
SourceMgr.setMainFileID(MainFileID);
505+
506+
EXPECT_TRUE(SourceMgr.isMainFile(FileEntryRef("mainFile.cpp", *SourceFile)));
507+
EXPECT_TRUE(
508+
SourceMgr.isMainFile(FileEntryRef("anotherName.cpp", *SourceFile)));
509+
EXPECT_FALSE(SourceMgr.isMainFile(FileEntryRef("mainFile.cpp", *SecondFile)));
510+
}
511+
488512
#endif
489513

490514
} // anonymous namespace

0 commit comments

Comments
 (0)