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