summaryrefslogtreecommitdiffstats
path: root/clang/tools/driver/driver.cpp
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2020-01-13 10:40:04 -0500
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2020-01-13 10:40:18 -0500
commitb4a99a061f517e60985667e39519f60186cbb469 (patch)
treee16cead143131c9185e51be2dac830f9df8a76e0 /clang/tools/driver/driver.cpp
parent043c5eafa8789d76b06b93d157c928830c4d0814 (diff)
downloadbcm5719-llvm-b4a99a061f517e60985667e39519f60186cbb469.tar.gz
bcm5719-llvm-b4a99a061f517e60985667e39519f60186cbb469.zip
[Clang][Driver] Re-use the calling process instead of creating a new process for the cc1 invocation
With this patch, the clang tool will now call the -cc1 invocation directly inside the same process. Previously, the -cc1 invocation was creating, and waiting for, a new process. This patch therefore reduces the number of created processes during a build, thus it reduces build times on platforms where process creation can be costly (Windows) and/or impacted by a antivirus. It also makes debugging a bit easier, as there's no need to attach to the secondary -cc1 process anymore, breakpoints will be hit inside the same process. Crashes or signaling inside the -cc1 invocation will have the same side-effect as before, and will be reported through the same means. This behavior can be controlled at compile-time through the CLANG_SPAWN_CC1 cmake flag, which defaults to OFF. Setting it to ON will revert to the previous behavior, where any -cc1 invocation will create/fork a secondary process. At run-time, it is also possible to tweak the CLANG_SPAWN_CC1 environment variable. Setting it and will override the compile-time setting. A value of 0 calls -cc1 inside the calling process; a value of 1 will create a secondary process, as before. Differential Revision: https://reviews.llvm.org/D69825
Diffstat (limited to 'clang/tools/driver/driver.cpp')
-rw-r--r--clang/tools/driver/driver.cpp43
1 files changed, 37 insertions, 6 deletions
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index f1600490017..4cdf8015b1b 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -14,6 +14,7 @@
#include "clang/Driver/Driver.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/Stack.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
@@ -30,6 +31,7 @@
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
@@ -239,6 +241,8 @@ static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver,
*NumberSignPtr = '=';
}
+static int ExecuteCC1Tool(ArrayRef<const char *> argv);
+
static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
// Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
@@ -254,6 +258,27 @@ static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
if (TheDriver.CCLogDiagnostics)
TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
+
+ // Whether the cc1 tool should be called inside the current process, or if we
+ // should spawn a new clang process (old behavior).
+ // Not having an additional process saves some execution time of Windows,
+ // and makes debugging easier.
+ bool UseNewCC1Process = CLANG_SPAWN_CC1;
+
+ StringRef SpawnCC1Str = ::getenv("CLANG_SPAWN_CC1");
+ if (!SpawnCC1Str.empty()) {
+ if (SpawnCC1Str != "0" && SpawnCC1Str != "1") {
+ llvm::errs() << "error: the value of the environment variable "
+ "CLANG_SPAWN_CC1 must be either 0 or 1.\n";
+ ::exit(1);
+ }
+ UseNewCC1Process = SpawnCC1Str[0] - '0';
+ }
+ if (!UseNewCC1Process) {
+ TheDriver.CC1Main = &ExecuteCC1Tool;
+ // Ensure the CC1Command actually catches cc1 crashes
+ llvm::CrashRecoveryContext::Enable();
+ }
}
static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
@@ -303,13 +328,19 @@ static void SetInstallDir(SmallVectorImpl<const char *> &argv,
TheDriver.setInstalledDir(InstalledPathParent);
}
-static int ExecuteCC1Tool(ArrayRef<const char *> argv, StringRef Tool) {
+static int ExecuteCC1Tool(ArrayRef<const char *> argv) {
+ // If we call the cc1 tool from the clangDriver library (through
+ // Driver::CC1Main), we need to cleanup the options usage count. The options
+ // are currently global, and they might have been used previously by the
+ // driver.
+ llvm::cl::ResetAllOptionOccurrences();
+ StringRef Tool = argv[1];
void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
- if (Tool == "")
+ if (Tool == "-cc1")
return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
- if (Tool == "as")
+ if (Tool == "-cc1as")
return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
- if (Tool == "gen-reproducer")
+ if (Tool == "-cc1gen-reproducer")
return cc1gen_reproducer_main(argv.slice(2), argv[0], GetExecutablePathVP);
// Reject unknown tools.
@@ -379,7 +410,7 @@ int main(int argc_, const char **argv_) {
auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);
argv.resize(newEnd - argv.begin());
}
- return ExecuteCC1Tool(argv, argv[1] + 4);
+ return ExecuteCC1Tool(argv);
}
bool CanonicalPrefixes = true;
@@ -503,7 +534,7 @@ int main(int argc_, const char **argv_) {
#ifdef _WIN32
// Exit status should not be negative on Win32, unless abnormal termination.
- // Once abnormal termiation was caught, negative status should not be
+ // Once abnormal termination was caught, negative status should not be
// propagated.
if (Res < 0)
Res = 1;
OpenPOWER on IntegriCloud