<div dir="ltr">Hi Samuel,<br><br>Looks like this revision introduced warning to one of our builders:<br><a href="http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/67/steps/build-stage3-clang/logs/warnings%20%28830%29">http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/67/steps/build-stage3-clang/logs/warnings%20%28830%29</a><br><br>Please have a look at this?<br><br>Thanks<br><br>Galina<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 27, 2016 at 11:14 AM, Samuel Antao via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: sfantao<br>
Date: Thu Oct 27 13:14:55 2016<br>
New Revision: 285326<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=285326&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=285326&view=rev</a><br>
Log:<br>
[Driver][OpenMP] Add support to create jobs for unbundling actions.<br>
<br>
Summary:<br>
This patch adds the support to create jobs for the `OffloadBundlingAction` which will invoke the `clang-offload-bundler` tool to unbundle input files.<br>
<br>
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.<br>
<br>
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.<br>
<br>
With this patch, it is possible to compile a functional OpenMP binary with offloading support, even with separate compilation.<br>
<br>
Reviewers: echristo, tra, jlebar, ABataev, hfinkel<br>
<br>
Subscribers: mkuron, whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D21857" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D21857</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/<wbr>Driver/Action.h<br>
    cfe/trunk/include/clang/<wbr>Driver/Driver.h<br>
    cfe/trunk/include/clang/<wbr>Driver/Tool.h<br>
    cfe/trunk/lib/Driver/Action.<wbr>cpp<br>
    cfe/trunk/lib/Driver/Driver.<wbr>cpp<br>
    cfe/trunk/lib/Driver/Tool.cpp<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Driver/Tools.h<br>
    cfe/trunk/test/Driver/<a href="http://cuda-bindings.cu" rel="noreferrer" target="_blank">cuda-<wbr>bindings.cu</a><br>
    cfe/trunk/test/Driver/openmp-<wbr>offload.c<br>
    cfe/trunk/test/Driver/opt-<wbr>record.c<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Driver/Action.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Driver/Action.h?rev=<wbr>285326&r1=285325&r2=285326&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Driver/Action.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Driver/Action.h Thu Oct 27 13:14:55 2016<br>
@@ -157,9 +157,12 @@ public:<br>
   /// Return a string containing the offload kind of the action.<br>
   std::string getOffloadingKindPrefix() const;<br>
   /// Return a string that can be used as prefix in order to generate unique<br>
-  /// files for each offloading kind.<br>
-  std::string<br>
-  getOffloadingFileNamePrefix(<wbr>llvm::StringRef NormalizedTriple) const;<br>
+  /// files for each offloading kind. By default, no prefix is used for<br>
+  /// non-device kinds, except if \a CreatePrefixForHost is set.<br>
+  static std::string<br>
+  GetOffloadingFileNamePrefix(<wbr>OffloadKind Kind,<br>
+                              llvm::StringRef NormalizedTriple,<br>
+                              bool CreatePrefixForHost = false);<br>
   /// Return a string containing a offload kind name.<br>
   static StringRef GetOffloadKindName(OffloadKind Kind);<br>
<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Driver/Driver.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Driver/Driver.h?rev=<wbr>285326&r1=285325&r2=285326&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Driver/Driver.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Driver/Driver.h Thu Oct 27 13:14:55 2016<br>
@@ -12,6 +12,7 @@<br>
<br>
 #include "clang/Basic/Diagnostic.h"<br>
 #include "clang/Basic/LLVM.h"<br>
+#include "clang/Driver/Action.h"<br>
 #include "clang/Driver/Phases.h"<br>
 #include "clang/Driver/Types.h"<br>
 #include "clang/Driver/Util.h"<br>
@@ -42,7 +43,6 @@ class FileSystem;<br>
<br>
 namespace driver {<br>
<br>
-  class Action;<br>
   class Command;<br>
   class Compilation;<br>
   class InputInfo;<br>
@@ -417,14 +417,14 @@ public:<br>
<br>
   /// BuildJobsForAction - Construct the jobs to perform for the action \p A and<br>
   /// return an InputInfo for the result of running \p A.  Will only construct<br>
-  /// jobs for a given (Action, ToolChain, BoundArch) tuple once.<br>
+  /// jobs for a given (Action, ToolChain, BoundArch, DeviceKind) tuple once.<br>
   InputInfo<br>
   BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC,<br>
                      StringRef BoundArch, bool AtTopLevel, bool MultipleArchs,<br>
                      const char *LinkingOutput,<br>
                      std::map<std::pair<const Action *, std::string>, InputInfo><br>
                          &CachedResults,<br>
-                     bool BuildForOffloadDevice) const;<br>
+                     Action::OffloadKind TargetDeviceOffloadKind) const;<br>
<br>
   /// Returns the default name for linked images (e.g., "a.out").<br>
   const char *getDefaultImageName() const;<br>
@@ -495,7 +495,7 @@ private:<br>
       bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,<br>
       std::map<std::pair<const Action *, std::string>, InputInfo><br>
           &CachedResults,<br>
-      bool BuildForOffloadDevice) const;<br>
+      Action::OffloadKind TargetDeviceOffloadKind) const;<br>
<br>
 public:<br>
   /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?<wbr>))?)? and<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Driver/Tool.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Tool.h?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Driver/Tool.h?rev=<wbr>285326&r1=285325&r2=285326&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Driver/Tool.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Driver/Tool.h Thu Oct 27 13:14:55 2016<br>
@@ -129,6 +129,20 @@ public:<br>
                             const InputInfoList &Inputs,<br>
                             const llvm::opt::ArgList &TCArgs,<br>
                             const char *LinkingOutput) const = 0;<br>
+  /// Construct jobs to perform the action \p JA, writing to the \p Outputs and<br>
+  /// with \p Inputs, and add the jobs to \p C. The default implementation<br>
+  /// assumes a single output and is expected to be overloaded for the tools<br>
+  /// that support multiple inputs.<br>
+  ///<br>
+  /// \param TCArgs The argument list for this toolchain, with any<br>
+  /// tool chain specific translations applied.<br>
+  /// \param LinkingOutput If this output will eventually feed the<br>
+  /// linker, then this is the final output name of the linked image.<br>
+  virtual void ConstructJob(Compilation &C, const JobAction &JA,<br>
+                            const InputInfoList &Outputs,<br>
+                            const InputInfoList &Inputs,<br>
+                            const llvm::opt::ArgList &TCArgs,<br>
+                            const char *LinkingOutput) const;<br>
 };<br>
<br>
 } // end namespace driver<br>
<br>
Modified: cfe/trunk/lib/Driver/Action.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Action.cpp?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>Action.cpp?rev=285326&r1=<wbr>285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/Action.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Driver/Action.<wbr>cpp Thu Oct 27 13:14:55 2016<br>
@@ -115,15 +115,18 @@ std::string Action::getOffloadingKindPre<br>
   return Res;<br>
 }<br>
<br>
+/// Return a string that can be used as prefix in order to generate unique files<br>
+/// for each offloading kind.<br>
 std::string<br>
-Action::<wbr>getOffloadingFileNamePrefix(<wbr>llvm::StringRef NormalizedTriple) const {<br>
-  // A file prefix is only generated for device actions and consists of the<br>
-  // offload kind and triple.<br>
-  if (!OffloadingDeviceKind)<br>
+Action::<wbr>GetOffloadingFileNamePrefix(<wbr>OffloadKind Kind,<br>
+                                    llvm::StringRef NormalizedTriple,<br>
+                                    bool CreatePrefixForHost) {<br>
+  // Don't generate prefix for host actions unless required.<br>
+  if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host))<br>
     return "";<br>
<br>
   std::string Res("-");<br>
-  Res += getOffloadingKindPrefix();<br>
+  Res += GetOffloadKindName(Kind);<br>
   Res += "-";<br>
   Res += NormalizedTriple;<br>
   return Res;<br>
<br>
Modified: cfe/trunk/lib/Driver/Driver.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>Driver.cpp?rev=285326&r1=<wbr>285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/Driver.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Driver/Driver.<wbr>cpp Thu Oct 27 13:14:55 2016<br>
@@ -2593,7 +2593,7 @@ void Driver::BuildJobs(Compilation &C) c<br>
                        /*AtTopLevel*/ true,<br>
                        /*MultipleArchs*/ ArchNames.size() > 1,<br>
                        /*LinkingOutput*/ LinkingOutput, CachedResults,<br>
-                       /*BuildForOffloadDevice*/ false);<br>
+                       /*TargetDeviceOffloadKind*/ Action::OFK_None);<br>
   }<br>
<br>
   // If the user passed -Qunused-arguments or there were errors, don't warn<br>
@@ -2926,31 +2926,38 @@ public:<br>
 };<br>
 }<br>
<br>
-InputInfo Driver::BuildJobsForAction(<br>
-    Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,<br>
-    bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,<br>
-    std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults,<br>
-    bool BuildForOffloadDevice) const {<br>
-  // The bound arch is not necessarily represented in the toolchain's triple --<br>
-  // for example, armv7 and armv7s both map to the same triple -- so we need<br>
-  // both in our map. Also, we need to add the offloading device kind, as the<br>
-  // same tool chain can be used for host and device for some programming<br>
-  // models, e.g. OpenMP.<br>
+/// Return a string that uniquely identifies the result of a job. The bound arch<br>
+/// is not necessarily represented in the toolchain's triple -- for example,<br>
+/// armv7 and armv7s both map to the same triple -- so we need both in our map.<br>
+/// Also, we need to add the offloading device kind, as the same tool chain can<br>
+/// be used for host and device for some programming models, e.g. OpenMP.<br>
+static std::string GetTriplePlusArchString(const ToolChain *TC,<br>
+                                           StringRef BoundArch,<br>
+                                           Action::OffloadKind OffloadKind) {<br>
   std::string TriplePlusArch = TC->getTriple().normalize();<br>
   if (!BoundArch.empty()) {<br>
     TriplePlusArch += "-";<br>
     TriplePlusArch += BoundArch;<br>
   }<br>
   TriplePlusArch += "-";<br>
-  TriplePlusArch += A->getOffloadingKindPrefix();<br>
-  std::pair<const Action *, std::string> ActionTC = {A, TriplePlusArch};<br>
+  TriplePlusArch += Action::GetOffloadKindName(<wbr>OffloadKind);<br>
+  return TriplePlusArch;<br>
+}<br>
+<br>
+InputInfo Driver::BuildJobsForAction(<br>
+    Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,<br>
+    bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,<br>
+    std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults,<br>
+    Action::OffloadKind TargetDeviceOffloadKind) const {<br>
+  std::pair<const Action *, std::string> ActionTC = {<br>
+      A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};<br>
   auto CachedResult = CachedResults.find(ActionTC);<br>
   if (CachedResult != CachedResults.end()) {<br>
     return CachedResult->second;<br>
   }<br>
   InputInfo Result = BuildJobsForActionNoCache(<br>
       C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,<br>
-      CachedResults, BuildForOffloadDevice);<br>
+      CachedResults, TargetDeviceOffloadKind);<br>
   CachedResults[ActionTC] = Result;<br>
   return Result;<br>
 }<br>
@@ -2959,10 +2966,11 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
     Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,<br>
     bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,<br>
     std::map<std::pair<const Action *, std::string>, InputInfo> &CachedResults,<br>
-    bool BuildForOffloadDevice) const {<br>
+    Action::OffloadKind TargetDeviceOffloadKind) const {<br>
   llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");<br>
<br>
   InputInfoList OffloadDependencesInputInfo;<br>
+  bool BuildingForOffloadDevice = TargetDeviceOffloadKind != Action::OFK_None;<br>
   if (const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {<br>
     // The offload action is expected to be used in four different situations.<br>
     //<br>
@@ -2995,7 +3003,7 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
         DevA =<br>
             BuildJobsForAction(C, DepA, DepTC, DepBoundArch, AtTopLevel,<br>
                                /*MultipleArchs*/ !!DepBoundArch, LinkingOutput,<br>
-                               CachedResults, /*BuildForOffloadDevice=*/<wbr>true);<br>
+                               CachedResults, DepA->getOffloadingDeviceKind(<wbr>));<br>
       });<br>
       return DevA;<br>
     }<br>
@@ -3005,16 +3013,15 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
     // generate the host dependences and override the action with the device<br>
     // dependence. The dependences can't therefore be a top-level action.<br>
     OA->doOnEachDependence(<br>
-        /*IsHostDependence=*/<wbr>BuildForOffloadDevice,<br>
+        /*IsHostDependence=*/<wbr>BuildingForOffloadDevice,<br>
         [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {<br>
           OffloadDependencesInputInfo.<wbr>push_back(BuildJobsForAction(<br>
               C, DepA, DepTC, DepBoundArch, /*AtTopLevel=*/false,<br>
               /*MultipleArchs*/ !!DepBoundArch, LinkingOutput, CachedResults,<br>
-              /*BuildForOffloadDevice=*/<wbr>DepA->getOffloadingDeviceKind(<wbr>) !=<br>
-                  Action::OFK_None));<br>
+              DepA->getOffloadingDeviceKind(<wbr>)));<br>
         });<br>
<br>
-    A = BuildForOffloadDevice<br>
+    A = BuildingForOffloadDevice<br>
             ? OA->getSingleDeviceDependence(<wbr>/*DoNotConsiderHostActions=*/<wbr>true)<br>
             : OA->getHostDependence();<br>
   }<br>
@@ -3044,7 +3051,7 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
<br>
     return BuildJobsForAction(C, *BAA->input_begin(), TC, ArchName, AtTopLevel,<br>
                               MultipleArchs, LinkingOutput, CachedResults,<br>
-                              BuildForOffloadDevice);<br>
+                              TargetDeviceOffloadKind);<br>
   }<br>
<br>
<br>
@@ -3063,13 +3070,12 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
   // need to build jobs for host/device-side inputs it may have held.<br>
   for (const auto *OA : CollapsedOffloadActions)<br>
     cast<OffloadAction>(OA)-><wbr>doOnEachDependence(<br>
-        /*IsHostDependence=*/<wbr>BuildForOffloadDevice,<br>
+        /*IsHostDependence=*/<wbr>BuildingForOffloadDevice,<br>
         [&](Action *DepA, const ToolChain *DepTC, const char *DepBoundArch) {<br>
           OffloadDependencesInputInfo.<wbr>push_back(BuildJobsForAction(<br>
               C, DepA, DepTC, DepBoundArch, /* AtTopLevel */ false,<br>
               /*MultipleArchs=*/!!<wbr>DepBoundArch, LinkingOutput, CachedResults,<br>
-              /*BuildForOffloadDevice=*/<wbr>DepA->getOffloadingDeviceKind(<wbr>) !=<br>
-                  Action::OFK_None));<br>
+              DepA->getOffloadingDeviceKind(<wbr>)));<br>
         });<br>
<br>
   // Only use pipes when there is exactly one input.<br>
@@ -3082,7 +3088,7 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
         AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));<br>
     InputInfos.push_back(<wbr>BuildJobsForAction(<br>
         C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,<br>
-        CachedResults, BuildForOffloadDevice));<br>
+        CachedResults, A->getOffloadingDeviceKind()))<wbr>;<br>
   }<br>
<br>
   // Always use the first input as the base input.<br>
@@ -3114,13 +3120,59 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
<br>
   // Determine the place to write output to, if any.<br>
   InputInfo Result;<br>
-  if (JA->getType() == types::TY_Nothing)<br>
+  InputInfoList UnbundlingResults;<br>
+  if (auto *UA = dyn_cast<<wbr>OffloadUnbundlingJobAction>(<wbr>JA)) {<br>
+    // If we have an unbundling job, we need to create results for all the<br>
+    // outputs. We also update the results cache so that other actions using<br>
+    // this unbundling action can get the right results.<br>
+    for (auto &UI : UA->getDependentActionsInfo()) {<br>
+      assert(UI.DependentOffloadKind != Action::OFK_None &&<br>
+             "Unbundling with no offloading??");<br>
+<br>
+      // Unbundling actions are never at the top level. When we generate the<br>
+      // offloading prefix, we also do that for the host file because the<br>
+      // unbundling action does not change the type of the output which can<br>
+      // cause a overwrite.<br>
+      std::string OffloadingPrefix = Action::<wbr>GetOffloadingFileNamePrefix(<br>
+          UI.DependentOffloadKind,<br>
+          UI.DependentToolChain-><wbr>getTriple().normalize(),<br>
+          /*CreatePrefixForHost=*/true);<br>
+      auto CurI = InputInfo(<br>
+          UA, GetNamedOutputPath(C, *UA, BaseInput, UI.DependentBoundArch,<br>
+                                 /*AtTopLevel=*/false, MultipleArchs,<br>
+                                 OffloadingPrefix),<br>
+          BaseInput);<br>
+      // Save the unbundling result.<br>
+      UnbundlingResults.push_back(<wbr>CurI);<br>
+<br>
+      // Get the unique string identifier for this dependence and cache the<br>
+      // result.<br>
+      CachedResults[{A, GetTriplePlusArchString(<br>
+                            UI.DependentToolChain, UI.DependentBoundArch,<br>
+                            UI.DependentOffloadKind)}] = CurI;<br>
+    }<br>
+<br>
+    // Now that we have all the results generated, select the one that should be<br>
+    // returned for the current depending action.<br>
+    std::pair<const Action *, std::string> ActionTC = {<br>
+        A, GetTriplePlusArchString(TC, BoundArch, TargetDeviceOffloadKind)};<br>
+    assert(CachedResults.find(<wbr>ActionTC) != CachedResults.end() &&<br>
+           "Result does not exist??");<br>
+    Result = CachedResults[ActionTC];<br>
+  } else if (JA->getType() == types::TY_Nothing)<br>
     Result = InputInfo(A, BaseInput);<br>
-  else<br>
+  else {<br>
+    // We only have to generate a prefix for the host if this is not a top-level<br>
+    // action.<br>
+    std::string OffloadingPrefix = Action::<wbr>GetOffloadingFileNamePrefix(<br>
+        A->getOffloadingDeviceKind(), TC->getTriple().normalize(),<br>
+        /*CreatePrefixForHost=*/!!A-><wbr>getOffloadingHostActiveKinds() &&<br>
+            !AtTopLevel);<br>
     Result = InputInfo(A, GetNamedOutputPath(C, *JA, BaseInput, BoundArch,<br>
                                              AtTopLevel, MultipleArchs,<br>
-                                             TC->getTriple().normalize()),<br>
+                                             OffloadingPrefix),<br>
                        BaseInput);<br>
+  }<br>
<br>
   if (CCCPrintBindings && !CCGenDiagnostics) {<br>
     llvm::errs() << "# \"" << T->getToolChain().<wbr>getTripleString() << '"'<br>
@@ -3130,12 +3182,28 @@ InputInfo Driver::BuildJobsForActionNoCa<br>
       if (i + 1 != e)<br>
         llvm::errs() << ", ";<br>
     }<br>
-    llvm::errs() << "], output: " << Result.getAsString() << "\n";<br>
+    if (UnbundlingResults.empty())<br>
+      llvm::errs() << "], output: " << Result.getAsString() << "\n";<br>
+    else {<br>
+      llvm::errs() << "], outputs: [";<br>
+      for (unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {<br>
+        llvm::errs() << UnbundlingResults[i].<wbr>getAsString();<br>
+        if (i + 1 != e)<br>
+          llvm::errs() << ", ";<br>
+      }<br>
+      llvm::errs() << "] \n";<br>
+    }<br>
   } else {<br>
-    T->ConstructJob(<br>
-        C, *JA, Result, InputInfos,<br>
-        C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind())<wbr>,<br>
-        LinkingOutput);<br>
+    if (UnbundlingResults.empty())<br>
+      T->ConstructJob(<br>
+          C, *JA, Result, InputInfos,<br>
+          C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind())<wbr>,<br>
+          LinkingOutput);<br>
+    else<br>
+      T->ConstructJob(<br>
+          C, *JA, UnbundlingResults, InputInfos,<br>
+          C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind())<wbr>,<br>
+          LinkingOutput);<br>
   }<br>
   return Result;<br>
 }<br>
@@ -3182,7 +3250,7 @@ const char *Driver::GetNamedOutputPath(C<br>
                                        const char *BaseInput,<br>
                                        StringRef BoundArch, bool AtTopLevel,<br>
                                        bool MultipleArchs,<br>
-                                       StringRef NormalizedTriple) const {<br>
+                                       StringRef OffloadingPrefix) const {<br>
   llvm::PrettyStackTraceString CrashInfo("Computing output path");<br>
   // Output to a user requested destination?<br>
   if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {<br>
@@ -3268,7 +3336,7 @@ const char *Driver::GetNamedOutputPath(C<br>
           MakeCLOutputFilename(C.<wbr>getArgs(), "", BaseName, types::TY_Image);<br>
     } else {<br>
       SmallString<128> Output(getDefaultImageName());<br>
-      Output += JA.<wbr>getOffloadingFileNamePrefix(<wbr>NormalizedTriple);<br>
+      Output += OffloadingPrefix;<br>
       if (MultipleArchs && !BoundArch.empty()) {<br>
         Output += "-";<br>
         Output.append(BoundArch);<br>
@@ -3285,7 +3353,7 @@ const char *Driver::GetNamedOutputPath(C<br>
     if (!types::appendSuffixForType(<wbr>JA.getType()))<br>
       End = BaseName.rfind('.');<br>
     SmallString<128> Suffixed(BaseName.substr(0, End));<br>
-    Suffixed += JA.<wbr>getOffloadingFileNamePrefix(<wbr>NormalizedTriple);<br>
+    Suffixed += OffloadingPrefix;<br>
     if (MultipleArchs && !BoundArch.empty()) {<br>
       Suffixed += "-";<br>
       Suffixed.append(BoundArch);<br>
<br>
Modified: cfe/trunk/lib/Driver/Tool.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tool.cpp?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>Tool.cpp?rev=285326&r1=285325&<wbr>r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/Tool.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tool.cpp Thu Oct 27 13:14:55 2016<br>
@@ -8,6 +8,7 @@<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
 #include "clang/Driver/Tool.h"<br>
+#include "InputInfo.h"<br>
<br>
 using namespace clang::driver;<br>
<br>
@@ -21,3 +22,12 @@ Tool::Tool(const char *_Name, const char<br>
<br>
 Tool::~Tool() {<br>
 }<br>
+<br>
+void Tool::ConstructJob(Compilation &C, const JobAction &JA,<br>
+                        const InputInfoList &Outputs,<br>
+                        const InputInfoList &Inputs,<br>
+                        const llvm::opt::ArgList &TCArgs,<br>
+                        const char *LinkingOutput) const {<br>
+  assert(Outputs.size() == 1 && "Expected only one output by default!");<br>
+  ConstructJob(C, JA, Outputs.front(), Inputs, TCArgs, LinkingOutput);<br>
+};<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>Tools.cpp?rev=285326&r1=<wbr>285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Oct 27 13:14:55 2016<br>
@@ -6222,7 +6222,8 @@ void Clang::ConstructJob(<wbr>Compilation &C,<br>
         if (!JA.isDeviceOffloading(<wbr>Action::OFK_None) &&<br>
             !JA.isDeviceOffloading(Action:<wbr>:OFK_Host)) {<br>
           llvm::sys::path::replace_<wbr>extension(F, "");<br>
-          F += JA.<wbr>getOffloadingFileNamePrefix(<wbr>Triple.normalize());<br>
+          F += Action::<wbr>GetOffloadingFileNamePrefix(<wbr>JA.getOffloadingDeviceKind(),<br>
+                                                   Triple.normalize());<br>
           F += "-";<br>
           F += JA.getOffloadingArch();<br>
         }<br>
@@ -7058,6 +7059,7 @@ void OffloadBundler::ConstructJob(<wbr>Compil<br>
                                   const InputInfoList &Inputs,<br>
                                   const llvm::opt::ArgList &TCArgs,<br>
                                   const char *LinkingOutput) const {<br>
+  // The version with only one output is expected to refer to a bundling job.<br>
   assert(isa<<wbr>OffloadBundlingJobAction>(JA) && "Expecting bundling job!");<br>
<br>
   // The bundling command looks like this:<br>
@@ -7114,6 +7116,68 @@ void OffloadBundler::ConstructJob(<wbr>Compil<br>
<br>
   // All the inputs are encoded as commands.<br>
   C.addCommand(llvm::make_<wbr>unique<Command>(<br>
+      JA, *this,<br>
+      TCArgs.MakeArgString(<wbr>getToolChain().GetProgramPath(<wbr>getShortName())),<br>
+      CmdArgs, None));<br>
+}<br>
+<br>
+void OffloadBundler::ConstructJob(<wbr>Compilation &C, const JobAction &JA,<br>
+                                  const InputInfoList &Outputs,<br>
+                                  const InputInfoList &Inputs,<br>
+                                  const llvm::opt::ArgList &TCArgs,<br>
+                                  const char *LinkingOutput) const {<br>
+  // The version with multiple outputs is expected to refer to a unbundling job.<br>
+  auto &UA = cast<<wbr>OffloadUnbundlingJobAction>(<wbr>JA);<br>
+<br>
+  // The unbundling command looks like this:<br>
+  // clang-offload-bundler -type=bc<br>
+  //   -targets=host-triple,openmp-<wbr>triple1,openmp-triple2<br>
+  //   -inputs=input_file<br>
+  //   -outputs=unbundle_file_host,<wbr>unbundle_file_tgt1,unbundle_<wbr>file_tgt2"<br>
+  //   -unbundle<br>
+<br>
+  ArgStringList CmdArgs;<br>
+<br>
+  assert(Inputs.size() == 1 && "Expecting to unbundle a single file!");<br>
+  InputInfo Input = Inputs.front();<br>
+<br>
+  // Get the type.<br>
+  CmdArgs.push_back(TCArgs.<wbr>MakeArgString(<br>
+      Twine("-type=") + types::getTypeTempSuffix(<wbr>Input.getType())));<br>
+<br>
+  // Get the targets.<br>
+  SmallString<128> Triples;<br>
+  Triples += "-targets=";<br>
+  auto DepInfo = UA.getDependentActionsInfo();<br>
+  for (unsigned I = 0; I < DepInfo.size(); ++I) {<br>
+    if (I)<br>
+      Triples += ',';<br>
+<br>
+    auto &Dep = DepInfo[I];<br>
+    Triples += Action::GetOffloadKindName(<wbr>Dep.DependentOffloadKind);<br>
+    Triples += '-';<br>
+    Triples += Dep.DependentToolChain-><wbr>getTriple().normalize();<br>
+  }<br>
+<br>
+  CmdArgs.push_back(TCArgs.<wbr>MakeArgString(Triples));<br>
+<br>
+  // Get bundled file command.<br>
+  CmdArgs.push_back(<br>
+      TCArgs.MakeArgString(Twine("-<wbr>inputs=") + Input.getFilename()));<br>
+<br>
+  // Get unbundled files command.<br>
+  SmallString<128> UB;<br>
+  UB += "-outputs=";<br>
+  for (unsigned I = 0; I < Outputs.size(); ++I) {<br>
+    if (I)<br>
+      UB += ',';<br>
+    UB += Outputs[I].getFilename();<br>
+  }<br>
+  CmdArgs.push_back(TCArgs.<wbr>MakeArgString(UB));<br>
+  CmdArgs.push_back("-unbundle")<wbr>;<br>
+<br>
+  // All the inputs are encoded as commands.<br>
+  C.addCommand(llvm::make_<wbr>unique<Command>(<br>
       JA, *this,<br>
       TCArgs.MakeArgString(<wbr>getToolChain().GetProgramPath(<wbr>getShortName())),<br>
       CmdArgs, None));<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>Tools.h?rev=285326&r1=285325&<wbr>r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/Tools.h (original)<br>
+++ cfe/trunk/lib/Driver/Tools.h Thu Oct 27 13:14:55 2016<br>
@@ -148,6 +148,10 @@ public:<br>
                     const InputInfo &Output, const InputInfoList &Inputs,<br>
                     const llvm::opt::ArgList &TCArgs,<br>
                     const char *LinkingOutput) const override;<br>
+  void ConstructJob(Compilation &C, const JobAction &JA,<br>
+                    const InputInfoList &Outputs, const InputInfoList &Inputs,<br>
+                    const llvm::opt::ArgList &TCArgs,<br>
+                    const char *LinkingOutput) const override;<br>
 };<br>
<br>
 /// \brief Base class for all GNU tools that provide the same behavior when<br>
<br>
Modified: cfe/trunk/test/Driver/<a href="http://cuda-bindings.cu" rel="noreferrer" target="_blank">cuda-<wbr>bindings.cu</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cuda-bindings.cu?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Driver/<wbr>cuda-bindings.cu?rev=285326&<wbr>r1=285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Driver/<a href="http://cuda-bindings.cu" rel="noreferrer" target="_blank">cuda-<wbr>bindings.cu</a> (original)<br>
+++ cfe/trunk/test/Driver/<a href="http://cuda-bindings.cu" rel="noreferrer" target="_blank">cuda-<wbr>bindings.cu</a> Thu Oct 27 13:14:55 2016<br>
@@ -34,7 +34,7 @@<br>
 //<br>
 // RUN: %clang -target powerpc64le-ibm-linux-gnu -ccc-print-bindings --cuda-gpu-arch=sm_30 %s -S 2>&1 \<br>
 // RUN: | FileCheck -check-prefix=ASM %s<br>
-// ASM-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.s"<br>
+// ASM-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.s"<br>
 // ASM-DAG: # "powerpc64le-ibm-linux-gnu" - "clang",{{.*}} output: "cuda-bindings.s"<br>
<br>
 //<br>
@@ -62,8 +62,8 @@<br>
 // RUN: %clang -target powerpc64le-ibm-linux-gnu -ccc-print-bindings \<br>
 // RUN:        --cuda-gpu-arch=sm_30 --cuda-gpu-arch=sm_35 %s -S 2>&1 \<br>
 // RUN: | FileCheck -check-prefix=ASM2 %s<br>
-// ASM2-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.s"<br>
-// ASM2-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_35.s"<br>
+// ASM2-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.s"<br>
+// ASM2-DAG: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_35.s"<br>
 // ASM2-DAG: # "powerpc64le-ibm-linux-gnu" - "clang",{{.*}} output: "cuda-bindings.s"<br>
<br>
 //<br>
@@ -101,7 +101,7 @@<br>
 // RUN: | FileCheck -check-prefix=DBIN %s<br>
 // DBIN: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output:<br>
 // DBIN-NOT: cuda-bindings-device-cuda-<wbr>nvptx64<br>
-// DBIN: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.o"<br>
+// DBIN: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.o"<br>
<br>
 //<br>
 // Test single gpu architecture up to the assemble phase in device-only<br>
@@ -110,7 +110,7 @@<br>
 // RUN: %clang -target powerpc64le-ibm-linux-gnu -ccc-print-bindings \<br>
 // RUN:        --cuda-gpu-arch=sm_30 %s --cuda-device-only -S 2>&1 \<br>
 // RUN: | FileCheck -check-prefix=DASM %s<br>
-// DASM: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.s"<br>
+// DASM: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.s"<br>
<br>
 //<br>
 // Test two gpu architectures with complete compilation in device-only<br>
@@ -121,10 +121,10 @@<br>
 // RUN: | FileCheck -check-prefix=DBIN2 %s<br>
 // DBIN2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output:<br>
 // DBIN2-NOT: cuda-bindings-device-cuda-<wbr>nvptx64<br>
-// DBIN2: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.o"<br>
+// DBIN2: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.o"<br>
 // DBIN2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output:<br>
 // DBIN2-NOT: cuda-bindings-device-cuda-<wbr>nvptx64<br>
-// DBIN2: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_35.o"<br>
+// DBIN2: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_35.o"<br>
<br>
 //<br>
 // Test two gpu architectures up to the assemble phase in device-only<br>
@@ -133,5 +133,5 @@<br>
 // RUN: %clang -target powerpc64le-ibm-linux-gnu -ccc-print-bindings \<br>
 // RUN:        --cuda-gpu-arch=sm_30 --cuda-gpu-arch=sm_35 %s --cuda-device-only -S 2>&1 \<br>
 // RUN: | FileCheck -check-prefix=DASM2 %s<br>
-// DASM2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_30.s"<br>
-// DASM2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-device-cuda-<wbr>nvptx64-nvidia-cuda-sm_35.s"<br>
+// DASM2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_30.s"<br>
+// DASM2: # "nvptx64-nvidia-cuda" - "clang",{{.*}} output: "cuda-bindings-cuda-nvptx64-<wbr>nvidia-cuda-sm_35.s"<br>
<br>
Modified: cfe/trunk/test/Driver/openmp-<wbr>offload.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/openmp-offload.c?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Driver/<wbr>openmp-offload.c?rev=285326&<wbr>r1=285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Driver/openmp-<wbr>offload.c (original)<br>
+++ cfe/trunk/test/Driver/openmp-<wbr>offload.c Thu Oct 27 13:14:55 2016<br>
@@ -210,8 +210,8 @@<br>
 // CHK-LKS: TARGET(binary)<br>
 // CHK-LKS-REG: INPUT([[T1BIN:.+\.out]])<br>
 // CHK-LKS-REG: INPUT([[T2BIN:.+\.out]])<br>
-// CHK-LKS-ST: INPUT([[T1BIN:.+\.out-device-<wbr>openmp-powerpc64le-ibm-linux-<wbr>gnu]])<br>
-// CHK-LKS-ST: INPUT([[T2BIN:.+\.out-device-<wbr>openmp-x86_64-pc-linux-gnu]])<br>
+// CHK-LKS-ST: INPUT([[T1BIN:.+\.out-openmp-<wbr>powerpc64le-ibm-linux-gnu]])<br>
+// CHK-LKS-ST: INPUT([[T2BIN:.+\.out-openmp-<wbr>x86_64-pc-linux-gnu]])<br>
 // CHK-LKS: SECTIONS<br>
 // CHK-LKS: {<br>
 // CHK-LKS:   .omp_offloading :<br>
@@ -389,3 +389,92 @@<br>
 // CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"<br>
 // CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "[[HOSTASM]]"<br>
 // CHK-BUJOBS-ST: clang-offload-bundler" "-type=o" "-targets=openmp-powerpc64le-<wbr>ibm-linux-gnu,openmp-x86_64-<wbr>pc-linux-gnu,host-powerpc64le-<wbr>-linux" "-outputs=[[RES:.+\.o]]" "-inputs=[[T1OBJ]],[[T2OBJ]],[<wbr>[HOSTOBJ]]"<br>
+<br>
+/// ##############################<wbr>##############################<wbr>###############<br>
+<br>
+/// Check separate compilation with offloading - unbundling jobs construct<br>
+// RUN:   touch %t.i<br>
+// RUN:   %clang -###  -fopenmp -o %t.out -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.i 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBJOBS %s<br>
+// RUN:   %clang -### -fopenmp -o %t.out -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.i -save-temps 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBJOBS-ST %s<br>
+// RUN:   touch %t.o<br>
+// RUN:   %clang -###  -fopenmp -o %t.out -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.o 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBJOBS2 %s<br>
+// RUN:   %clang -### -fopenmp -o %t.out -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.o -save-temps 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBJOBS2-ST %s<br>
+<br>
+// Unbundle and create host BC.<br>
+// CHK-UBJOBS: clang-offload-bundler" "-type=i" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.i]]" "-outputs=[[HOSTPP:.+\.i]],[[<wbr>T1PP:.+\.i]],[[T2PP:.+\.i]]" "-unbundle"<br>
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc"  {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "cpp-output" "[[HOSTPP]]" "-fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu"<br>
+// CHK-UBJOBS-ST: clang-offload-bundler" "-type=i" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.i]]" "-outputs=[[HOSTPP:.+\.i]],[[<wbr>T1PP:.+\.i]],[[T2PP:.+\.i]]" "-unbundle"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc"  {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "cpp-output" "[[HOSTPP]]" "-fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu"<br>
+<br>
+// Create target 1 object.<br>
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBJOBS: ld" {{.*}}"-o" "[[T1BIN:.+\.out]]" {{.*}}"[[T1OBJ]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1BC:.+\.bc]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1ASM:.+\.s]]" "-x" "ir" "[[T1BC]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "[[T1ASM]]"<br>
+// CHK-UBJOBS-ST: ld" {{.*}}"-o" "[[T1BIN:.+\.out-openmp-<wbr>powerpc64le-ibm-linux-gnu]]" {{.*}}"[[T1OBJ]]"<br>
+<br>
+// Create target 2 object.<br>
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBJOBS: ld" {{.*}}"-o" "[[T2BIN:.+\.out]]" {{.*}}"[[T2OBJ]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2BC:.+\.bc]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2ASM:.+\.s]]" "-x" "ir" "[[T2BC]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "[[T2ASM]]"<br>
+// CHK-UBJOBS-ST: ld" {{.*}}"-o" "[[T2BIN:.+\.out-openmp-x86_<wbr>64-pc-linux-gnu]]" {{.*}}"[[T2OBJ]]"<br>
+<br>
+// Create binary.<br>
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "-x" "ir" "[[HOSTBC]]"<br>
+// CHK-UBJOBS: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"[[HOSTOBJ]]" {{.*}}"-T" "[[LKS:.+\.lk]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"<br>
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "[[HOSTASM]]"<br>
+// CHK-UBJOBS-ST: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"[[HOSTOBJ]]" {{.*}}"-T" "[[LKS:.+\.lk]]"<br>
+<br>
+// Unbundle object file.<br>
+// CHK-UBJOBS2: clang-offload-bundler" "-type=o" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.o]]" "-outputs=[[HOSTOBJ:.+\.o]],[[<wbr>T1OBJ:.+\.o]],[[T2OBJ:.+\.o]]" "-unbundle"<br>
+// CHK-UBJOBS2: ld" {{.*}}"-o" "[[T1BIN:.+\.out]]" {{.*}}"[[T1OBJ]]"<br>
+// CHK-UBJOBS2: ld" {{.*}}"-o" "[[T2BIN:.+\.out]]" {{.*}}"[[T2OBJ]]"<br>
+// CHK-UBJOBS2: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"[[HOSTOBJ]]" {{.*}}"-T" "[[LKS:.+\.lk]]"<br>
+// CHK-UBJOBS2-ST: clang-offload-bundler" "-type=o" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.o]]" "-outputs=[[HOSTOBJ:.+\.o]],[[<wbr>T1OBJ:.+\.o]],[[T2OBJ:.+\.o]]" "-unbundle"<br>
+// CHK-UBJOBS2-ST: ld" {{.*}}"-o" "[[T1BIN:.+\.out-openmp-<wbr>powerpc64le-ibm-linux-gnu]]" {{.*}}"[[T1OBJ]]"<br>
+// CHK-UBJOBS2-ST: ld" {{.*}}"-o" "[[T2BIN:.+\.out-openmp-x86_<wbr>64-pc-linux-gnu]]" {{.*}}"[[T2OBJ]]"<br>
+// CHK-UBJOBS2-ST: ld" {{.*}}"-o" "[[HOSTBIN:.+\.out]]" {{.*}}"[[HOSTOBJ]]" {{.*}}"-T" "[[LKS:.+\.lk]]"<br>
+<br>
+/// ##############################<wbr>##############################<wbr>###############<br>
+<br>
+/// Check separate compilation with offloading - unbundling/bundling jobs<br>
+/// construct<br>
+// RUN:   touch %t.i<br>
+// RUN:   %clang -### -fopenmp -c %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.i 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBUJOBS %s<br>
+// RUN:   %clang -### -fopenmp -c %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu %t.i -save-temps 2>&1 \<br>
+// RUN:   | FileCheck -check-prefix=CHK-UBUJOBS-ST %s<br>
+<br>
+// Unbundle and create host BC.<br>
+// CHK-UBUJOBS: clang-offload-bundler" "-type=i" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.i]]" "-outputs=[[HOSTPP:.+\.i]],[[<wbr>T1PP:.+\.i]],[[T2PP:.+\.i]]" "-unbundle"<br>
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc"  {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "cpp-output" "[[HOSTPP]]" "-fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu"<br>
+<br>
+// CHK-UBUJOBS-ST: clang-offload-bundler" "-type=i" "-targets=host-powerpc64le--<wbr>linux,openmp-powerpc64le-ibm-<wbr>linux-gnu,openmp-x86_64-pc-<wbr>linux-gnu" "-inputs=[[INPUT:.+\.i]]" "-outputs=[[HOSTPP:.+\.i]],[[<wbr>T1PP:.+\.i]],[[T2PP:.+\.i]]" "-unbundle"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-llvm-bc"  {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTBC:.+\.bc]]" "-x" "cpp-output" "[[HOSTPP]]" "-fopenmp-targets=powerpc64le-<wbr>ibm-linux-gnu,x86_64-pc-linux-<wbr>gnu"<br>
+<br>
+// Create target 1 object.<br>
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1BC:.+\.bc]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1ASM:.+\.s]]" "-x" "ir" "[[T1BC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "[[T1ASM]]"<br>
+<br>
+// Create target 2 object.<br>
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2BC:.+\.bc]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2ASM:.+\.s]]" "-x" "ir" "[[T2BC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "[[T2ASM]]"<br>
+<br>
+// Create binary.<br>
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "-x" "ir" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS: clang-offload-bundler" "-type=o" "-targets=openmp-powerpc64le-<wbr>ibm-linux-gnu,openmp-x86_64-<wbr>pc-linux-gnu,host-powerpc64le-<wbr>-linux" "-outputs=[[RES:.+\.o]]" "-inputs=[[T1OBJ]],[[T2OBJ]],[<wbr>[HOSTOBJ]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le--linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[HOSTASM:.+\.s]]" "-x" "ir" "[[HOSTBC]]"<br>
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le--linux" "-filetype" "obj" {{.*}}"-o" "[[HOSTOBJ:.+\.o]]" "[[HOSTASM]]"<br>
+// CHK-UBUJOBS-ST: clang-offload-bundler" "-type=o" "-targets=openmp-powerpc64le-<wbr>ibm-linux-gnu,openmp-x86_64-<wbr>pc-linux-gnu,host-powerpc64le-<wbr>-linux" "-outputs=[[RES:.+\.o]]" "-inputs=[[T1OBJ]],[[T2OBJ]],[<wbr>[HOSTOBJ]]"<br>
<br>
Modified: cfe/trunk/test/Driver/opt-<wbr>record.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/opt-record.c?rev=285326&r1=285325&r2=285326&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Driver/<wbr>opt-record.c?rev=285326&r1=<wbr>285325&r2=285326&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Driver/opt-<wbr>record.c (original)<br>
+++ cfe/trunk/test/Driver/opt-<wbr>record.c Thu Oct 27 13:14:55 2016<br>
@@ -11,7 +11,7 @@<br>
<br>
 // CHECK-NO-O: "-cc1"<br>
 // CHECK-NO-O-DAG: "-opt-record-file" "opt-record.opt.yaml"<br>
-// CHECK-CUDA-DEV-DAG: "-opt-record-file" "opt-record-device-cuda-{{<wbr>nvptx64|nvptx}}-nvidia-cuda-<wbr>sm_20.opt.yaml"<br>
+// CHECK-CUDA-DEV-DAG: "-opt-record-file" "opt-record-cuda-{{nvptx64|<wbr>nvptx}}-nvidia-cuda-sm_20.opt.<wbr>yaml"<br>
<br>
 // CHECK-EQ: "-cc1"<br>
 // CHECK-EQ: "-opt-record-file" "BAR.txt"<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>