sfantao updated this revision to Diff 76064.
sfantao marked an inline comment as done.
sfantao added a comment.

- Add comment explaing that the bundler tool can detect if the input file is a 
bundle or not.


https://reviews.llvm.org/D21853

Files:
  include/clang/Driver/Action.h
  include/clang/Driver/Types.h
  lib/Driver/Action.cpp
  lib/Driver/Driver.cpp
  lib/Driver/ToolChain.cpp
  lib/Driver/Types.cpp
  test/Driver/openmp-offload.c

Index: test/Driver/openmp-offload.c
===================================================================
--- test/Driver/openmp-offload.c
+++ test/Driver/openmp-offload.c
@@ -302,3 +302,56 @@
 // CHK-BUACTIONS: 17: backend, {2}, assembler, (host-openmp)
 // CHK-BUACTIONS: 18: assembler, {17}, object, (host-openmp)
 // CHK-BUACTIONS: 19: clang-offload-bundler, {9, 16, 18}, object, (host-openmp)
+
+/// ###########################################################################
+
+/// Check separate compilation with offloading - unbundling actions
+// RUN:   touch %t.i
+// RUN:   %clang -### -ccc-print-phases -fopenmp -o %t.out -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %t.i 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHK-UBACTIONS %s
+
+// CHK-UBACTIONS: 0: input, "somelib", object, (host-openmp)
+// CHK-UBACTIONS: 1: input, "[[INPUT:.+\.i]]", cpp-output, (host-openmp)
+// CHK-UBACTIONS: 2: clang-offload-unbundler, {1}, cpp-output, (host-openmp)
+// CHK-UBACTIONS: 3: compiler, {2}, ir, (host-openmp)
+// CHK-UBACTIONS: 4: backend, {3}, assembler, (host-openmp)
+// CHK-UBACTIONS: 5: assembler, {4}, object, (host-openmp)
+// CHK-UBACTIONS: 6: linker, {0, 5}, image, (host-openmp)
+// CHK-UBACTIONS: 7: input, "somelib", object, (device-openmp)
+// CHK-UBACTIONS: 8: compiler, {2}, ir, (device-openmp)
+// CHK-UBACTIONS: 9: offload, "host-openmp (powerpc64le--linux)" {3}, "device-openmp (powerpc64le-ibm-linux-gnu)" {8}, ir
+// CHK-UBACTIONS: 10: backend, {9}, assembler, (device-openmp)
+// CHK-UBACTIONS: 11: assembler, {10}, object, (device-openmp)
+// CHK-UBACTIONS: 12: linker, {7, 11}, image, (device-openmp)
+// CHK-UBACTIONS: 13: input, "somelib", object, (device-openmp)
+// CHK-UBACTIONS: 14: compiler, {2}, ir, (device-openmp)
+// CHK-UBACTIONS: 15: offload, "host-openmp (powerpc64le--linux)" {3}, "device-openmp (x86_64-pc-linux-gnu)" {14}, ir
+// CHK-UBACTIONS: 16: backend, {15}, assembler, (device-openmp)
+// CHK-UBACTIONS: 17: assembler, {16}, object, (device-openmp)
+// CHK-UBACTIONS: 18: linker, {13, 17}, image, (device-openmp)
+// CHK-UBACTIONS: 19: offload, "host-openmp (powerpc64le--linux)" {6}, "device-openmp (powerpc64le-ibm-linux-gnu)" {12}, "device-openmp (x86_64-pc-linux-gnu)" {18}, image
+
+/// ###########################################################################
+
+/// Check separate compilation with offloading - unbundling/bundling actions
+// RUN:   touch %t.i
+// RUN:   %clang -### -ccc-print-phases -fopenmp -c -o %t.o -lsomelib -target powerpc64le-linux -fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu %t.i 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHK-UBUACTIONS %s
+
+// CHK-UBUACTIONS: 0: input, "[[INPUT:.+\.i]]", cpp-output, (host-openmp)
+// CHK-UBUACTIONS: 1: clang-offload-unbundler, {0}, cpp-output, (host-openmp)
+// CHK-UBUACTIONS: 2: compiler, {1}, ir, (host-openmp)
+// CHK-UBUACTIONS: 3: compiler, {1}, ir, (device-openmp)
+// CHK-UBUACTIONS: 4: offload, "host-openmp (powerpc64le--linux)" {2}, "device-openmp (powerpc64le-ibm-linux-gnu)" {3}, ir
+// CHK-UBUACTIONS: 5: backend, {4}, assembler, (device-openmp)
+// CHK-UBUACTIONS: 6: assembler, {5}, object, (device-openmp)
+// CHK-UBUACTIONS: 7: offload, "device-openmp (powerpc64le-ibm-linux-gnu)" {6}, object
+// CHK-UBUACTIONS: 8: compiler, {1}, ir, (device-openmp)
+// CHK-UBUACTIONS: 9: offload, "host-openmp (powerpc64le--linux)" {2}, "device-openmp (x86_64-pc-linux-gnu)" {8}, ir
+// CHK-UBUACTIONS: 10: backend, {9}, assembler, (device-openmp)
+// CHK-UBUACTIONS: 11: assembler, {10}, object, (device-openmp)
+// CHK-UBUACTIONS: 12: offload, "device-openmp (x86_64-pc-linux-gnu)" {11}, object
+// CHK-UBUACTIONS: 13: backend, {2}, assembler, (host-openmp)
+// CHK-UBUACTIONS: 14: assembler, {13}, object, (host-openmp)
+// CHK-UBUACTIONS: 15: clang-offload-bundler, {7, 12, 14}, object, (host-openmp)
+
Index: lib/Driver/Types.cpp
===================================================================
--- lib/Driver/Types.cpp
+++ lib/Driver/Types.cpp
@@ -170,6 +170,10 @@
   }
 }
 
+bool types::isSrcFile(ID Id) {
+  return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
+}
+
 types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
   return llvm::StringSwitch<types::ID>(Ext)
            .Case("c", TY_C)
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -265,6 +265,7 @@
     return getClang();
 
   case Action::OffloadBundlingJobClass:
+  case Action::OffloadUnbundlingJobClass:
     // FIXME: Add a tool for the bundling actions.
     return nullptr;
   }
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -1891,6 +1891,17 @@
         return ABRT_Success;
       }
 
+      // If this is an unbundling action use it as is for each OpenMP toolchain.
+      if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
+        OpenMPDeviceActions.clear();
+        for (unsigned I = 0; I < ToolChains.size(); ++I) {
+          OpenMPDeviceActions.push_back(UA);
+          UA->registerDependentActionInfo(
+              ToolChains[I], /*BoundArch=*/StringRef(), Action::OFK_OpenMP);
+        }
+        return ABRT_Success;
+      }
+
       // When generating code for OpenMP we use the host compile phase result as
       // a dependence to the device compile phase so that it can learn what
       // declarations should be emitted. However, this is not the only use for
@@ -2081,11 +2092,28 @@
   /// Generate an action that adds a host dependence to a device action. The
   /// results will be kept in this action builder. Return true if an error was
   /// found.
-  bool addHostDependenceToDeviceActions(Action *HostAction,
+  bool addHostDependenceToDeviceActions(Action *&HostAction,
                                         const Arg *InputArg) {
     if (!IsValid)
       return true;
 
+    // If we are supporting bundling/unbundling and the current action is an
+    // input action of non-source file, we replace the host action by the
+    // unbundling action. The bundler tool has the logic to detect if an input
+    // is a bundle or not and if the input is not a bundle it assumes it is a
+    // host file. Therefore it is safe to create an unbundling action even if
+    // the input is not a bundle.
+    if (CanUseBundler && isa<InputAction>(HostAction) &&
+        InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
+        !types::isSrcFile(HostAction->getType())) {
+      auto UnbundlingHostAction =
+          C.MakeAction<OffloadUnbundlingJobAction>(HostAction);
+      UnbundlingHostAction->registerDependentActionInfo(
+          C.getSingleOffloadToolChain<Action::OFK_Host>(),
+          /*BoundArch=*/StringRef(), Action::OFK_Host);
+      HostAction = UnbundlingHostAction;
+    }
+
     assert(HostAction && "Invalid host action!");
 
     // Register the offload kinds that are used.
Index: lib/Driver/Action.cpp
===================================================================
--- lib/Driver/Action.cpp
+++ lib/Driver/Action.cpp
@@ -38,6 +38,8 @@
   case VerifyPCHJobClass: return "verify-pch";
   case OffloadBundlingJobClass:
     return "clang-offload-bundler";
+  case OffloadUnbundlingJobClass:
+    return "clang-offload-unbundler";
   }
 
   llvm_unreachable("invalid class");
@@ -47,6 +49,9 @@
   // Offload action set its own kinds on their dependences.
   if (Kind == OffloadClass)
     return;
+  // Unbundling actions use the host kinds.
+  if (Kind == OffloadUnbundlingJobClass)
+    return;
 
   assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) &&
          "Setting device kind to a different device??");
@@ -353,3 +358,8 @@
 
 OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs)
     : JobAction(OffloadBundlingJobClass, Inputs, Inputs.front()->getType()) {}
+
+void OffloadUnbundlingJobAction::anchor() {}
+
+OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input)
+    : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {}
Index: include/clang/Driver/Types.h
===================================================================
--- include/clang/Driver/Types.h
+++ include/clang/Driver/Types.h
@@ -80,6 +80,11 @@
   /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
   bool isObjC(ID Id);
 
+  /// isSrcFile - Is this a source file, i.e. something that still has to be
+  /// preprocessed. The logic behind this is the same that decides if the first
+  /// compilation phase is a preprocessing one.
+  bool isSrcFile(ID Id);
+
   /// lookupTypeForExtension - Lookup the type to use for the file
   /// extension \p Ext.
   ID lookupTypeForExtension(llvm::StringRef Ext);
Index: include/clang/Driver/Action.h
===================================================================
--- include/clang/Driver/Action.h
+++ include/clang/Driver/Action.h
@@ -67,9 +67,10 @@
     VerifyDebugInfoJobClass,
     VerifyPCHJobClass,
     OffloadBundlingJobClass,
+    OffloadUnbundlingJobClass,
 
     JobClassFirst = PreprocessJobClass,
-    JobClassLast = OffloadBundlingJobClass
+    JobClassLast = OffloadUnbundlingJobClass
   };
 
   // The offloading kind determines if this action is binded to a particular
@@ -494,6 +495,52 @@
   }
 };
 
+class OffloadUnbundlingJobAction final : public JobAction {
+  void anchor() override;
+
+public:
+  /// Type that provides information about the actions that depend on this
+  /// unbundling action.
+  struct DependentActionInfo final {
+    /// \brief The tool chain of the dependent action.
+    const ToolChain *DependentToolChain = nullptr;
+    /// \brief The bound architecture of the dependent action.
+    StringRef DependentBoundArch;
+    /// \brief The offload kind of the dependent action.
+    const OffloadKind DependentOffloadKind = OFK_None;
+    DependentActionInfo(const ToolChain *DependentToolChain,
+                        StringRef DependentBoundArch,
+                        const OffloadKind DependentOffloadKind)
+        : DependentToolChain(DependentToolChain),
+          DependentBoundArch(DependentBoundArch),
+          DependentOffloadKind(DependentOffloadKind){};
+  };
+
+private:
+  /// Container that keeps information about each dependence of this unbundling
+  /// action.
+  SmallVector<DependentActionInfo, 6> DependentActionInfoArray;
+
+public:
+  // Offloading unbundling doesn't change the type of output.
+  OffloadUnbundlingJobAction(Action *Input);
+
+  /// Register information about a dependent action.
+  void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch,
+                                   OffloadKind Kind) {
+    DependentActionInfoArray.push_back({TC, BoundArch, Kind});
+  }
+
+  /// Return the information about all depending actions.
+  ArrayRef<DependentActionInfo> getDependentActionsInfo() const {
+    return DependentActionInfoArray;
+  }
+
+  static bool classof(const Action *A) {
+    return A->getKind() == OffloadUnbundlingJobClass;
+  }
+};
+
 } // end namespace driver
 } // end namespace clang
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to