diff options
author | Alex Lorenz <arphaman@gmail.com> | 2019-09-11 20:40:31 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2019-09-11 20:40:31 +0000 |
commit | ca6e60971e9578acb0561df7797283474291f9d9 (patch) | |
tree | 7befe213930939771810d9aa830ce7323c119389 /clang/lib/Tooling/DependencyScanning | |
parent | 2f843616849963e8df7a561ce5179ed29a767057 (diff) | |
download | bcm5719-llvm-ca6e60971e9578acb0561df7797283474291f9d9.tar.gz bcm5719-llvm-ca6e60971e9578acb0561df7797283474291f9d9.zip |
[clang-scan-deps] add skip excluded conditional preprocessor block preprocessing optimization
This commit adds an optimization to clang-scan-deps and clang's preprocessor that skips excluded preprocessor
blocks by bumping the lexer pointer, and not lexing the tokens until reaching appropriate #else/#endif directive.
The skip positions and lexer offsets are computed when the file is minimized, directly from the minimized tokens.
On an 18-core iMacPro with macOS Catalina Beta I got 10-15% speed-up from this optimization when running clang-scan-deps on
the compilation database for a recent LLVM and Clang (3511 files).
Differential Revision: https://reviews.llvm.org/D67127
llvm-svn: 371656
Diffstat (limited to 'clang/lib/Tooling/DependencyScanning')
3 files changed, 50 insertions, 11 deletions
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 487d2c35c25..12e8df6360c 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -69,6 +69,25 @@ CachedFileSystemEntry CachedFileSystemEntry::createFileEntry( // Now make the null terminator implicit again, so that Clang's lexer can find // it right where the buffer ends. Result.Contents.pop_back(); + + // Compute the skipped PP ranges that speedup skipping over inactive + // preprocessor blocks. + llvm::SmallVector<minimize_source_to_dependency_directives::SkippedRange, 32> + SkippedRanges; + minimize_source_to_dependency_directives::computeSkippedRanges(Tokens, + SkippedRanges); + PreprocessorSkippedRangeMapping Mapping; + for (const auto &Range : SkippedRanges) { + if (Range.Length < 16) { + // Ignore small ranges as non-profitable. + // FIXME: This is a heuristic, its worth investigating the tradeoffs + // when it should be applied. + continue; + } + Mapping[Range.Offset] = Range.Length; + } + Result.PPSkippedRangeMapping = std::move(Mapping); + return Result; } @@ -172,14 +191,19 @@ private: }; llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> -createFile(const CachedFileSystemEntry *Entry) { +createFile(const CachedFileSystemEntry *Entry, + ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings) { llvm::ErrorOr<StringRef> Contents = Entry->getContents(); if (!Contents) return Contents.getError(); - return std::make_unique<MinimizedVFSFile>( + auto Result = std::make_unique<MinimizedVFSFile>( llvm::MemoryBuffer::getMemBuffer(*Contents, Entry->getName(), /*RequiresNullTerminator=*/false), *Entry->getStatus()); + if (!Entry->getPPSkippedRangeMapping().empty() && PPSkipMappings) + (*PPSkipMappings)[Result->getBufferPtr()] = + &Entry->getPPSkippedRangeMapping(); + return Result; } } // end anonymous namespace @@ -191,7 +215,7 @@ DependencyScanningWorkerFilesystem::openFileForRead(const Twine &Path) { // Check the local cache first. if (const CachedFileSystemEntry *Entry = getCachedEntry(Filename)) - return createFile(Entry); + return createFile(Entry, PPSkipMappings); // FIXME: Handle PCM/PCH files. // FIXME: Handle module map files. @@ -214,5 +238,5 @@ DependencyScanningWorkerFilesystem::openFileForRead(const Twine &Path) { // Store the result in the local cache. setCachedEntry(Filename, Result); - return createFile(Result); + return createFile(Result, PPSkipMappings); } diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp index 6ddce0dcee8..e5cebe38100 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp @@ -13,5 +13,7 @@ using namespace tooling; using namespace dependencies; DependencyScanningService::DependencyScanningService(ScanningMode Mode, - bool ReuseFileManager) - : Mode(Mode), ReuseFileManager(ReuseFileManager) {} + bool ReuseFileManager, + bool SkipExcludedPPRanges) + : Mode(Mode), ReuseFileManager(ReuseFileManager), + SkipExcludedPPRanges(SkipExcludedPPRanges) {} diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 827ec8a6ca8..f6096078d15 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -12,6 +12,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/Tooling.h" @@ -66,9 +67,10 @@ class DependencyScanningAction : public tooling::ToolAction { public: DependencyScanningAction( StringRef WorkingDirectory, DependencyConsumer &Consumer, - llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS) + llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS, + ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings) : WorkingDirectory(WorkingDirectory), Consumer(Consumer), - DepFS(std::move(DepFS)) {} + DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings) {} bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation, FileManager *FileMgr, @@ -101,6 +103,12 @@ public: // filesystem. FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation( CI, Compiler.getDiagnostics(), DepFS)); + + // Pass the skip mappings which should speed up excluded conditional block + // skipping in the preprocessor. + if (PPSkipMappings) + Compiler.getPreprocessorOpts() + .ExcludedConditionalDirectiveSkipMappings = PPSkipMappings; } FileMgr->getFileSystemOpts().WorkingDir = WorkingDirectory; @@ -134,6 +142,7 @@ private: StringRef WorkingDirectory; DependencyConsumer &Consumer; llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; + ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings; }; } // end anonymous namespace @@ -143,9 +152,12 @@ DependencyScanningWorker::DependencyScanningWorker( DiagOpts = new DiagnosticOptions(); PCHContainerOps = std::make_shared<PCHContainerOperations>(); RealFS = new ProxyFileSystemWithoutChdir(llvm::vfs::getRealFileSystem()); + if (Service.canSkipExcludedPPRanges()) + PPSkipMappings = + std::make_unique<ExcludedPreprocessorDirectiveSkipMapping>(); if (Service.getMode() == ScanningMode::MinimizedSourcePreprocessing) - DepFS = new DependencyScanningWorkerFilesystem(Service.getSharedCache(), - RealFS); + DepFS = new DependencyScanningWorkerFilesystem( + Service.getSharedCache(), RealFS, PPSkipMappings.get()); if (Service.canReuseFileManager()) Files = new FileManager(FileSystemOptions(), RealFS); } @@ -178,7 +190,8 @@ llvm::Error DependencyScanningWorker::computeDependencies( Tool.setRestoreWorkingDir(false); Tool.setPrintErrorMessage(false); Tool.setDiagnosticConsumer(&DC); - DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS); + DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS, + PPSkipMappings.get()); return !Tool.run(&Action); }); } |