xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/SYCL.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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