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