versioner: use a virtual filesystem for input files.
Use an InMemoryFileSystem to store and share input files across
compilations.
This improves the result of `time versioner` further, from:
versioner 109.12s user 17.43s system 2433% cpu 5.201 total
to:
versioner 112.20s user 1.38s system 2416% cpu 4.700 total
Bug: http://b/32748936
Test: python run_tests.py
Change-Id: I72d37b7c30850b8399cc40338247700fe3e7b2f9
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index dad8a1e..215dc3c 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -29,6 +29,7 @@
#include <clang/AST/ASTConsumer.h>
#include <clang/Basic/Diagnostic.h>
#include <clang/Basic/TargetInfo.h>
+#include <clang/Basic/VirtualFileSystem.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Frontend/CompilerInstance.h>
@@ -92,7 +93,8 @@
// Run it once to generate flags for each target, and memoize the results.
static std::unordered_map<CompilationType, std::vector<std::string>> cc1_flags;
static const char* filename_placeholder = "__VERSIONER_PLACEHOLDER__";
-static void generateTargetCC1Flags(CompilationType type,
+static void generateTargetCC1Flags(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
+ CompilationType type,
const std::vector<std::string>& include_dirs) {
std::vector<std::string> cmd = { "versioner" };
cmd.push_back("-std=c11");
@@ -122,12 +124,8 @@
cmd.push_back("-nostdinc");
if (add_include) {
- const char* top = getenv("ANDROID_BUILD_TOP");
- if (!top) {
- errx(1, "-i passed, but ANDROID_BUILD_TOP is unset");
- }
cmd.push_back("-include");
- cmd.push_back(to_string(top) + "/bionic/libc/include/android/versioning.h");
+ cmd.push_back("android/versioning.h");
}
for (const auto& dir : include_dirs) {
@@ -138,7 +136,7 @@
cmd.push_back(filename_placeholder);
auto diags = constructDiags();
- driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags);
+ driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, vfs);
driver.setCheckInputsExist(false);
llvm::SmallVector<const char*, 32> driver_args;
@@ -192,7 +190,8 @@
return result;
}
-void initializeTargetCC1FlagCache(const std::set<CompilationType>& types,
+void initializeTargetCC1FlagCache(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
+ const std::set<CompilationType>& types,
const std::unordered_map<Arch, CompilationRequirements>& reqs) {
if (!cc1_flags.empty()) {
errx(1, "reinitializing target CC1 flag cache?");
@@ -201,14 +200,14 @@
auto start = std::chrono::high_resolution_clock::now();
std::vector<std::thread> threads;
for (const CompilationType type : types) {
- threads.emplace_back([type, &reqs]() {
+ threads.emplace_back([type, &vfs, &reqs]() {
const auto& arch_req_it = reqs.find(type.arch);
if (arch_req_it == reqs.end()) {
errx(1, "CompilationRequirement map missing entry for CompilationType %s",
to_string(type).c_str());
}
- generateTargetCC1Flags(type, arch_req_it->second.dependencies);
+ generateTargetCC1Flags(vfs, type, arch_req_it->second.dependencies);
});
}
for (auto& thread : threads) {
@@ -226,7 +225,8 @@
}
}
-void compileHeader(HeaderDatabase* header_database, CompilationType type,
+void compileHeader(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
+ HeaderDatabase* header_database, CompilationType type,
const std::string& filename) {
auto diags = constructDiags();
std::vector<const char*> cc1_flags = getCC1Command(type, filename);
@@ -239,6 +239,7 @@
clang::CompilerInstance Compiler;
Compiler.setInvocation(invocation.release());
Compiler.setDiagnostics(diags.get());
+ Compiler.setVirtualFileSystem(vfs);
VersionerASTAction versioner_action(header_database, type);
if (!Compiler.ExecuteAction(versioner_action)) {