-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[Driver][SYCL] Add initial SYCL offload compilation support #117268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
3fdc746
6b937eb
5e63d1e
df928e8
94485ac
e611f4c
a884680
36cd7f0
2279e33
8fb3eba
fbf976a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| #include "ToolChains/PS4CPU.h" | ||
| #include "ToolChains/RISCVToolchain.h" | ||
| #include "ToolChains/SPIRV.h" | ||
| #include "ToolChains/SYCL.h" | ||
| #include "ToolChains/Solaris.h" | ||
| #include "ToolChains/TCE.h" | ||
| #include "ToolChains/UEFI.h" | ||
|
|
@@ -780,6 +781,41 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const { | |
| return RT; | ||
| } | ||
|
|
||
| static const char *getDefaultSYCLArch(Compilation &C) { | ||
|
||
| // If -fsycl is supplied we will assume SPIR-V | ||
| if (C.getDefaultToolChain().getTriple().isArch32Bit()) | ||
| return "spirv32"; | ||
| return "spirv64"; | ||
| } | ||
|
|
||
| static llvm::Triple getSYCLDeviceTriple(StringRef TargetArch) { | ||
| SmallVector<StringRef, 5> SYCLAlias = {"spir", "spir64", "spirv", "spirv32", | ||
| "spirv64"}; | ||
| if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) != | ||
|
||
| SYCLAlias.end()) { | ||
| llvm::Triple TargetTriple; | ||
| TargetTriple.setArchName(TargetArch); | ||
| TargetTriple.setVendor(llvm::Triple::UnknownVendor); | ||
| TargetTriple.setOS(llvm::Triple::UnknownOS); | ||
| return TargetTriple; | ||
| } | ||
| return llvm::Triple(TargetArch); | ||
| } | ||
|
|
||
| static bool addSYCLDefaultTriple(Compilation &C, | ||
| SmallVectorImpl<llvm::Triple> &SYCLTriples) { | ||
| // Check current set of triples to see if the default has already been set. | ||
| for (const auto &SYCLTriple : SYCLTriples) { | ||
| if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch && | ||
| SYCLTriple.isSPIROrSPIRV()) | ||
| return false; | ||
| } | ||
| // Add the default triple as it was not found. | ||
| llvm::Triple DefaultTriple = getSYCLDeviceTriple(getDefaultSYCLArch(C)); | ||
| SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple); | ||
| return true; | ||
| } | ||
|
|
||
| void Driver::CreateOffloadingDeviceToolChains(Compilation &C, | ||
| InputList &Inputs) { | ||
|
|
||
|
|
@@ -841,7 +877,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, | |
| return; | ||
| auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple, | ||
| *HostTC, OFK); | ||
| assert(HIPTC && "Could not create offloading device tool chain."); | ||
| C.addOffloadDeviceToolChain(HIPTC, OFK); | ||
| } | ||
|
|
||
|
|
@@ -993,6 +1028,41 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, | |
| return; | ||
| } | ||
|
|
||
| // | ||
|
||
| // SYCL | ||
| // | ||
| // We need to generate a SYCL toolchain if the user specified -fsycl. | ||
| bool IsSYCL = C.getInputArgs().hasFlag(options::OPT_fsycl, | ||
| options::OPT_fno_sycl, false); | ||
|
|
||
| auto argSYCLIncompatible = [&](OptSpecifier OptId) { | ||
| if (!IsSYCL) | ||
| return; | ||
| if (Arg *IncompatArg = C.getInputArgs().getLastArg(OptId)) | ||
| Diag(clang::diag::err_drv_argument_not_allowed_with) | ||
| << IncompatArg->getSpelling() << "-fsycl"; | ||
| }; | ||
| // -static-libstdc++ is not compatible with -fsycl. | ||
| argSYCLIncompatible(options::OPT_static_libstdcxx); | ||
| // -ffreestanding cannot be used with -fsycl | ||
| argSYCLIncompatible(options::OPT_ffreestanding); | ||
|
|
||
| llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec; | ||
|
|
||
| if (IsSYCL) { | ||
| addSYCLDefaultTriple(C, UniqueSYCLTriplesVec); | ||
|
|
||
| // We'll need to use the SYCL and host triples as the key into | ||
| // getOffloadingDeviceToolChain, because the device toolchains we're | ||
| // going to create will depend on both. | ||
| const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); | ||
| for (const auto &TargetTriple : UniqueSYCLTriplesVec) { | ||
| auto SYCLTC = &getOffloadingDeviceToolChain( | ||
| C.getInputArgs(), TargetTriple, *HostTC, Action::OFK_SYCL); | ||
| C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL); | ||
| } | ||
| } | ||
|
|
||
| // | ||
| // TODO: Add support for other offloading programming models here. | ||
| // | ||
|
|
@@ -4183,6 +4253,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, | |
|
|
||
| bool UseNewOffloadingDriver = | ||
| C.isOffloadingHostKind(Action::OFK_OpenMP) || | ||
| C.isOffloadingHostKind(Action::OFK_SYCL) || | ||
| Args.hasFlag(options::OPT_foffload_via_llvm, | ||
| options::OPT_fno_offload_via_llvm, false) || | ||
| Args.hasFlag(options::OPT_offload_new_driver, | ||
|
|
@@ -4593,6 +4664,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, | |
| Archs.insert(OffloadArchToString(OffloadArch::HIPDefault)); | ||
| else if (Kind == Action::OFK_OpenMP) | ||
| Archs.insert(StringRef()); | ||
| else if (Kind == Action::OFK_SYCL) | ||
| Archs.insert(StringRef()); | ||
| } else { | ||
| Args.ClaimAllArgs(options::OPT_offload_arch_EQ); | ||
| Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ); | ||
|
|
@@ -4617,7 +4690,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C, | |
| OffloadAction::DeviceDependences DDeps; | ||
|
|
||
| const Action::OffloadKind OffloadKinds[] = { | ||
| Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP}; | ||
| Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL}; | ||
|
|
||
| for (Action::OffloadKind Kind : OffloadKinds) { | ||
| SmallVector<const ToolChain *, 2> ToolChains; | ||
|
|
@@ -4654,6 +4727,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C, | |
| if (DeviceActions.empty()) | ||
| return HostAction; | ||
|
|
||
| // FIXME: Do not collapse the host side for Darwin targets with SYCL offload | ||
| // compilations. The toolchain is not properly initialized for the target. | ||
| if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL && | ||
| HostAction->getType() != types::TY_Nothing && | ||
| C.getSingleOffloadToolChain<Action::OFK_Host>() | ||
| ->getTriple() | ||
| .isOSDarwin()) | ||
| HostAction->setCannotBeCollapsedWithNextDependentAction(); | ||
|
|
||
| auto PL = types::getCompilationPhases(*this, Args, InputType); | ||
|
|
||
| for (phases::ID Phase : PL) { | ||
|
|
@@ -4662,6 +4744,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C, | |
| break; | ||
| } | ||
|
|
||
| // Assemble actions are not used for the SYCL device side. Both compile | ||
| // and backend actions are used to generate IR and textual IR if needed. | ||
| if (Kind == Action::OFK_SYCL && Phase == phases::Assemble) | ||
| continue; | ||
|
|
||
| auto TCAndArch = TCAndArchs.begin(); | ||
| for (Action *&A : DeviceActions) { | ||
| if (A->getType() == types::TY_Nothing) | ||
|
|
@@ -4900,6 +4987,7 @@ Action *Driver::ConstructPhaseAction( | |
| return C.MakeAction<BackendJobAction>(Input, Output); | ||
| } | ||
| if (Args.hasArg(options::OPT_emit_llvm) || | ||
| TargetDeviceOffloadKind == Action::OFK_SYCL || | ||
| (((Input->getOffloadingToolChain() && | ||
| Input->getOffloadingToolChain()->getTriple().isAMDGPU()) || | ||
| TargetDeviceOffloadKind == Action::OFK_HIP) && | ||
|
|
@@ -6591,11 +6679,23 @@ const ToolChain &Driver::getOffloadingDeviceToolChain( | |
| HostTC, Args); | ||
| break; | ||
| } | ||
| case Action::OFK_SYCL: | ||
| switch (Target.getArch()) { | ||
|
||
| case llvm::Triple::spir: | ||
| case llvm::Triple::spir64: | ||
| case llvm::Triple::spirv32: | ||
| case llvm::Triple::spirv64: | ||
| TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, HostTC, | ||
| Args); | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
| default: | ||
| break; | ||
tahonermann marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| assert(TC && "Could not create offloading device tool chain."); | ||
| return *TC; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.