diff options
author | Samuel Antao <sfantao@us.ibm.com> | 2016-10-27 18:14:55 +0000 |
---|---|---|
committer | Samuel Antao <sfantao@us.ibm.com> | 2016-10-27 18:14:55 +0000 |
commit | 3b7e38b45061826dde67445dfc1488b489872a68 (patch) | |
tree | a4e98a6fc9c02b96637e4fb807201bd5d3221c3b /clang/lib/Driver/Driver.cpp | |
parent | 7cab8f14662bfeb0f7fc8507f09421123c5c9474 (diff) | |
download | bcm5719-llvm-3b7e38b45061826dde67445dfc1488b489872a68.tar.gz bcm5719-llvm-3b7e38b45061826dde67445dfc1488b489872a68.zip |
[Driver][OpenMP] Add support to create jobs for unbundling actions.
Summary:
This patch adds the support to create jobs for the `OffloadBundlingAction` which will invoke the `clang-offload-bundler` tool to unbundle input files.
Unlike other actions, unbundling actions have multiple outputs. Therefore, this patch adds the required changes to have a variant of `Tool::ConstructJob` with multiple outputs.
The way the naming of the results is implemented is also slightly modified so that the same action can use a different offloading prefix for each use by the different offloading actions.
With this patch, it is possible to compile a functional OpenMP binary with offloading support, even with separate compilation.
Reviewers: echristo, tra, jlebar, ABataev, hfinkel
Subscribers: mkuron, whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin
Differential Revision: https://reviews.llvm.org/D21857
llvm-svn: 285326
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 140 |
1 files changed, 104 insertions, 36 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 2712efb0ffe..a2929de6aec 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2593,7 +2593,7 @@ void Driver::BuildJobs(Compilation &C) const { /*AtTopLevel*/ true, /*MultipleArchs*/ ArchNames.size() > 1, /*LinkingOutput*/ LinkingOutput, CachedResults, - /*BuildForOffloadDevice*/ false); + /*TargetDeviceOffloadKind*/ Action::OFK_None); } // If the user passed -Qunused-arguments or there were errors, don't warn @@ -2926,31 +2926,38 @@ public: }; } -InputInfo Driver::BuildJobsForAction( - Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, - bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, - std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults, - bool BuildForOffloadDevice) const { - // The bound arch is not necessarily represented in the toolchain's triple -- - // for example, armv7 and armv7s both map to the same triple -- so we need - // both in our map. Also, we need to add the offloading device kind, as the - // same tool chain can be used for host and device for some programming - // models, e.g. OpenMP. +/// Return a string that uniquely identifies the result of a job. The bound arch +/// is not necessarily represented in the toolchain's triple -- for example, +/// armv7 and armv7s both map to the same triple -- so we need both in our map. +/// Also, we need to add the offloading device kind, as the same tool chain can +/// be used for host and device for some programming models, e.g. OpenMP. +static std::string GetTriplePlusArchString(const ToolChain *TC, + StringRef BoundArch, + Action::OffloadKind OffloadKind) { std::string TriplePlusArch = TC->getTriple().normalize(); if (!BoundArch.empty()) { TriplePlusArch += "-"; TriplePlusArch += BoundArch; } TriplePlusArch += "-"; - TriplePlusArch += A->getOffloadingKindPrefix(); - std::pair<const Action *, std::string> ActionTC = {A, TriplePlusArch}; + TriplePlusArch += Action::GetOffloadKindName(OffloadKind); + return TriplePlusArch; +} + +InputInfo Driver::BuildJobsForAction( + Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, + bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, + std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults, + Action::OffloadKind TargetDeviceOffloadKind) const { + std::pair<const Action *, std::string> ActionTC = { + A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}; auto CachedResult = CachedResults.find(ActionTC); if (CachedResult != CachedResults.end()) { return CachedResult->second; } InputInfo Result = BuildJobsForActionNoCache( C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput, - CachedResults, BuildForOffloadDevice); + CachedResults, TargetDeviceOffloadKind); CachedResults[ActionTC] = Result; return Result; } @@ -2959,10 +2966,11 @@ InputInfo Driver::BuildJobsForActionNoCache( Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults, - bool BuildForOffloadDevice) const { + Action::OffloadKind TargetDeviceOffloadKind) const { llvm::PrettyStackTraceString CrashInfo("Building compilation jobs"); InputInfoList OffloadDependencesInputInfo; + bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None; if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) { // The offload action is expected to be used in four different situations. // @@ -2995,7 +3003,7 @@ InputInfo Driver::BuildJobsForActionNoCache( DevA = BuildJobsForAction(C, DepA, DepTC, DepBoundArch, AtTopLevel, /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, - CachedResults, /*BuildForOffloadDevice=*/true); + CachedResults, DepA->getOffloadingDeviceKind()); }); return DevA; } @@ -3005,16 +3013,15 @@ InputInfo Driver::BuildJobsForActionNoCache( // generate the host dependences and override the action with the device // dependence. The dependences can't therefore be a top-level action. OA->doOnEachDependence( - /*IsHostDependence=*/BuildForOffloadDevice, + /*IsHostDependence=*/BuildingForOffloadDevice, [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) { OffloadDependencesInputInfo.push_back(BuildJobsForAction( C, DepA, DepTC, DepBoundArch, /*AtTopLevel=*/false, /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, CachedResults, - /*BuildForOffloadDevice=*/DepA->getOffloadingDeviceKind() != - Action::OFK_None)); + DepA->getOffloadingDeviceKind())); }); - A = BuildForOffloadDevice + A = BuildingForOffloadDevice ? OA->getSingleDeviceDependence(/*DoNotConsiderHostActions=*/true) : OA->getHostDependence(); } @@ -3044,7 +3051,7 @@ InputInfo Driver::BuildJobsForActionNoCache( return BuildJobsForAction(C, *BAA->input_begin(), TC, ArchName, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults, - BuildForOffloadDevice); + TargetDeviceOffloadKind); } @@ -3063,13 +3070,12 @@ InputInfo Driver::BuildJobsForActionNoCache( // need to build jobs for host/device-side inputs it may have held. for (const auto *OA : CollapsedOffloadActions) cast<OffloadAction>(OA)->doOnEachDependence( - /*IsHostDependence=*/BuildForOffloadDevice, + /*IsHostDependence=*/BuildingForOffloadDevice, [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) { OffloadDependencesInputInfo.push_back(BuildJobsForAction( C, DepA, DepTC, DepBoundArch, /* AtTopLevel */ false, /*MultipleArchs=*/!!DepBoundArch, LinkingOutput, CachedResults, - /*BuildForOffloadDevice=*/DepA->getOffloadingDeviceKind() != - Action::OFK_None)); + DepA->getOffloadingDeviceKind())); }); // Only use pipes when there is exactly one input. @@ -3082,7 +3088,7 @@ InputInfo Driver::BuildJobsForActionNoCache( AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A)); InputInfos.push_back(BuildJobsForAction( C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput, - CachedResults, BuildForOffloadDevice)); + CachedResults, A->getOffloadingDeviceKind())); } // Always use the first input as the base input. @@ -3114,13 +3120,59 @@ InputInfo Driver::BuildJobsForActionNoCache( // Determine the place to write output to, if any. InputInfo Result; - if (JA->getType() == types::TY_Nothing) + InputInfoList UnbundlingResults; + if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) { + // If we have an unbundling job, we need to create results for all the + // outputs. We also update the results cache so that other actions using + // this unbundling action can get the right results. + for (auto &UI : UA->getDependentActionsInfo()) { + assert(UI.DependentOffloadKind != Action::OFK_None && + "Unbundling with no offloading??"); + + // Unbundling actions are never at the top level. When we generate the + // offloading prefix, we also do that for the host file because the + // unbundling action does not change the type of the output which can + // cause a overwrite. + std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix( + UI.DependentOffloadKind, + UI.DependentToolChain->getTriple().normalize(), + /*CreatePrefixForHost=*/true); + auto CurI = InputInfo( + UA, GetNamedOutputPath(C, *UA, BaseInput, UI.DependentBoundArch, + /*AtTopLevel=*/false, MultipleArchs, + OffloadingPrefix), + BaseInput); + // Save the unbundling result. + UnbundlingResults.push_back(CurI); + + // Get the unique string identifier for this dependence and cache the + // result. + CachedResults[{A, GetTriplePlusArchString( + UI.DependentToolChain, UI.DependentBoundArch, + UI.DependentOffloadKind)}] = CurI; + } + + // Now that we have all the results generated, select the one that should be + // returned for the current depending action. + std::pair<const Action *, std::string> ActionTC = { + A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)}; + assert(CachedResults.find(ActionTC) != CachedResults.end() && + "Result does not exist??"); + Result = CachedResults[ActionTC]; + } else if (JA->getType() == types::TY_Nothing) Result = InputInfo(A, BaseInput); - else + else { + // We only have to generate a prefix for the host if this is not a top-level + // action. + std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix( + A->getOffloadingDeviceKind(), TC->getTriple().normalize(), + /*CreatePrefixForHost=*/!!A->getOffloadingHostActiveKinds() && + !AtTopLevel); Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch, AtTopLevel, MultipleArchs, - TC->getTriple().normalize()), + OffloadingPrefix), BaseInput); + } if (CCCPrintBindings && !CCGenDiagnostics) { llvm::errs() << "# \"" << T->getToolChain().getTripleString() << '"' @@ -3130,12 +3182,28 @@ InputInfo Driver::BuildJobsForActionNoCache( if (i + 1 != e) llvm::errs() << ", "; } - llvm::errs() << "], output: " << Result.getAsString() << "\n"; + if (UnbundlingResults.empty()) + llvm::errs() << "], output: " << Result.getAsString() << "\n"; + else { + llvm::errs() << "], outputs: ["; + for (unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) { + llvm::errs() << UnbundlingResults[i].getAsString(); + if (i + 1 != e) + llvm::errs() << ", "; + } + llvm::errs() << "] \n"; + } } else { - T->ConstructJob( - C, *JA, Result, InputInfos, - C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), - LinkingOutput); + if (UnbundlingResults.empty()) + T->ConstructJob( + C, *JA, Result, InputInfos, + C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), + LinkingOutput); + else + T->ConstructJob( + C, *JA, UnbundlingResults, InputInfos, + C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), + LinkingOutput); } return Result; } @@ -3182,7 +3250,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, - StringRef NormalizedTriple) const { + StringRef OffloadingPrefix) const { llvm::PrettyStackTraceString CrashInfo("Computing output path"); // Output to a user requested destination? if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) { @@ -3268,7 +3336,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, MakeCLOutputFilename(C.getArgs(), "", BaseName, types::TY_Image); } else { SmallString<128> Output(getDefaultImageName()); - Output += JA.getOffloadingFileNamePrefix(NormalizedTriple); + Output += OffloadingPrefix; if (MultipleArchs && !BoundArch.empty()) { Output += "-"; Output.append(BoundArch); @@ -3285,7 +3353,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, if (!types::appendSuffixForType(JA.getType())) End = BaseName.rfind('.'); SmallString<128> Suffixed(BaseName.substr(0, End)); - Suffixed += JA.getOffloadingFileNamePrefix(NormalizedTriple); + Suffixed += OffloadingPrefix; if (MultipleArchs && !BoundArch.empty()) { Suffixed += "-"; Suffixed.append(BoundArch); |