Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5017,6 +5017,9 @@ class OffloadingActionBuilder final {
/// Flag to signal if the user requested device-only compilation.
bool CompileDeviceOnly = false;

/// Flag to signal if the user requested host-only compilation.
bool CompileHostOnly = false;

/// Flag to signal if the user requested the device object to be wrapped.
bool WrapDeviceOnlyBinary = false;

Expand Down Expand Up @@ -5106,7 +5109,10 @@ class OffloadingActionBuilder final {
const InputList &Inputs, OffloadingActionBuilder &OAB)
: DeviceActionBuilder(C, Args, Inputs, Action::OFK_SYCL, OAB),
SYCLInstallation(C.getDriver(), C.getDefaultToolChain().getTriple(),
Args) {}
Args) {
CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
CompileHostOnly = C.getDriver().offloadHostOnly();
}

void pushForeignAction(Action *A) override {
// Accept a foreign action from the CudaActionBuilder for compiling CUDA
Expand Down Expand Up @@ -5159,6 +5165,35 @@ class OffloadingActionBuilder final {
if (SYCLDeviceActions.empty())
return ABRT_Success;

// When performing host only compilations, we need to perform a
// device compilation to create the integration header/footer, but
// we don't need the full device compilation - just syntax checking
// is sufficient to generate the integration files.
if (CompileHostOnly) {
for (auto TargetActionInfo :
llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
Action *&A = std::get<0>(TargetActionInfo);
auto &TargetInfo = std::get<1>(TargetActionInfo);
// Create a syntax-only compile action to generate the integration
// header/footer. This action compiles the source file (not a
// preprocessed file) to allow for proper control of diagnostics
// from system headers. Output type is TY_Nothing since we only
// want the integration header side effect, not a device binary.
Action *CompileAction =
C.MakeAction<CompileJobAction>(A, types::TY_Nothing);
// Add to device dependencies so it gets executed, but TY_Nothing
// means it won't produce output to bundle.
DA.add(*CompileAction, *TargetInfo.TC, TargetInfo.BoundArch,
Action::OFK_SYCL);
}
// Clear device actions so they don't get processed again in
// appendTopLevelActions.
SYCLDeviceActions.clear();
// Host compilation will proceed normally and consume the generated
// integration header/footer files.
return ABRT_Success;
}

Action *DeviceCompilerInput = nullptr;
const DeviceTargetInfo &DevTarget = SYCLTargetInfoList.back();
for (auto TargetActionInfo :
Expand Down Expand Up @@ -5296,6 +5331,15 @@ class OffloadingActionBuilder final {
if (IA->getInputArg().getOption().hasFlag(options::LinkerInput))
return ABRT_Inactive;

if (CompileHostOnly) {
for (auto &TargetInfo : SYCLTargetInfoList) {
(void)TargetInfo;
SYCLDeviceActions.push_back(
C.MakeAction<InputAction>(IA->getInputArg(), IA->getType()));
}
return ABRT_Success;
}

std::string InputName = IA->getInputArg().getAsString(Args);
// Objects will be consumed as part of the partial link step when
// dealing with offload static libraries
Expand Down Expand Up @@ -6699,8 +6743,11 @@ class OffloadingActionBuilder final {
// bundling one in the resulting list. Otherwise, just append the device
// actions. For device only compilation, HostAction is a null pointer,
// therefore only do this when HostAction is not a null pointer.
// For host-only compilation, skip bundling even if device actions exist
// (they're only for integration header generation).
if (CanUseBundler && ShouldUseBundler && HostAction &&
HostAction->getType() != types::TY_Nothing && !OffloadAL.empty()) {
HostAction->getType() != types::TY_Nothing && !OffloadAL.empty() &&
!C.getDriver().offloadHostOnly()) {
// Add the host action to the list in order to create the bundling action.
OffloadAL.push_back(HostAction);

Expand Down
55 changes: 55 additions & 0 deletions clang/test/Driver/sycl-offload-host-only.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
///
/// Tests for -fsycl --offload-host-only with the old offloading model.
///

/// ###########################################################################
/// Test phase output with -ccc-print-phases
// RUN: %clang -fsycl --target=x86_64-unknown-linux-gnu --no-offload-new-driver --offload-host-only -ccc-print-phases -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-PHASES %s

// CHK-PHASES: 0: input, "[[INPUT:.+\.cpp]]", c++, (host-sycl)
// CHK-PHASES: 1: preprocessor, {0}, c++-cpp-output, (host-sycl)
// CHK-PHASES: 2: input, "[[INPUT]]", c++, (device-sycl)
// CHK-PHASES: 3: preprocessor, {2}, c++-cpp-output, (device-sycl)
// CHK-PHASES: 4: compiler, {3}, none, (device-sycl)
// CHK-PHASES: 5: offload, "host-sycl (x86_64-unknown-linux-gnu)" {1}, "device-sycl (spir64-unknown-unknown)" {4}, c++-cpp-output
// CHK-PHASES: 6: compiler, {5}, ir, (host-sycl)
// CHK-PHASES: 7: backend, {6}, assembler, (host-sycl)
// CHK-PHASES: 8: assembler, {7}, object, (host-sycl)

/// ###########################################################################
/// Test that device compile generates integration header/footer, and the host
/// compiler consumes these.
// RUN: %clang -fsycl --target=x86_64-unknown-linux-gnu --no-offload-new-driver --offload-host-only -### -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-INT-HEADER %s

// CHK-INT-HEADER: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown"
// CHK-INT-HEADER-SAME: "-fsycl-is-device"
// CHK-INT-HEADER-SAME: "-fsycl-int-header=[[HEADER:.+\.h]]" "-fsycl-int-footer=[[FOOTER:.+\.h]]"
// CHK-INT-HEADER-SAME: "-fsyntax-only"
// CHK-INT-HEADER: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
// CHK-INT-HEADER-SAME: "-fsycl-is-host"
// CHK-INT-HEADER-SAME: "-include-internal-header" "[[HEADER]]"
// CHK-INT-HEADER-SAME: "-dependency-filter" "[[HEADER]]"
// CHK-INT-HEADER-SAME: "-include-internal-footer" "[[FOOTER]]"
// CHK-INT-HEADER-SAME: "-dependency-filter" "[[FOOTER]]"
// CHK-INT-HEADER-SAME: "-emit-obj"
// CHK-INT-HEADER-SAME: "-o" "{{.*\.o}}"

/// ###########################################################################
/// Test with multiple source files
// RUN: %clang -fsycl --target=x86_64-unknown-linux-gnu --no-offload-new-driver --offload-host-only -### -c %s %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-MULTI %s

// CHK-MULTI: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown"
// CHK-MULTI-SAME: "-fsycl-is-device"
// CHK-MULTI-SAME: "-fsyntax-only"
// CHK-MULTI: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
// CHK-MULTI-SAME: "-fsycl-is-host"
// CHK-MULTI-SAME: "-emit-obj"
// CHK-MULTI: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown"
// CHK-MULTI-SAME: "-fsycl-is-device"
// CHK-MULTI-SAME: "-fsyntax-only"
// CHK-MULTI: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
// CHK-MULTI-SAME: "-fsycl-is-host"
// CHK-MULTI-SAME: "-emit-obj"
Loading