sfantao created this revision.
sfantao added reviewers: echristo, tra, jlebar, hfinkel, ABataev.
sfantao added subscribers: caomhin, carlo.bertolli, arpith-jacob, 
andreybokhanko, Hahnfeld, cfe-commits.
Herald added a subscriber: mehdi_amini.

Each time that offloading support is requested by the user and the input file 
is not a source file, an action `OffloadUnbundlingAction` is created to signal 
that the input file may contain bundles, so that the proper tool is then 
invoked to attempt to extract the components of the bundle. This patch adds the 
logic to create that action in offload action builder.

The job creation for the new action will be proposed in a separate patch.

http://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
@@ -255,4 +255,57 @@
 // CHK-BUACTIONS: 16: offload, "device-openmp (x86_64-pc-linux-gnu)" {15}, object
 // 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)
\ No newline at end of file
+// 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
@@ -153,6 +153,10 @@
   }
 }
 
+bool types::isSrcFile(ID Id) {
+  return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
+}
+
 types::ID types::lookupTypeForExtension(const char *Ext) {
   return llvm::StringSwitch<types::ID>(Ext)
            .Case("c", TY_C)
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -264,6 +264,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
@@ -1833,6 +1833,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->registerDependingActionInfo(ToolChains[I], /*BoundArch=*/nullptr,
+                                          Action::OFK_OpenMP);
+        }
+        return ABRT_Success;
+      }
+
       // When generating code for OpenMP we use the host compile phase result as
       // dependence to the device compile phase so that it can learn what
       // declaration should be emitted. However, this is not the only use for
@@ -2021,13 +2032,28 @@
   }
 
   /// \brief 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
+  /// The results will be kept in this action builder. This method will replace
+  /// the host action if a unbundling action is legal. 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.
+    if (CanUseBundler && isa<InputAction>(HostAction) &&
+        InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
+        !types::isSrcFile(HostAction->getType())) {
+      auto UnbundlingHostAction =
+          C.MakeAction<OffloadUnbundlingJobAction>(HostAction);
+      UnbundlingHostAction->registerDependingActionInfo(
+          C.getSingleOffloadToolChain<Action::OFK_Host>(),
+          /*BoundArch=*/nullptr, 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??");
@@ -347,3 +352,7 @@
 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
@@ -72,6 +72,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 the first
+  /// compilation phase is a preprocessor one.
+  bool isSrcFile(ID Id);
+
   /// lookupTypeForExtension - Lookup the type to use for the file
   /// extension \p Ext.
   ID lookupTypeForExtension(const char *Ext);
Index: include/clang/Driver/Action.h
===================================================================
--- include/clang/Driver/Action.h
+++ include/clang/Driver/Action.h
@@ -66,9 +66,10 @@
     VerifyDebugInfoJobClass,
     VerifyPCHJobClass,
     OffloadBundlingJobClass,
+    OffloadUnbundlingJobClass,
 
     JobClassFirst = PreprocessJobClass,
-    JobClassLast = OffloadBundlingJobClass
+    JobClassLast = OffloadUnbundlingJobClass
   };
 
   // The offloading kind determines if this action is binded to a particular
@@ -489,6 +490,45 @@
   }
 };
 
+class OffloadUnbundlingJobAction : public JobAction {
+  void anchor() override;
+
+public:
+  /// \brief Type that provides information about the actions that depend on
+  /// this unbundling action.
+  struct DependingActionInfoTy {
+    /// \brief The tool chain of the depending action.
+    const ToolChain *DependingToolChain;
+    /// \brief The bound architecture of the depending action.
+    const char *DependingBoundArch;
+    /// \brief The offload kind of the depending action.
+    const OffloadKind DependingOffloadKind;
+  };
+
+private:
+  /// \brief Constainer that kepps information about each dependence of this
+  /// unbundling action.
+  SmallVector<DependingActionInfoTy, 6> DependingActionInfo;
+
+public:
+  // Offloading unbundling doesn't change the type of output.
+  OffloadUnbundlingJobAction(Action *Input);
+
+  /// \brief Register information about a depending action.
+  void registerDependingActionInfo(const ToolChain *TC, const char *BoundArch,
+                                   OffloadKind Kind) {
+    DependingActionInfo.push_back({TC, BoundArch, Kind});
+  }
+
+  /// \brief Return the information about all depending actions.
+  ArrayRef<DependingActionInfoTy> getDependingActionsInfo() const {
+    return DependingActionInfo;
+  }
+
+  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