diff options
| author | Samuel Antao <sfantao@us.ibm.com> | 2016-10-27 17:50:43 +0000 |
|---|---|---|
| committer | Samuel Antao <sfantao@us.ibm.com> | 2016-10-27 17:50:43 +0000 |
| commit | 69d6f31f744a8b3dcb1a3fecae41a9d6f667b476 (patch) | |
| tree | 5c8e8f72da3b46e46b3989fef3f8380f7a370ea2 /clang/lib/Driver | |
| parent | 093abab817e61da02ddc30774b22a16641deac38 (diff) | |
| download | bcm5719-llvm-69d6f31f744a8b3dcb1a3fecae41a9d6f667b476.tar.gz bcm5719-llvm-69d6f31f744a8b3dcb1a3fecae41a9d6f667b476.zip | |
[Driver][OpenMP] Update actions builder to create bundling action when necessary.
Summary:
In order to save the user from dealing with multiple output files (for host and device) while using separate compilation, a new action `OffloadBundlingAction` is used when the last phase is not linking. This action will then result in a job that uses the proposed bundling tool to create a single preprocessed/IR/ASM/Object file from multiple ones.
The job creation for the new action will be proposed in a separate patch.
Reviewers: echristo, tra, jlebar, ABataev, hfinkel
Subscribers: whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin
Differential Revision: https://reviews.llvm.org/D21852
llvm-svn: 285323
Diffstat (limited to 'clang/lib/Driver')
| -rw-r--r-- | clang/lib/Driver/Action.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Driver/Driver.cpp | 70 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 4 |
3 files changed, 77 insertions, 4 deletions
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index a351429ad7b..90bc149fd33 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -36,6 +36,8 @@ const char *Action::getClassName(ActionClass AC) { case DsymutilJobClass: return "dsymutil"; case VerifyDebugInfoJobClass: return "verify-debug-info"; case VerifyPCHJobClass: return "verify-pch"; + case OffloadBundlingJobClass: + return "clang-offload-bundler"; } llvm_unreachable("invalid class"); @@ -346,3 +348,8 @@ void VerifyPCHJobAction::anchor() {} VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type) : VerifyJobAction(VerifyPCHJobClass, Input, Type) {} + +void OffloadBundlingJobAction::anchor() {} + +OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs) + : JobAction(OffloadBundlingJobClass, Inputs, Inputs.front()->getType()) {} diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index fe9605279f3..8d96284a69b 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1568,6 +1568,9 @@ class OffloadingActionBuilder final { /// found. virtual bool initialize() { return false; } + /// Return true if the builder can use bundling/unbundling. + virtual bool canUseBundlerUnbundler() const { return false; } + /// Return true if this builder is valid. We have a valid builder if we have /// associated device tool chains. bool isValid() { return !ToolChains.empty(); } @@ -1911,6 +1914,26 @@ class OffloadingActionBuilder final { return ABRT_Success; } + void appendTopLevelActions(ActionList &AL) override { + if (OpenMPDeviceActions.empty()) + return; + + // We should always have an action for each input. + assert(OpenMPDeviceActions.size() == ToolChains.size() && + "Number of OpenMP actions and toolchains do not match."); + + // Append all device actions followed by the proper offload action. + auto TI = ToolChains.begin(); + for (auto *A : OpenMPDeviceActions) { + OffloadAction::DeviceDependences Dep; + Dep.add(*A, **TI, /*BoundArch=*/nullptr, Action::OFK_OpenMP); + AL.push_back(C.MakeAction<OffloadAction>(Dep, A->getType())); + ++TI; + } + // We no longer need the action stored in this builder. + OpenMPDeviceActions.clear(); + } + void appendLinkDependences(OffloadAction::DeviceDependences &DA) override { assert(ToolChains.size() == DeviceLinkerInputs.size() && "Toolchains and linker inputs sizes do not match."); @@ -1937,6 +1960,11 @@ class OffloadingActionBuilder final { DeviceLinkerInputs.resize(ToolChains.size()); return false; } + + bool canUseBundlerUnbundler() const override { + // OpenMP should use bundled files whenever possible. + return true; + } }; /// @@ -1946,6 +1974,9 @@ class OffloadingActionBuilder final { /// Specialized builders being used by this offloading action builder. SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders; + /// Flag set to true if all valid builders allow file bundling/unbundling. + bool CanUseBundler; + public: OffloadingActionBuilder(Compilation &C, DerivedArgList &Args, const Driver::InputList &Inputs) @@ -1964,9 +1995,22 @@ public: // TODO: Build other specialized builders here. // - // Initialize all the builders, keeping track of errors. - for (auto *SB : SpecializedBuilders) + // Initialize all the builders, keeping track of errors. If all valid + // builders agree that we can use bundling, set the flag to true. + unsigned ValidBuilders = 0u; + unsigned ValidBuildersSupportingBundling = 0u; + for (auto *SB : SpecializedBuilders) { IsValid = IsValid && !SB->initialize(); + + // Update the counters if the builder is valid. + if (SB->isValid()) { + ++ValidBuilders; + if (SB->canUseBundlerUnbundler()) + ++ValidBuildersSupportingBundling; + } + } + CanUseBundler = + ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling; } ~OffloadingActionBuilder() { @@ -2066,15 +2110,33 @@ public: return false; } - /// Add the offloading top level actions to the provided action list. + /// Add the offloading top level actions to the provided action list. This + /// function can replace the host action by a bundling action if the + /// programming models allow it. bool appendTopLevelActions(ActionList &AL, Action *HostAction, const Arg *InputArg) { + // Get the device actions to be appended. + ActionList OffloadAL; for (auto *SB : SpecializedBuilders) { if (!SB->isValid()) continue; - SB->appendTopLevelActions(AL); + SB->appendTopLevelActions(OffloadAL); } + // If we can use the bundler, replace the host action by the bundling one in + // the resulting list. Otherwise, just append the device actions. + if (CanUseBundler && !OffloadAL.empty()) { + // Add the host action to the list in order to create the bundling action. + OffloadAL.push_back(HostAction); + + // We expect that the host action was just appended to the action list + // before this method was called. + assert(HostAction == AL.back() && "Host action not in the list??"); + HostAction = C.MakeAction<OffloadBundlingJobAction>(OffloadAL); + AL.back() = HostAction; + } else + AL.append(OffloadAL.begin(), OffloadAL.end()); + // Propagate to the current host action (if any) the offload information // associated with the current input. if (HostAction) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 90232659659..a82ebfe6d98 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -263,6 +263,10 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::VerifyPCHJobClass: case Action::BackendJobClass: return getClang(); + + case Action::OffloadBundlingJobClass: + // FIXME: Add a tool for the bundling actions. + return nullptr; } llvm_unreachable("Invalid tool kind."); |

