diff options
Diffstat (limited to 'lib/Driver/Compilation.cpp')
-rw-r--r-- | lib/Driver/Compilation.cpp | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index cf86644fb8cd..645da5059587 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -26,9 +26,9 @@ Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain, InputArgList *_Args, DerivedArgList *_TranslatedArgs, bool ContainsError) : TheDriver(D), DefaultToolChain(_DefaultToolChain), ActiveOffloadMask(0u), - Args(_Args), TranslatedArgs(_TranslatedArgs), Redirects(nullptr), - ForDiagnostics(false), ContainsError(ContainsError) { - // The offloading host toolchain is the default tool chain. + Args(_Args), TranslatedArgs(_TranslatedArgs), ForDiagnostics(false), + ContainsError(ContainsError) { + // The offloading host toolchain is the default toolchain. OrderedOffloadingToolchains.insert( std::make_pair(Action::OFK_Host, &DefaultToolChain)); } @@ -41,14 +41,6 @@ Compilation::~Compilation() { for (auto Arg : TCArgs) if (Arg.second != TranslatedArgs) delete Arg.second; - - // Free redirections of stdout/stderr. - if (Redirects) { - delete Redirects[0]; - delete Redirects[1]; - delete Redirects[2]; - delete [] Redirects; - } } const DerivedArgList & @@ -59,9 +51,32 @@ Compilation::getArgsForToolChain(const ToolChain *TC, StringRef BoundArch, DerivedArgList *&Entry = TCArgs[{TC, BoundArch, DeviceOffloadKind}]; if (!Entry) { - Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch, DeviceOffloadKind); - if (!Entry) - Entry = TranslatedArgs; + SmallVector<Arg *, 4> AllocatedArgs; + DerivedArgList *OpenMPArgs = nullptr; + // Translate OpenMP toolchain arguments provided via the -Xopenmp-target flags. + if (DeviceOffloadKind == Action::OFK_OpenMP) { + const ToolChain *HostTC = getSingleOffloadToolChain<Action::OFK_Host>(); + bool SameTripleAsHost = (TC->getTriple() == HostTC->getTriple()); + OpenMPArgs = TC->TranslateOpenMPTargetArgs( + *TranslatedArgs, SameTripleAsHost, AllocatedArgs); + } + + if (!OpenMPArgs) { + Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch, DeviceOffloadKind); + if (!Entry) + Entry = TranslatedArgs; + } else { + Entry = TC->TranslateArgs(*OpenMPArgs, BoundArch, DeviceOffloadKind); + if (!Entry) + Entry = OpenMPArgs; + else + delete OpenMPArgs; + } + + // Add allocated arguments to the final DAL. + for (auto ArgPtr : AllocatedArgs) { + Entry->AddSynthesizedArg(ArgPtr); + } } return *Entry; @@ -167,16 +182,51 @@ int Compilation::ExecuteCommand(const Command &C, return ExecutionFailed ? 1 : Res; } -void Compilation::ExecuteJobs( - const JobList &Jobs, - SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const { +using FailingCommandList = SmallVectorImpl<std::pair<int, const Command *>>; + +static bool ActionFailed(const Action *A, + const FailingCommandList &FailingCommands) { + + if (FailingCommands.empty()) + return false; + + // CUDA can have the same input source code compiled multiple times so do not + // compiled again if there are already failures. It is OK to abort the CUDA + // pipeline on errors. + if (A->isOffloading(Action::OFK_Cuda)) + return true; + + for (const auto &CI : FailingCommands) + if (A == &(CI.second->getSource())) + return true; + + for (const Action *AI : A->inputs()) + if (ActionFailed(AI, FailingCommands)) + return true; + + return false; +} + +static bool InputsOk(const Command &C, + const FailingCommandList &FailingCommands) { + return !ActionFailed(&C.getSource(), FailingCommands); +} + +void Compilation::ExecuteJobs(const JobList &Jobs, + FailingCommandList &FailingCommands) const { + // According to UNIX standard, driver need to continue compiling all the + // inputs on the command line even one of them failed. + // In all but CLMode, execute all the jobs unless the necessary inputs for the + // job is missing due to previous failures. for (const auto &Job : Jobs) { + if (!InputsOk(Job, FailingCommands)) + continue; const Command *FailingCommand = nullptr; if (int Res = ExecuteCommand(Job, FailingCommand)) { FailingCommands.push_back(std::make_pair(Res, FailingCommand)); - // Bail as soon as one command fails, so we don't output duplicate error - // messages if we die on e.g. the same file. - return; + // Bail as soon as one command fails in cl driver mode. + if (TheDriver.IsCLMode()) + return; } } } @@ -205,16 +255,13 @@ void Compilation::initCompilationForDiagnostics() { TranslatedArgs->ClaimAllArgs(); // Redirect stdout/stderr to /dev/null. - Redirects = new const StringRef*[3](); - Redirects[0] = nullptr; - Redirects[1] = new StringRef(); - Redirects[2] = new StringRef(); + Redirects = {None, {""}, {""}}; } StringRef Compilation::getSysRoot() const { return getDriver().SysRoot; } -void Compilation::Redirect(const StringRef** Redirects) { +void Compilation::Redirect(ArrayRef<Optional<StringRef>> Redirects) { this->Redirects = Redirects; } |