diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -55,9 +55,6 @@ /// The list of program arguments which are inputs. llvm::opt::ArgStringList InputFilenames; - /// Whether to print the input filenames when executing. - bool PrintInputFilenames = false; - /// Response file name, if this command is set to use one, or nullptr /// otherwise const char *ResponseFile = nullptr; @@ -86,6 +83,12 @@ void writeResponseFile(raw_ostream &OS) const; public: + /// Whether to print the input filenames when executing. + bool PrintInputFilenames = false; + + /// Whether the command will be executed in this process or not. + bool InProcess = false; + Command(const Action &Source, const Tool &Creator, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs); @@ -128,9 +131,6 @@ /// Print a command argument, and optionally quote it. static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote); - /// Set whether to print the input filenames when executing. - void setPrintInputFilenames(bool P) { PrintInputFilenames = P; } - protected: /// Optionally print the filenames to be compiled void PrintFileNames() const; @@ -139,7 +139,9 @@ /// Use the CC1 tool callback when available, to avoid creating a new process class CC1Command : public Command { public: - using Command::Command; + CC1Command(const Action &Source, const Tool &Creator, const char *Executable, + const llvm::opt::ArgStringList &Arguments, + ArrayRef Inputs); void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo = nullptr) const override; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3753,6 +3753,11 @@ /*TargetDeviceOffloadKind*/ Action::OFK_None); } + // If we have more than one job, then disable integrated-cc1 for now. + if (C.getJobs().size() > 1) + for (auto &J : C.getJobs()) + J.InProcess = false; + // If the user passed -Qunused-arguments or there were errors, don't warn // about any unused arguments. if (Diags.hasErrorOccurred() || diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -371,14 +371,29 @@ /*memoryLimit*/ 0, ErrMsg, ExecutionFailed); } +CC1Command::CC1Command(const Action &Source, const Tool &Creator, + const char *Executable, + const llvm::opt::ArgStringList &Arguments, + ArrayRef Inputs) + : Command(Source, Creator, Executable, Arguments, Inputs) { + InProcess = true; +} + void CC1Command::Print(raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo) const { - OS << " (in-process)\n"; + if (InProcess) + OS << " (in-process)\n"; Command::Print(OS, Terminator, Quote, CrashInfo); } -int CC1Command::Execute(ArrayRef> /*Redirects*/, +int CC1Command::Execute(ArrayRef> Redirects, std::string *ErrMsg, bool *ExecutionFailed) const { + // FIXME: Currently, if there're more than one job, we disable + // -fintegrate-cc1. If we're no longer a integrated-cc1 job, fallback to + // out-of-process execution. See discussion in https://reviews.llvm.org/D74447 + if (!InProcess) + return Command::Execute(Redirects, ErrMsg, ExecutionFailed); + PrintFileNames(); SmallVector Argv; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6146,7 +6146,7 @@ if (Output.getType() == types::TY_Object && Args.hasFlag(options::OPT__SLASH_showFilenames, options::OPT__SLASH_showFilenames_, false)) { - C.getJobs().getJobs().back()->setPrintInputFilenames(true); + C.getJobs().getJobs().back()->PrintInputFilenames = true; } if (Arg *A = Args.getLastArg(options::OPT_pg)) diff --git a/clang/test/Driver/cc1-spawnprocess.c b/clang/test/Driver/cc1-spawnprocess.c --- a/clang/test/Driver/cc1-spawnprocess.c +++ b/clang/test/Driver/cc1-spawnprocess.c @@ -1,22 +1,37 @@ -// 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 -c -### %s 2>&1 | FileCheck %s --check-prefix=YES +// RUN: %clang -fno-integrated-cc1 -c -### %s 2>&1 | FileCheck %s --check-prefix=NO -// RUN: %clang -fintegrated-cc1 -fno-integrated-cc1 -### %s 2>&1 \ +// RUN: %clang -fintegrated-cc1 -fno-integrated-cc1 -c -### %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO -// RUN: %clang -fno-integrated-cc1 -fintegrated-cc1 -### %s 2>&1 \ +// RUN: %clang -fno-integrated-cc1 -fintegrated-cc1 -c -### %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=YES -// RUN: %clang_cl -fintegrated-cc1 -### -- %s 2>&1 \ +// RUN: %clang_cl -fintegrated-cc1 -c -### -- %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=YES -// RUN: %clang_cl -fno-integrated-cc1 -### -- %s 2>&1 \ +// RUN: %clang_cl -fno-integrated-cc1 -c -### -- %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO // RUN: env CCC_OVERRIDE_OPTIONS=+-fintegrated-cc1 \ -// RUN: %clang -fintegrated-cc1 -### %s 2>&1 \ +// RUN: %clang -fintegrated-cc1 -c -### %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: %clang -fintegrated-cc1 -c -### %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO // YES: (in-process) // NO-NOT: (in-process) + +// The following tests ensure that only one integrated-cc1 is executed. + +// Only one TU, one job, thus integrated-cc1 is enabled. +// RUN: %clang -fintegrated-cc1 -c %s -### 2>&1 | FileCheck %s --check-prefix=YES + +// Only one TU, but we're linking, two jobs, thus integrated-cc1 is disabled. +// RUN: %clang -fintegrated-cc1 %s -### 2>&1 | FileCheck %s --check-prefix=NO + +// RUN: echo 'int main() { return f() + g(); }' > %t1.cpp +// RUN: echo 'int f() { return 1; }' > %t2.cpp +// RUN: echo 'int g() { return 2; }' > %t3.cpp + +// Three jobs, thus integrated-cc1 is disabled. +// RUN: %clang -fintegrated-cc1 -c %t1.cpp %t2.cpp %t3.cpp -### 2>&1 | FileCheck %s --check-prefix=NO