summaryrefslogtreecommitdiff
path: root/lib/Driver/Compilation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Compilation.cpp')
-rw-r--r--lib/Driver/Compilation.cpp97
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;
}