Skip to content

Commit

Permalink
Replace CLANG_SPAWN_CC1 env var with a driver mode flag
Browse files Browse the repository at this point in the history
Flags are clang's default UI is flags.

We can have an env var in addition to that, but in D69825 nobody has yet
mentioned why this needs an env var, so omit it for now.  If someone
needs to set the flag via env var, the existing CCC_OVERRIDE_OPTIONS
mechanism works for it (set CCC_OVERRIDE_OPTIONS=+-fno-integrated-cc1
for example).

Also mention the cc1-in-process change in the release notes.

Also spruce up the test a bit so it actually tests something :)

Differential Revision: https://reviews.llvm.org/D72769

(cherry picked from commit 8e5018e)
  • Loading branch information
nico authored and zmodem committed Jan 16, 2020
1 parent 0b5157d commit c4a134a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 28 deletions.
5 changes: 5 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ sections with improvements to Clang's support for those languages.
Major New Features
------------------

- clang used to run the actual compilation in a subprocess ("clang -cc1").
Now compilations are done in-process by default. ``-fno-integrated-cc1``
restores the former behavior. The ``-v`` and ``-###`` flags will print
"(in-process)" when compilations are done in-process.

- ...

Improvements to Clang's diagnostics
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2855,6 +2855,14 @@ def fintegrated_as : Flag<["-"], "fintegrated-as">, Flags<[DriverOption]>,
def fno_integrated_as : Flag<["-"], "fno-integrated-as">,
Flags<[CC1Option, DriverOption]>, Group<f_Group>,
HelpText<"Disable the integrated assembler">;

def fintegrated_cc1 : Flag<["-"], "fintegrated-cc1">,
Flags<[CoreOption, DriverOption]>, Group<f_Group>,
HelpText<"Run cc1 in-process">;
def fno_integrated_cc1 : Flag<["-"], "fno-integrated-cc1">,
Flags<[CoreOption, DriverOption]>, Group<f_Group>,
HelpText<"Spawn a separate process for each cc1">;

def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[DriverOption]>;
def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
Flags<[CC1Option, DriverOption]>;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,10 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// -no-canonical-prefixes is used very early in main.
Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);

// f(no-)integated-cc1 is also used very early in main.
Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);

// Ignore -pipe.
Args.ClaimAllArgs(options::OPT_pipe);

Expand Down
26 changes: 22 additions & 4 deletions clang/test/Driver/cc1-spawnprocess.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
// RUN: env CLANG_SPAWN_CC1= %clang -S %s -o /dev/null
// RUN: env CLANG_SPAWN_CC1=0 %clang -S %s -o /dev/null
// RUN: env CLANG_SPAWN_CC1=1 %clang -S %s -o /dev/null
// RUN: env CLANG_SPAWN_CC1=test not %clang -S %s -o /dev/null
// RUN: %clang -fintegrated-cc1 -### %s 2>&1 | FileCheck %s --check-prefix=YES
// RUN: %clang -fno-integrated-cc1 -### %s 2>&1 | FileCheck %s --check-prefix=NO

// RUN: %clang -fintegrated-cc1 -fno-integrated-cc1 -### %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NO
// RUN: %clang -fno-integrated-cc1 -fintegrated-cc1 -### %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=YES

// RUN: %clang_cl -fintegrated-cc1 -### -- %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=YES
// RUN: %clang_cl -fno-integrated-cc1 -### -- %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NO

// RUN: env CCC_OVERRIDE_OPTIONS=+-fintegrated-cc1 \
// RUN: %clang -fintegrated-cc1 -### %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=YES
// RUN: env CCC_OVERRIDE_OPTIONS=+-fno-integrated-cc1 \
// RUN: %clang -fintegrated-cc1 -### %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NO

// YES: (in-process)
// NO-NOT: (in-process)
47 changes: 23 additions & 24 deletions clang/tools/driver/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,27 +258,6 @@ 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,
Expand All @@ -294,7 +273,7 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
// This lets us create the DiagnosticsEngine with a properly-filled-out
// DiagnosticOptions instance.
static DiagnosticOptions *
CreateAndPopulateDiagOpts(ArrayRef<const char *> argv) {
CreateAndPopulateDiagOpts(ArrayRef<const char *> argv, bool &UseNewCC1Process) {
auto *DiagOpts = new DiagnosticOptions;
unsigned MissingArgIndex, MissingArgCount;
InputArgList Args = getDriverOptTable().ParseArgs(
Expand All @@ -303,6 +282,12 @@ CreateAndPopulateDiagOpts(ArrayRef<const char *> argv) {
// Any errors that would be diagnosed here will also be diagnosed later,
// when the DiagnosticsEngine actually exists.
(void)ParseDiagnosticArgs(*DiagOpts, Args);

UseNewCC1Process =
Args.hasFlag(clang::driver::options::OPT_fno_integrated_cc1,
clang::driver::options::OPT_fintegrated_cc1,
/*Default=*/CLANG_SPAWN_CC1);

return DiagOpts;
}

Expand Down Expand Up @@ -330,7 +315,7 @@ static void SetInstallDir(SmallVectorImpl<const char *> &argv,

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
// Driver::CC1Main), we need to clean up the options usage count. The options
// are currently global, and they might have been used previously by the
// driver.
llvm::cl::ResetAllOptionOccurrences();
Expand Down Expand Up @@ -413,6 +398,8 @@ int main(int argc_, const char **argv_) {
return ExecuteCC1Tool(argv);
}

// Handle options that need handling before the real command line parsing in
// Driver::BuildCompilation()
bool CanonicalPrefixes = true;
for (int i = 1, size = argv.size(); i < size; ++i) {
// Skip end-of-line response file markers
Expand Down Expand Up @@ -457,8 +444,14 @@ int main(int argc_, const char **argv_) {

std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);

// Whether the cc1 tool should be called inside the current process, or if we
// should spawn a new clang subprocess (old behavior).
// Not having an additional process saves some execution time of Windows,
// and makes debugging and profiling easier.
bool UseNewCC1Process;

IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
CreateAndPopulateDiagOpts(argv);
CreateAndPopulateDiagOpts(argv, UseNewCC1Process);

TextDiagnosticPrinter *DiagClient
= new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
Expand Down Expand Up @@ -486,6 +479,12 @@ int main(int argc_, const char **argv_) {

SetBackdoorDriverOutputsFromEnvVars(TheDriver);

if (!UseNewCC1Process) {
TheDriver.CC1Main = &ExecuteCC1Tool;
// Ensure the CC1Command actually catches cc1 crashes
llvm::CrashRecoveryContext::Enable();
}

std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 1;
if (C && !C->containsError()) {
Expand Down

0 comments on commit c4a134a

Please sign in to comment.