Skip to content

Commit

Permalink
[Driver][SYCL] Add support for -fsycl-force-target
Browse files Browse the repository at this point in the history
Introduce -fsycl-force-target=arg support.  This is used along with -fsycl
to allow the user to override the target used to unbundle device objects
from fat objects and archives.

For example, object.o is built from -fsycl-targets=spir64.  The user wants
to build with -fsycl-targets=spir64_gen and object.o.  Use of
-fsycl-force-target=spir64 allows for this to be accomplished.

Additional notes:
  - Only valid when used with a single triple from -fsycl-targets
  - Applies to all unbundled archives and objects
  • Loading branch information
mdtoguchi committed Aug 27, 2022
1 parent 443971c commit fe0259d
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 1 deletion.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ def warn_drv_sycl_offload_target_duplicate : Warning<
def warn_drv_sycl_target_missing : Warning<
"linked binaries do not contain expected '%0' target; found targets: '%1'">,
InGroup<SyclTarget>;
def err_drv_multiple_target_with_forced_target : Error<
"multiple target usage with '%0' is not supported with '%1'">;
def err_drv_failed_to_deduce_target_from_arch : Error<
"failed to deduce triple for target architecture '%0'; specify the triple "
"using '-fopenmp-targets' and '-Xopenmp-target' instead.">;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2848,6 +2848,10 @@ def fsycl_link_targets_EQ : CommaJoined<["-"], "fsycl-link-targets=">,
Flags<[NoXarchOption, CC1Option, CoreOption, Deprecated]>,
HelpText<"Specify comma-separated list of triples SYCL offloading targets "
"to produce linked device images (deprecated)">;
def fsycl_force_target_EQ : Joined<["-"], "fsycl-force-target=">,
Flags<[NoXarchOption, CoreOption]>,
HelpText<"Force the usage of the given triple when extracting device code "
"from any given objects on the command line">;
def fsycl_device_code_split_EQ : Joined<["-"], "fsycl-device-code-split=">,
Flags<[CC1Option, CoreOption]>, HelpText<"Perform SYCL device code split: per_kernel (device code module is "
"created for each SYCL kernel) | per_source (device code module is created for each source (translation unit)) | off (no device code split). | auto (use heuristic to select the best way of splitting device code). "
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ static bool addSYCLDefaultTriple(Compilation &C,
/// Returns true if a triple is added to SYCLTriples, false otherwise
if (!C.getDriver().isSYCLDefaultTripleImplied())
return false;
if (C.getInputArgs().hasArg(options::OPT_fsycl_force_target_EQ))
return false;
for (const auto &SYCLTriple : SYCLTriples) {
if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
SYCLTriple.isSPIR())
Expand Down Expand Up @@ -1057,6 +1059,14 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
C.getInputArgs().getLastArg(options::OPT_fsycl_device_code_split_EQ),
{"per_kernel", "per_source", "auto", "off"});

Arg *SYCLForceTarget =
getArgRequiringSYCLRuntime(options::OPT_fsycl_force_target_EQ);
if (SYCLForceTarget) {
StringRef Val(SYCLForceTarget->getValue());
llvm::Triple TT(MakeSYCLDeviceTriple(Val));
if (!isValidSYCLTriple(TT))
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
}
bool HasSYCLTargetsOption = SYCLTargets || SYCLLinkTargets || SYCLAddTargets;
llvm::StringMap<StringRef> FoundNormalizedTriples;
llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec;
Expand All @@ -1066,6 +1076,15 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
Arg *SYCLTargetsValues = SYCLTargets ? SYCLTargets : SYCLLinkTargets;
if (SYCLTargetsValues) {
if (SYCLTargetsValues->getNumValues()) {

// Multiple targets are currently not supported when using
// -fsycl-force-target as the bundler does not allow for multiple
// outputs of the same target.
if (SYCLForceTarget && SYCLTargetsValues->getNumValues() > 1)
Diag(clang::diag::err_drv_multiple_target_with_forced_target)
<< SYCLTargetsValues->getAsString(C.getInputArgs())
<< SYCLForceTarget->getAsString(C.getInputArgs());

for (StringRef Val : SYCLTargetsValues->getValues()) {
llvm::Triple TT(MakeSYCLDeviceTriple(Val));
if (!isValidSYCLTriple(TT)) {
Expand Down
11 changes: 10 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8916,7 +8916,16 @@ void OffloadBundler::ConstructJobMultipleOutputs(
Triples += ',';
Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind);
Triples += '-';
Triples += Dep.DependentToolChain->getTriple().normalize();
// When -fsycl-force-target is used, this value overrides the expected
// output type we are unbundling.
if (Dep.DependentOffloadKind == Action::OFK_SYCL &&
TCArgs.hasArg(options::OPT_fsycl_force_target_EQ)) {
StringRef Val(
TCArgs.getLastArg(options::OPT_fsycl_force_target_EQ)->getValue());
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
Triples += TT.normalize();
} else
Triples += Dep.DependentToolChain->getTriple().normalize();
if ((Dep.DependentOffloadKind == Action::OFK_HIP ||
Dep.DependentOffloadKind == Action::OFK_OpenMP ||
Dep.DependentOffloadKind == Action::OFK_Cuda ||
Expand Down
26 changes: 26 additions & 0 deletions clang/test/Driver/sycl-force-target.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// Verify the usage of -fsycl-force-target applies to all expected unbundlings
// RUN: touch %t.o
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fsycl-force-target=spir64 \
// RUN: %s --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK_FORCE_TARGET
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen \
// RUN: -fsycl-force-target=spir64-unknown-unknown \
// RUN: %s --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
// RUN: | FileCheck %s -check-prefixes=CHECK_FORCE_TARGET,CHECK_FORCE_TARGET_GEN
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64 \
// RUN: -fsycl-force-target=spir64 %s \
// RUN: --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
// RUN: | FileCheck %s -check-prefixes=CHECK_FORCE_TARGET,CHECK_FORCE_TARGET_CPU
// CHECK_FORCE_TARGET: clang-offload-bundler{{.*}} "-type=o" "-targets=host-{{.*}},sycl-spir64-unknown-unknown" "-input={{.*}}" "-output={{.*}}" "-output=[[DEVICEOBJECTOUT:.+]]" "-unbundle" "-allow-missing-bundles"
// CHECK_FORCE_TARGET: spirv-to-ir-wrapper{{.*}} "[[DEVICEOBJECTOUT]]" "-o" "[[DEVICEOBJECTBC:.+\.bc]]"
// CHECK_FORCE_TARGET: llvm-link{{.*}} "[[DEVICEOBJECTBC]]"{{.*}} "-o" "[[DEVICEOBJLINKED:.+\.bc]]" "--suppress-warnings"
// CHECK_FORCE_TARGET: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown" "-input={{.*}}libsycl-complex{{.*}}" "-output={{.*}}libsycl-complex-{{.*}}" "-unbundle"
// CHECK_FORCE_TARGET_GEN: llvm-foreach{{.*}} {{.*}}ocloc{{.*}}
// CHECK_FORCE_TARGET_CPU: llvm-foreach{{.*}} {{.*}}opencl-aot{{.*}}

/// -fsycl-force-target is only valid with -fsycl-target with single targets
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen,spir64_x86_64 \
// RUN: -fsycl-force-target=spir64 %s -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=MULTIPLE_TARGET
// MULTIPLE_TARGET: error: multiple target usage with '-fsycl-targets=spir64_gen,spir64_x86_64' is not supported with '-fsycl-force-target=spir64'

8 changes: 8 additions & 0 deletions sycl/doc/UsersManual.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ and not recommended to use in production environment.

NOTE: This option is currently only supported on Linux.

**`-fsycl-force-target=<T>`**

When used along with '-fsycl-targets', force the device object being
unbundled to match the <T> given. This allows the user to override the
expected unbundling type even though the target given does not match.
The forced target applies to all objects, archives and default device
libraries.

## Intel FPGA specific options

**`-fintelfpga`**
Expand Down

0 comments on commit fe0259d

Please sign in to comment.