clang 24.0.0git
SYCL.cpp
Go to the documentation of this file.
1//===--- SYCL.cpp - SYCL Tool and ToolChain Implementations -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8#include "SYCL.h"
9#include "SPIRV.h"
11#include "llvm/Support/Path.h"
12#include "llvm/Support/VirtualFileSystem.h"
13
14using namespace clang::driver;
15using namespace clang::driver::toolchains;
16using namespace clang::driver::tools;
17using namespace clang;
18using namespace llvm::opt;
19
21 const Driver &D, const llvm::Triple &HostTriple,
22 const llvm::opt::ArgList &Args)
23 : D(D) {
24 // When -fsycl is active, locate the SYCL runtime library and record its
25 // directory in SYCLRTLibPath for use by the linker.
26 SmallString<128> DriverDir(D.Dir);
27
28 if (HostTriple.isWindowsMSVCEnvironment() ||
29 HostTriple.isWindowsItaniumEnvironment()) {
30 // Windows: Check for LLVMSYCL.lib
31 // NOTE: Only checks for LLVMSYCL.lib existence (release variant).
32 // Debug vs release library selection happens at link time based on CRT
33 // flags.
34 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
35 SmallString<128> LibDir(DriverDir);
36 llvm::sys::path::append(LibDir, "..", "lib");
37
38 // Verify SYCL runtime library exists
39 SmallString<128> SYCLLibPath(LibDir);
40 llvm::sys::path::append(SYCLLibPath, "LLVMSYCL.lib");
41
42 if (D.getVFS().exists(SYCLLibPath))
43 SYCLRTLibPath = LibDir;
44 }
45 } else {
46 // Linux/Unix: Check for libLLVMSYCL.so
47 SmallString<128> LibPath(DriverDir);
48 llvm::sys::path::append(LibPath, "..", "lib", HostTriple.str(),
49 "libLLVMSYCL.so");
50 // Flat lib path for LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF builds,
51 // where the library is installed directly in lib/ with no triple subdir.
52 SmallString<128> FlatLibPath(DriverDir);
53 llvm::sys::path::append(FlatLibPath, "..", "lib", "libLLVMSYCL.so");
54
55 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
56 // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON: library is in lib/<triple>/
57 if (D.getVFS().exists(LibPath))
58 llvm::sys::path::append(DriverDir, "..", "lib", HostTriple.str());
59 // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF: library is in lib/
60 else if (D.getVFS().exists(FlatLibPath))
61 llvm::sys::path::append(DriverDir, "..", "lib");
62 else
63 return; // Neither path exists : broken install, leave SYCLRTLibPath
64 // unset
65
66 SYCLRTLibPath = DriverDir;
67 }
68 }
69}
70
72 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
73 if (DriverArgs.hasArg(options::OPT_nobuiltininc))
74 return;
75
76 // Add the SYCL header search locations.
77 // These are included for both SYCL host and device compilations.
78 SmallString<128> IncludePath(D.Dir);
79 llvm::sys::path::append(IncludePath, "..", "include");
80 CC1Args.push_back("-internal-isystem");
81 CC1Args.push_back(DriverArgs.MakeArgString(IncludePath));
82}
83
84// Unsupported options for SYCL device compilation.
86 static constexpr options::ID UnsupportedOpts[] = {
87 options::OPT_fsanitize_EQ, // -fsanitize
88 options::OPT_fcf_protection_EQ, // -fcf-protection
89 options::OPT_fprofile_generate,
90 options::OPT_fprofile_generate_EQ,
91 options::OPT_fno_profile_generate, // -f[no-]profile-generate
92 options::OPT_ftest_coverage,
93 options::OPT_fno_test_coverage, // -f[no-]test-coverage
94 options::OPT_fcoverage_mapping,
95 options::OPT_fno_coverage_mapping, // -f[no-]coverage-mapping
96 options::OPT_coverage, // --coverage
97 options::OPT_fprofile_instr_generate,
98 options::OPT_fprofile_instr_generate_EQ,
99 options::OPT_fno_profile_instr_generate, // -f[no-]profile-instr-generate
100 options::OPT_fprofile_arcs,
101 options::OPT_fno_profile_arcs, // -f[no-]profile-arcs
102 options::OPT_fcreate_profile, // -fcreate-profile
103 options::OPT_fprofile_instr_use,
104 options::OPT_fprofile_instr_use_EQ, // -fprofile-instr-use
105 options::OPT_fcs_profile_generate, // -fcs-profile-generate
106 options::OPT_fcs_profile_generate_EQ,
107 };
108 return UnsupportedOpts;
109}
110
111SYCLToolChain::SYCLToolChain(const Driver &D, const llvm::Triple &Triple,
112 const ToolChain &HostTC, const ArgList &Args)
113 : ToolChain(D, Triple, Args), HostTC(HostTC),
114 SYCLInstallation(D, Triple, Args) {
115 // Lookup binaries into the driver directory, this is used to discover any
116 // dependent SYCL offload compilation tools.
117 getProgramPaths().push_back(getDriver().Dir);
118
119 // Diagnose unsupported options only once.
120 for (OptSpecifier Opt : getUnsupportedOpts()) {
121 if (const Arg *A = Args.getLastArg(Opt)) {
122 D.Diag(clang::diag::warn_drv_unsupported_option_for_target)
123 << A->getAsString(Args) << getTriple().str();
124 }
125 }
126}
127
129 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
130 BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
131 HostTC.addClangTargetOptions(DriverArgs, CC1Args, BA, DeviceOffloadingKind);
132
133 // Compilations that stop at or before the compile phase (e.g. -E,
134 // -fsyntax-only) emit no IR, so they need no device libraries.
135 if (getDriver().getFinalPhase(DriverArgs) <= phases::Compile)
136 return;
137
138 for (const auto &BCFile :
139 getDeviceLibs(DriverArgs, BA, DeviceOffloadingKind)) {
140 CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
141 : "-mlink-bitcode-file");
142 CC1Args.push_back(DriverArgs.MakeArgStringRef(BCFile.Path));
143 }
144}
145
146llvm::opt::DerivedArgList *
147SYCLToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
148 BoundArch BA,
149 Action::OffloadKind DeviceOffloadKind) const {
150 DerivedArgList *DAL = HostTC.TranslateArgs(Args, BA, DeviceOffloadKind);
151
152 bool IsNewDAL = false;
153 if (!DAL) {
154 DAL = new DerivedArgList(Args.getBaseArgs());
155 IsNewDAL = true;
156 }
157
158 for (Arg *A : Args) {
159 // Filter out any options we do not want to pass along to the device
160 // compilation.
161 auto Opt(A->getOption());
162 bool Unsupported = false;
163 for (OptSpecifier UnsupportedOpt : getUnsupportedOpts()) {
164 if (Opt.matches(UnsupportedOpt)) {
165 if (Opt.getID() == options::OPT_fsanitize_EQ &&
166 A->getValues().size() == 1) {
167 std::string SanitizeVal = A->getValue();
168 if (SanitizeVal == "address") {
169 if (IsNewDAL)
170 DAL->append(A);
171 continue;
172 }
173 }
174 if (!IsNewDAL)
175 DAL->eraseArg(Opt.getID());
176 Unsupported = true;
177 }
178 }
179 if (Unsupported)
180 continue;
181 if (IsNewDAL)
182 DAL->append(A);
183 }
184
185 const OptTable &Opts = getDriver().getOpts();
186 if (BA) {
187 DAL->eraseArg(options::OPT_march_EQ);
188 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
189 BA.ArchName);
190 }
191 return DAL;
192}
193
194void SYCLToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
195 HostTC.addClangWarningOptions(CC1Args);
196}
197
199 // The SPIR-V linker dispatches to clang-sycl-linker for SYCL offloading.
200 return new tools::SPIRV::Linker(*this);
201}
202
204SYCLToolChain::GetCXXStdlibType(const ArgList &Args) const {
205 return HostTC.GetCXXStdlibType(Args);
206}
207
208void SYCLToolChain::addSYCLIncludeArgs(const ArgList &DriverArgs,
209 ArgStringList &CC1Args) const {
210 SYCLInstallation.addSYCLIncludeArgs(DriverArgs, CC1Args);
211}
212
213void SYCLToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
214 ArgStringList &CC1Args) const {
215 HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
216}
217
219 ArgStringList &CC1Args) const {
220 HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
221}
222
224 const ArgList &Args) const {
225 return HostTC.computeMSVCVersion(D, Args);
226}
227
230 const llvm::opt::ArgList &DriverArgs, BoundArch /*BA*/,
231 const Action::OffloadKind /*DeviceOffloadingKind*/) const {
232 if (getTriple().getArch() != llvm::Triple::spirv64)
233 return {};
234 if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
235 true))
236 return {};
237 // Per-target layout: lib/<triple>/libclang_rt.builtins.bc.
238 if (std::optional<std::string> RuntimeDir = getRuntimePath()) {
239 SmallString<128> BCPath(*RuntimeDir);
240 llvm::sys::path::append(BCPath, "libclang_rt.builtins.bc");
241 if (getVFS().exists(BCPath))
242 return {{std::string(BCPath), /*ShouldInternalize=*/true}};
243 }
244 // Flat layout (LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF):
245 // lib/<os>/libclang_rt.builtins-spirv64.bc.
246 SmallString<128> BCPath(HostTC.getCompilerRTPath());
247 llvm::sys::path::append(BCPath, "libclang_rt.builtins-spirv64.bc");
248 if (getVFS().exists(BCPath))
249 return {{std::string(BCPath), /*ShouldInternalize=*/true}};
250 // The builtins only exist if compiler-rt was built for spirv64, so a missing
251 // library is not an error, as with the OpenMP NVPTX and AMDGPU builtins.
252 return {};
253}
static ArrayRef< options::ID > getUnsupportedOpts()
Definition SYCL.cpp:85
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:93
const llvm::opt::OptTable & getOpts() const
Definition Driver.h:406
SYCLInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args)
Definition SYCL.cpp:20
void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Definition SYCL.cpp:71
llvm::Triple::ArchType getArch() const
Definition ToolChain.h:298
const Driver & getDriver() const
Definition ToolChain.h:282
llvm::vfs::FileSystem & getVFS() const
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition ToolChain.cpp:93
path_list & getProgramPaths()
Definition ToolChain.h:325
const llvm::Triple & getTriple() const
Definition ToolChain.h:284
std::optional< std::string > getRuntimePath() const
Tool - Information on a specific compilation tool.
Definition Tool.h:31
VersionTuple computeMSVCVersion(const Driver *D, const llvm::opt::ArgList &Args) const override
On Windows, returns the MSVC compatibility version.
Definition SYCL.cpp:223
Tool * buildLinker() const override
Definition SYCL.cpp:198
void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add arguments to use system-specific SYCL includes.
Definition SYCL.cpp:208
CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override
Definition SYCL.cpp:204
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
Definition SYCL.cpp:218
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition SYCL.cpp:213
SYCLToolChain(const Driver &D, const llvm::Triple &Triple, const ToolChain &HostTC, const llvm::opt::ArgList &Args)
Definition SYCL.cpp:111
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, BoundArch BA, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition SYCL.cpp:147
void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override
Add warning options that need to be passed to cc1 for this target.
Definition SYCL.cpp:194
llvm::SmallVector< BitCodeLibraryInfo, 12 > getDeviceLibs(const llvm::opt::ArgList &Args, BoundArch BA, const Action::OffloadKind DeviceOffloadingKind) const override
Get paths for device libraries.
Definition SYCL.cpp:229
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, BoundArch BA, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition SYCL.cpp:128
Top level wrappers for InstallAPI frontend operations.
Represents a bound architecture for offload / multiple architecture compilation.
llvm::StringRef ArchName