jlebar created this revision.
jlebar added a reviewer: tra.
jlebar added subscribers: echristo, cfe-commits, jhen.

When compiling CUDA, we run the frontend N times, once for each device
arch.  This means that if you have a compile error in your file, you'll
see that error N times.

Relatedly, if ptxas fails, we'll output that error and then still try to
pass its output to fatbinary, which then fails because (duh) its input
file doesn't exist.

This patch stops compilations with -stop-on-failure as soon as we
encounter an error.  -stop-on-failure is turned on by default for CUDA
compilations.

http://reviews.llvm.org/D16514

Files:
  include/clang/Driver/Compilation.h
  include/clang/Driver/Driver.h
  include/clang/Driver/Options.td
  lib/Driver/Compilation.cpp
  lib/Driver/Driver.cpp

Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -58,7 +58,8 @@
       CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
       CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
       CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
-      CCCUsePCH(true), SuppressMissingInputWarning(false) {
+      CCCUsePCH(true), SuppressMissingInputWarning(false),
+      StopOnJobFailure(false) {
 
   // Provide a sane fallback if no VFS is specified.
   if (!this->VFS)
@@ -503,6 +504,16 @@
   InputList Inputs;
   BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
 
+  // StopOnJobFailure defaults to false, except for CUDA compilations.
+  if (Arg *A = C->getArgs().getLastArg(options::OPT_stop_on_failure,
+                                       options::OPT_nostop_on_failure))
+    StopOnJobFailure = A->getOption().matches(options::OPT_stop_on_failure);
+  else
+    StopOnJobFailure =
+        llvm::any_of(Inputs, [](const std::pair<types::ID, const Arg *> &I) {
+          return I.first == types::TY_CUDA;
+        });
+
   // Construct the list of abstract actions to perform for this compilation. On
   // MachO targets this uses the driver-driver and universal actions.
   if (TC.getTriple().isOSBinFormatMachO())
@@ -636,7 +647,7 @@
 
   // Generate preprocessed output.
   SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
-  C.ExecuteJobs(C.getJobs(), FailingCommands);
+  C.ExecuteJobs(C.getJobs(), /* StopOnFailure = */ false, FailingCommands);
 
   // If any of the preprocessing commands failed, clean up and exit.
   if (!FailingCommands.empty()) {
@@ -728,7 +739,7 @@
   for (auto &Job : C.getJobs())
     setUpResponseFiles(C, Job);
 
-  C.ExecuteJobs(C.getJobs(), FailingCommands);
+  C.ExecuteJobs(C.getJobs(), StopOnJobFailure, FailingCommands);
 
   // Remove temp files.
   C.CleanupFileList(C.getTempFiles());
Index: lib/Driver/Compilation.cpp
===================================================================
--- lib/Driver/Compilation.cpp
+++ lib/Driver/Compilation.cpp
@@ -188,14 +188,17 @@
   return !ActionFailed(&C.getSource(), FailingCommands);
 }
 
-void Compilation::ExecuteJobs(const JobList &Jobs,
+void Compilation::ExecuteJobs(const JobList &Jobs, bool StopOnFailure,
                               FailingCommandList &FailingCommands) const {
   for (const auto &Job : Jobs) {
     if (!InputsOk(Job, FailingCommands))
       continue;
     const Command *FailingCommand = nullptr;
-    if (int Res = ExecuteCommand(Job, FailingCommand))
+    if (int Res = ExecuteCommand(Job, FailingCommand)) {
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
+      if (StopOnFailure)
+        return;
+    }
   }
 }
 
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1801,6 +1801,11 @@
 def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
       Flags<[CC1Option, DriverOption]>;
 
+def stop_on_failure : Flag<["-"], "stop-on-failure">, Flags<[DriverOption]>,
+  HelpText<"Stop running jobs as soon as one fails.  This is the default during "
+    "CUDA compilation without --save-temps.">;
+def nostop_on_failure : Flag<["-"], "nostop-on-failure">, Flags<[DriverOption]>;
+
 def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>,
   HelpText<"Resolve file paths relative to the specified directory">;
 def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>,
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -192,6 +192,10 @@
   /// Certain options suppress the 'no input files' warning.
   bool SuppressMissingInputWarning : 1;
 
+  /// Should we stop running all jobs as soon as one fails?  If false, we run as
+  /// much as we can.
+  bool StopOnJobFailure : 1;
+
   std::list<std::string> TempFiles;
   std::list<std::string> ResultFiles;
 
Index: include/clang/Driver/Compilation.h
===================================================================
--- include/clang/Driver/Compilation.h
+++ include/clang/Driver/Compilation.h
@@ -193,12 +193,13 @@
   /// \return The result code of the subprocess.
   int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
 
-  /// ExecuteJob - Execute a single job.
+  /// ExecuteJobs - Execute a list of jobs.
   ///
-  /// \param FailingCommands - For non-zero results, this will be a vector of
-  /// failing commands and their associated result code.
+  /// \param StopOnFailure - If true, execution stops as soon as one job fails.
+  /// \param FailingCommands - Outparam that's set to the list of Commands that
+  /// failed, plus their associated result codes.
   void ExecuteJobs(
-      const JobList &Jobs,
+      const JobList &Jobs, bool StopOnFailure,
       SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
 
   /// initCompilationForDiagnostics - Remove stale state and suppress output
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to