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
SYCLInstallationDetector(const Driver & D,const llvm::Triple & HostTriple,const llvm::opt::ArgList & Args)17 SYCLInstallationDetector::SYCLInstallationDetector(
18 const Driver &D, const llvm::Triple &HostTriple,
19 const llvm::opt::ArgList &Args) {}
20
addSYCLIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const21 void SYCLInstallationDetector::addSYCLIncludeArgs(
22 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
23 if (DriverArgs.hasArg(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.
getUnsupportedOpts()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
SYCLToolChain(const Driver & D,const llvm::Triple & Triple,const ToolChain & HostTC,const ArgList & Args)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(getDriver().Dir);
65
66 // Diagnose unsupported options only once.
67 for (OptSpecifier Opt : getUnsupportedOpts()) {
68 if (const Arg *A = Args.getLastArg(Opt)) {
69 D.Diag(clang::diag::warn_drv_unsupported_option_for_target)
70 << A->getAsString(Args) << getTriple().str();
71 }
72 }
73 }
74
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args,Action::OffloadKind DeviceOffloadingKind) const75 void SYCLToolChain::addClangTargetOptions(
76 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
77 Action::OffloadKind DeviceOffloadingKind) const {
78 HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
79 }
80
81 llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList & Args,StringRef BoundArch,Action::OffloadKind DeviceOffloadKind) const82 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(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(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(options::OPT_march_EQ);
124 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
125 BoundArch);
126 }
127 return DAL;
128 }
129
addClangWarningOptions(ArgStringList & CC1Args) const130 void SYCLToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
131 HostTC.addClangWarningOptions(CC1Args);
132 }
133
134 ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const135 SYCLToolChain::GetCXXStdlibType(const ArgList &Args) const {
136 return HostTC.GetCXXStdlibType(Args);
137 }
138
addSYCLIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const139 void SYCLToolChain::addSYCLIncludeArgs(const ArgList &DriverArgs,
140 ArgStringList &CC1Args) const {
141 SYCLInstallation.addSYCLIncludeArgs(DriverArgs, CC1Args);
142 }
143
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const144 void SYCLToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
145 ArgStringList &CC1Args) const {
146 HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
147 }
148
AddClangCXXStdlibIncludeArgs(const ArgList & Args,ArgStringList & CC1Args) const149 void SYCLToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
150 ArgStringList &CC1Args) const {
151 HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
152 }
153