From c8d06a93f2545f7aa4ff6afe2c25e4a1b7319a79 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 9 Jun 2017 08:29:58 +0000 Subject: [PATCH] Speed up preamble loading Cache filename - SourceLocation pairs to speed up preamble loading and global completion. This is especially relevant for windows, where preamble loading takes a while. Patch by Ivan Donchevskii! Differential Revision: http://reviews.llvm.org/D33493 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305061 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/ASTUnit.h | 8 ++++++++ lib/Frontend/ASTUnit.cpp | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 259946b342..234fd837cd 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -188,6 +188,14 @@ private: /// some number of calls. unsigned PreambleRebuildCounter; + /// \brief Cache pairs "filename - source location" + /// + /// Cache contains only source locations from preamble so it is + /// guaranteed that they stay valid when the SourceManager is recreated. + /// This cache is used when loading preambule to increase performance + /// of that loading. It must be cleared when preamble is recreated. + llvm::StringMap PreambleSrcLocCache; + public: class PreambleData { const FileEntry *File; diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index bf856f0146..0137d2c812 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -1159,6 +1159,8 @@ bool ASTUnit::Parse(std::shared_ptr PCHContainerOps, if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); + else + PreambleSrcLocCache.clear(); if (!Act->Execute()) goto error; @@ -2602,11 +2604,9 @@ void ASTUnit::TranslateStoredDiagnostics( // remap all the locations to the new view. This includes the diag location, // any associated source ranges, and the source ranges of associated fix-its. // FIXME: There should be a cleaner way to do this. - SmallVector Result; Result.reserve(Diags.size()); - const FileEntry *PreviousFE = nullptr; - FileID FID; + for (const StandaloneDiagnostic &SD : Diags) { // Rebuild the StoredDiagnostic. if (SD.Filename.empty()) @@ -2614,11 +2614,16 @@ void ASTUnit::TranslateStoredDiagnostics( const FileEntry *FE = FileMgr.getFile(SD.Filename); if (!FE) continue; - if (FE != PreviousFE) { - FID = SrcMgr.translateFile(FE); - PreviousFE = FE; + SourceLocation FileLoc; + auto ItFileID = PreambleSrcLocCache.find(SD.Filename); + if (ItFileID == PreambleSrcLocCache.end()) { + FileID FID = SrcMgr.translateFile(FE); + FileLoc = SrcMgr.getLocForStartOfFile(FID); + PreambleSrcLocCache[SD.Filename] = FileLoc; + } else { + FileLoc = ItFileID->getValue(); } - SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID); + if (FileLoc.isInvalid()) continue; SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset); -- 2.40.0