| 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 | |