Skip to content

Commit 5bd5c87

Browse files
authored
[Driver][SYCL] Introduce gpu specific device targets for AOT (#6775)
Expands spir64_gen target capabilities with -fsycl by introducing a number of GPU specific targets that can be specified via -fsycl-targets. These targets (intel_gpu_* in format) are a set of reserved values which will correspond to spir64_gen target compilations with implied -device values. Example: -fsycl-targets=intel_gpu_skl - Passes '-device skl' to ocloc - Adds -D__SYCL_TARGET_INTEL_GPU_SKL__ to the device compilation step For each value passed in -fsycl-targets, additional device specific compilations will be performed. When bundling (using -c) the corresponding fat object will be generated with spir64_gen-unknown-unknown-skl to continue to be unique for extraction at a later time.
1 parent 99bdc82 commit 5bd5c87

File tree

6 files changed

+431
-29
lines changed

6 files changed

+431
-29
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,19 @@ static bool addSYCLDefaultTriple(Compilation &C,
802802
return true;
803803
}
804804

805+
// Prefix for Intel GPU specific targets used for -fsycl-targets
806+
constexpr char IntelGPU[] = "intel_gpu_";
807+
808+
static llvm::Optional<StringRef> isIntelGPUTarget(StringRef Target) {
809+
// Handle target specifications that resemble 'intel_gpu_*' here. These are
810+
// 'spir64_gen' based.
811+
if (Target.startswith(IntelGPU)) {
812+
return tools::SYCL::gen::resolveGenDevice(
813+
Target.drop_front(sizeof(IntelGPU) - 1));
814+
}
815+
return llvm::None;
816+
}
817+
805818
void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
806819
InputList &Inputs) {
807820

@@ -1086,8 +1099,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
10861099
<< SYCLForceTarget->getAsString(C.getInputArgs());
10871100

10881101
for (StringRef Val : SYCLTargetsValues->getValues()) {
1102+
StringRef UserTargetName(Val);
1103+
if (auto Device = isIntelGPUTarget(Val)) {
1104+
if (Device->empty()) {
1105+
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1106+
continue;
1107+
}
1108+
UserTargetName = "spir64_gen";
1109+
}
1110+
10891111
llvm::Triple TT(MakeSYCLDeviceTriple(Val));
1090-
if (!isValidSYCLTriple(TT)) {
1112+
if (!isValidSYCLTriple(MakeSYCLDeviceTriple(UserTargetName))) {
10911113
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
10921114
continue;
10931115
}
@@ -1125,7 +1147,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
11251147
// Store the current triple so that we can check for duplicates in
11261148
// the following iterations.
11271149
FoundNormalizedTriples[NormalizedName] = Val;
1128-
UniqueSYCLTriplesVec.push_back(TT);
1150+
UniqueSYCLTriplesVec.push_back(MakeSYCLDeviceTriple(UserTargetName));
11291151
}
11301152
addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
11311153
} else
@@ -3576,8 +3598,16 @@ void Driver::checkForOffloadMismatch(Compilation &C,
35763598
// each target individually.
35773599
SmallVector<StringRef, 4> Targets;
35783600
if (const Arg *A = Args.getLastArg(options::OPT_fsycl_targets_EQ)) {
3579-
for (const char *Val : A->getValues())
3601+
for (StringRef Val : A->getValues()) {
3602+
if (auto ValidDevice = isIntelGPUTarget(Val)) {
3603+
if (!ValidDevice->empty())
3604+
Targets.push_back(Args.MakeArgString(
3605+
C.getDriver().MakeSYCLDeviceTriple("spir64_gen").str() + "-" +
3606+
*ValidDevice));
3607+
continue;
3608+
}
35803609
Targets.push_back(Val);
3610+
}
35813611
} else { // Implied targets
35823612
// No -fsycl-targets given, check based on -fintelfpga or default device
35833613
bool SYCLfpga = C.getInputArgs().hasArg(options::OPT_fintelfpga);
@@ -4722,7 +4752,7 @@ class OffloadingActionBuilder final {
47224752
llvm::function_ref<void(const char *)> Op) {
47234753
for (auto &A : GpuArchList) {
47244754
if (TC->getTriple() == A.first) {
4725-
Op(Args.MakeArgString(A.second));
4755+
Op(A.second ? Args.MakeArgString(A.second) : nullptr);
47264756
return;
47274757
}
47284758
}
@@ -5500,10 +5530,12 @@ class OffloadingActionBuilder final {
55005530
auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
55015531
WrapperInputs, types::TY_Object);
55025532

5503-
if (isSpirvAOT)
5504-
DA.add(*DeviceWrappingAction, *TC, /*BoundArch=*/nullptr,
5533+
if (isSpirvAOT) {
5534+
bool AddBA = (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen &&
5535+
BoundArch != nullptr);
5536+
DA.add(*DeviceWrappingAction, *TC, AddBA ? BoundArch : nullptr,
55055537
Action::OFK_SYCL);
5506-
else
5538+
} else
55075539
withBoundArchForToolChain(TC, [&](const char *BoundArch) {
55085540
DA.add(*DeviceWrappingAction, *TC, BoundArch, Action::OFK_SYCL);
55095541
});
@@ -5675,7 +5707,17 @@ class OffloadingActionBuilder final {
56755707
Arg *SYCLTargetsValues = SYCLTargets ? SYCLTargets : SYCLLinkTargets;
56765708
// Fill SYCLTripleList
56775709
llvm::StringMap<StringRef> FoundNormalizedTriples;
5678-
for (const char *Val : SYCLTargetsValues->getValues()) {
5710+
for (StringRef Val : SYCLTargetsValues->getValues()) {
5711+
StringRef UserTargetName(Val);
5712+
if (auto ValidDevice = isIntelGPUTarget(Val)) {
5713+
if (ValidDevice->empty())
5714+
// Unrecognized, we have already diagnosed this earlier; skip.
5715+
continue;
5716+
// Add the proper -device value to the list.
5717+
GpuArchList.emplace_back(C.getDriver().MakeSYCLDeviceTriple(
5718+
"spir64_gen"), ValidDevice->data());
5719+
UserTargetName = "spir64_gen";
5720+
}
56795721
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
56805722
std::string NormalizedName = TT.normalize();
56815723

@@ -5688,9 +5730,14 @@ class OffloadingActionBuilder final {
56885730
// the following iterations.
56895731
FoundNormalizedTriples[NormalizedName] = Val;
56905732

5691-
SYCLTripleList.push_back(TT);
5733+
SYCLTripleList.push_back(
5734+
C.getDriver().MakeSYCLDeviceTriple(UserTargetName));
56925735
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
56935736
SYCLfpgaTriple = true;
5737+
// For user specified spir64_gen, add an empty device value as a
5738+
// placeholder.
5739+
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
5740+
GpuArchList.emplace_back(TT, nullptr);
56945741
}
56955742

56965743
// Fill GpuArchList, end if there are issues in initializingGpuArchMap
@@ -5705,9 +5752,20 @@ class OffloadingActionBuilder final {
57055752
ToolChains, [&](auto &TC) { return TT == TC->getTriple(); });
57065753
assert(TCIt != ToolChains.end() &&
57075754
"Toolchain was not created for this platform");
5708-
if (!TT.isNVPTX() && !TT.isAMDGCN())
5755+
if (!TT.isNVPTX() && !TT.isAMDGCN()) {
5756+
// When users specify the target as 'intel_gpu_*', the proper
5757+
// triple is 'spir64_gen'. The given string from intel_gpu_*
5758+
// is the target device.
5759+
if (TT.isSPIR() &&
5760+
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
5761+
StringRef Device(GpuArchList[I].second);
5762+
SYCLTargetInfoList.emplace_back(
5763+
*TCIt, Device.empty() ? nullptr : Device.data());
5764+
++I;
5765+
continue;
5766+
}
57095767
SYCLTargetInfoList.emplace_back(*TCIt, nullptr);
5710-
else {
5768+
} else {
57115769
SYCLTargetInfoList.emplace_back(*TCIt, GpuArchList[I].second);
57125770
++I;
57135771
}
@@ -5731,6 +5789,9 @@ class OffloadingActionBuilder final {
57315789
// populate the AOT binary inputs vector.
57325790
SYCLAOTInputs.push_back(std::make_pair(TT, TF));
57335791
ShouldAddDefaultTriple = false;
5792+
// Add an empty entry to the Device list
5793+
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
5794+
GpuArchList.emplace_back(TT, nullptr);
57345795
}
57355796
}
57365797
} else if (HasValidSYCLRuntime) {

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5003,6 +5003,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
50035003

50045004
// Forward -fsycl-default-sub-group-size if in SYCL mode.
50055005
Args.AddLastArg(CmdArgs, options::OPT_fsycl_default_sub_group_size);
5006+
5007+
// Add any predefined macros associated with intel_gpu* type targets
5008+
// passed in with -fsycl-targets
5009+
if (RawTriple.isSPIR() &&
5010+
RawTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
5011+
StringRef Device = JA.getOffloadingArch();
5012+
if (!Device.empty())
5013+
CmdArgs.push_back(Args.MakeArgString(
5014+
Twine("-D") + SYCL::gen::getGenDeviceMacro(Device)));
5015+
}
5016+
if (RawTriple.isSPIR() &&
5017+
RawTriple.getSubArch() == llvm::Triple::SPIRSubArch_x86_64)
5018+
CmdArgs.push_back("-D__SYCL_TARGET_INTEL_X86_64__");
50065019
}
50075020

50085021
if (IsSYCL) {
@@ -9070,7 +9083,7 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
90709083
if (TC.getTriple().getSubArch() == llvm::Triple::NoSubArch) {
90719084
// Only store compile/link opts in the image descriptor for the SPIR-V
90729085
// target; AOT compilation has already been performed otherwise.
9073-
TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs);
9086+
TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs, JA);
90749087
TC.TranslateBackendTargetArgs(TT, TCArgs, BuildArgs);
90759088
createArgString("-compile-opts=");
90769089
BuildArgs.clear();

0 commit comments

Comments
 (0)