summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/DependencyScanning
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2019-09-11 20:40:31 +0000
committerAlex Lorenz <arphaman@gmail.com>2019-09-11 20:40:31 +0000
commitca6e60971e9578acb0561df7797283474291f9d9 (patch)
tree7befe213930939771810d9aa830ce7323c119389 /clang/lib/Tooling/DependencyScanning
parent2f843616849963e8df7a561ce5179ed29a767057 (diff)
downloadbcm5719-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')
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp32
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp6
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp23
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);
});
}
OpenPOWER on IntegriCloud