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 "clang/Driver/CommonArgs.h" |
10 | |
11 | using namespace clang::driver; |
12 | using namespace clang::driver::toolchains; |
13 | using namespace clang::driver::tools; |
14 | using namespace clang; |
15 | using namespace llvm::opt; |
16 | |
17 | SYCLInstallationDetector::SYCLInstallationDetector( |
18 | const Driver &D, const llvm::Triple &HostTriple, |
19 | const llvm::opt::ArgList &Args) {} |
20 | |
21 | void SYCLInstallationDetector::addSYCLIncludeArgs( |
22 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
23 | if (DriverArgs.hasArg(Ids: clang::driver::options::OPT_nobuiltininc)) |
24 | return; |
25 | |
26 | // Add the SYCL header search locations in the specified order. |
27 | // FIXME: Add the header file locations once the SYCL library and headers |
28 | // are properly established within the build. |
29 | } |
30 | |
31 | // Unsupported options for SYCL device compilation. |
32 | static ArrayRef<options::ID> getUnsupportedOpts() { |
33 | static constexpr options::ID UnsupportedOpts[] = { |
34 | options::OPT_fsanitize_EQ, // -fsanitize |
35 | options::OPT_fcf_protection_EQ, // -fcf-protection |
36 | options::OPT_fprofile_generate, |
37 | options::OPT_fprofile_generate_EQ, |
38 | options::OPT_fno_profile_generate, // -f[no-]profile-generate |
39 | options::OPT_ftest_coverage, |
40 | options::OPT_fno_test_coverage, // -f[no-]test-coverage |
41 | options::OPT_fcoverage_mapping, |
42 | options::OPT_fno_coverage_mapping, // -f[no-]coverage-mapping |
43 | options::OPT_coverage, // --coverage |
44 | options::OPT_fprofile_instr_generate, |
45 | options::OPT_fprofile_instr_generate_EQ, |
46 | options::OPT_fno_profile_instr_generate, // -f[no-]profile-instr-generate |
47 | options::OPT_fprofile_arcs, |
48 | options::OPT_fno_profile_arcs, // -f[no-]profile-arcs |
49 | options::OPT_fcreate_profile, // -fcreate-profile |
50 | options::OPT_fprofile_instr_use, |
51 | options::OPT_fprofile_instr_use_EQ, // -fprofile-instr-use |
52 | options::OPT_fcs_profile_generate, // -fcs-profile-generate |
53 | options::OPT_fcs_profile_generate_EQ, |
54 | }; |
55 | return UnsupportedOpts; |
56 | } |
57 | |
58 | SYCLToolChain::SYCLToolChain(const Driver &D, const llvm::Triple &Triple, |
59 | const ToolChain &HostTC, const ArgList &Args) |
60 | : ToolChain(D, Triple, Args), HostTC(HostTC), |
61 | SYCLInstallation(D, Triple, Args) { |
62 | // Lookup binaries into the driver directory, this is used to discover any |
63 | // dependent SYCL offload compilation tools. |
64 | getProgramPaths().push_back(Elt: getDriver().Dir); |
65 | |
66 | // Diagnose unsupported options only once. |
67 | for (OptSpecifier Opt : getUnsupportedOpts()) { |
68 | if (const Arg *A = Args.getLastArg(Ids: Opt)) { |
69 | D.Diag(DiagID: clang::diag::warn_drv_unsupported_option_for_target) |
70 | << A->getAsString(Args) << getTriple().str(); |
71 | } |
72 | } |
73 | } |
74 | |
75 | void SYCLToolChain::addClangTargetOptions( |
76 | const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, |
77 | Action::OffloadKind DeviceOffloadingKind) const { |
78 | HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind: DeviceOffloadingKind); |
79 | } |
80 | |
81 | llvm::opt::DerivedArgList * |
82 | SYCLToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, |
83 | StringRef BoundArch, |
84 | Action::OffloadKind DeviceOffloadKind) const { |
85 | DerivedArgList *DAL = |
86 | HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind); |
87 | |
88 | bool IsNewDAL = false; |
89 | if (!DAL) { |
90 | DAL = new DerivedArgList(Args.getBaseArgs()); |
91 | IsNewDAL = true; |
92 | } |
93 | |
94 | for (Arg *A : Args) { |
95 | // Filter out any options we do not want to pass along to the device |
96 | // compilation. |
97 | auto Opt(A->getOption()); |
98 | bool Unsupported = false; |
99 | for (OptSpecifier UnsupportedOpt : getUnsupportedOpts()) { |
100 | if (Opt.matches(ID: UnsupportedOpt)) { |
101 | if (Opt.getID() == options::OPT_fsanitize_EQ && |
102 | A->getValues().size() == 1) { |
103 | std::string SanitizeVal = A->getValue(); |
104 | if (SanitizeVal == "address" ) { |
105 | if (IsNewDAL) |
106 | DAL->append(A); |
107 | continue; |
108 | } |
109 | } |
110 | if (!IsNewDAL) |
111 | DAL->eraseArg(Id: Opt.getID()); |
112 | Unsupported = true; |
113 | } |
114 | } |
115 | if (Unsupported) |
116 | continue; |
117 | if (IsNewDAL) |
118 | DAL->append(A); |
119 | } |
120 | |
121 | const OptTable &Opts = getDriver().getOpts(); |
122 | if (!BoundArch.empty()) { |
123 | DAL->eraseArg(Id: options::OPT_march_EQ); |
124 | DAL->AddJoinedArg(BaseArg: nullptr, Opt: Opts.getOption(Opt: options::OPT_march_EQ), |
125 | Value: BoundArch); |
126 | } |
127 | return DAL; |
128 | } |
129 | |
130 | void SYCLToolChain::addClangWarningOptions(ArgStringList &CC1Args) const { |
131 | HostTC.addClangWarningOptions(CC1Args); |
132 | } |
133 | |
134 | ToolChain::CXXStdlibType |
135 | SYCLToolChain::GetCXXStdlibType(const ArgList &Args) const { |
136 | return HostTC.GetCXXStdlibType(Args); |
137 | } |
138 | |
139 | void SYCLToolChain::addSYCLIncludeArgs(const ArgList &DriverArgs, |
140 | ArgStringList &CC1Args) const { |
141 | SYCLInstallation.addSYCLIncludeArgs(DriverArgs, CC1Args); |
142 | } |
143 | |
144 | void SYCLToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
145 | ArgStringList &CC1Args) const { |
146 | HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); |
147 | } |
148 | |
149 | void SYCLToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args, |
150 | ArgStringList &CC1Args) const { |
151 | HostTC.AddClangCXXStdlibIncludeArgs(DriverArgs: Args, CC1Args); |
152 | } |
153 | |