diff options
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 141 |
1 files changed, 133 insertions, 8 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index dc84c1b..528b7d1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -43,6 +43,8 @@ #include "ToolChains/PS4CPU.h" #include "ToolChains/RISCVToolchain.h" #include "ToolChains/SPIRV.h" +#include "ToolChains/SPIRVOpenMP.h" +#include "ToolChains/SYCL.h" #include "ToolChains/Solaris.h" #include "ToolChains/TCE.h" #include "ToolChains/UEFI.h" @@ -780,6 +782,35 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const { return RT; } +static llvm::Triple getSYCLDeviceTriple(StringRef TargetArch) { + SmallVector<StringRef, 5> SYCLAlias = {"spir", "spir64", "spirv", "spirv32", + "spirv64"}; + if (llvm::is_contained(SYCLAlias, TargetArch)) { + llvm::Triple TargetTriple; + TargetTriple.setArchName(TargetArch); + TargetTriple.setVendor(llvm::Triple::UnknownVendor); + TargetTriple.setOS(llvm::Triple::UnknownOS); + return TargetTriple; + } + return llvm::Triple(TargetArch); +} + +static bool addSYCLDefaultTriple(Compilation &C, + SmallVectorImpl<llvm::Triple> &SYCLTriples) { + // Check current set of triples to see if the default has already been set. + for (const auto &SYCLTriple : SYCLTriples) { + if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch && + SYCLTriple.isSPIROrSPIRV()) + return false; + } + // Add the default triple as it was not found. + llvm::Triple DefaultTriple = getSYCLDeviceTriple( + C.getDefaultToolChain().getTriple().isArch32Bit() ? "spirv32" + : "spirv64"); + SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple); + return true; +} + void Driver::CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs) { @@ -841,7 +872,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, return; auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple, *HostTC, OFK); - assert(HIPTC && "Could not create offloading device tool chain."); C.addOffloadDeviceToolChain(HIPTC, OFK); } @@ -890,9 +920,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, HostTC->getTriple()); // Attempt to deduce the offloading triple from the set of architectures. - // We can only correctly deduce NVPTX / AMDGPU triples currently. We need - // to temporarily create these toolchains so that we can access tools for - // inferring architectures. + // We can only correctly deduce NVPTX / AMDGPU triples currently. + // We need to temporarily create these toolchains so that we can access + // tools for inferring architectures. llvm::DenseSet<StringRef> Archs; if (NVPTXTriple) { auto TempTC = std::make_unique<toolchains::CudaToolChain>( @@ -962,7 +992,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, const ToolChain *TC; // Device toolchains have to be selected differently. They pair host // and device in their implementation. - if (TT.isNVPTX() || TT.isAMDGCN()) { + if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) { const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); assert(HostTC && "Host toolchain should be always defined."); @@ -975,6 +1005,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, else if (TT.isAMDGCN()) DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>( *this, TT, *HostTC, C.getInputArgs()); + else if (TT.isSPIRV()) + DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>( + *this, TT, *HostTC, C.getInputArgs()); else assert(DeviceTC && "Device toolchain not defined."); } @@ -993,11 +1026,71 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, return; } + // We need to generate a SYCL toolchain if the user specified -fsycl. + bool IsSYCL = C.getInputArgs().hasFlag(options::OPT_fsycl, + options::OPT_fno_sycl, false); + + auto argSYCLIncompatible = [&](OptSpecifier OptId) { + if (!IsSYCL) + return; + if (Arg *IncompatArg = C.getInputArgs().getLastArg(OptId)) + Diag(clang::diag::err_drv_argument_not_allowed_with) + << IncompatArg->getSpelling() << "-fsycl"; + }; + // -static-libstdc++ is not compatible with -fsycl. + argSYCLIncompatible(options::OPT_static_libstdcxx); + // -ffreestanding cannot be used with -fsycl + argSYCLIncompatible(options::OPT_ffreestanding); + + llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec; + + if (IsSYCL) { + addSYCLDefaultTriple(C, UniqueSYCLTriplesVec); + + // We'll need to use the SYCL and host triples as the key into + // getOffloadingDeviceToolChain, because the device toolchains we're + // going to create will depend on both. + const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); + for (const auto &TargetTriple : UniqueSYCLTriplesVec) { + auto SYCLTC = &getOffloadingDeviceToolChain( + C.getInputArgs(), TargetTriple, *HostTC, Action::OFK_SYCL); + C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL); + } + } + // // TODO: Add support for other offloading programming models here. // } +bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) { + if (IsCLMode() || IsDXCMode() || IsFlangMode()) + return false; + + SmallString<128> CustomizationFile; + StringRef PathLIBEnv = StringRef(getenv("CLANG_CONFIG_PATH")).trim(); + // If the env var is a directory then append "/clang.cfg" and treat + // that as the config file. Otherwise treat the env var as the + // config file. + if (!PathLIBEnv.empty()) { + llvm::sys::path::append(CustomizationFile, PathLIBEnv); + if (llvm::sys::fs::is_directory(PathLIBEnv)) + llvm::sys::path::append(CustomizationFile, "/clang.cfg"); + if (llvm::sys::fs::is_regular_file(CustomizationFile)) + return readConfigFile(CustomizationFile, ExpCtx); + Diag(diag::err_drv_config_file_not_found) << CustomizationFile; + return true; + } + + SmallString<128> BaseDir(llvm::sys::path::parent_path(Dir)); + llvm::sys::path::append(CustomizationFile, BaseDir + "/etc/clang.cfg"); + if (llvm::sys::fs::is_regular_file(CustomizationFile)) + return readConfigFile(CustomizationFile, ExpCtx); + + // If no customization file, just return + return false; +} + static void appendOneArg(InputArgList &Args, const Arg *Opt) { // The args for config files or /clang: flags belong to different InputArgList // objects than Args. This copies an Arg from one of those other InputArgLists @@ -1219,11 +1312,18 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { } // Otherwise, use the real triple as used by the driver. + llvm::Triple RealTriple = + computeTargetTriple(*this, TargetTriple, *CLOptions); if (Triple.str().empty()) { - Triple = computeTargetTriple(*this, TargetTriple, *CLOptions); + Triple = RealTriple; assert(!Triple.str().empty()); } + // On z/OS, start by loading the customization file before loading + // the usual default config file(s). + if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx)) + return true; + // Search for config files in the following order: // 1. <triple>-<mode>.cfg using real driver mode // (e.g. i386-pc-linux-gnu-clang++.cfg). @@ -4230,6 +4330,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, bool UseNewOffloadingDriver = C.isOffloadingHostKind(Action::OFK_OpenMP) || + C.isOffloadingHostKind(Action::OFK_SYCL) || Args.hasFlag(options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm, false) || Args.hasFlag(options::OPT_offload_new_driver, @@ -4647,6 +4748,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Archs.insert(OffloadArchToString(OffloadArch::HIPDefault)); else if (Kind == Action::OFK_OpenMP) Archs.insert(StringRef()); + else if (Kind == Action::OFK_SYCL) + Archs.insert(StringRef()); } else { Args.ClaimAllArgs(options::OPT_offload_arch_EQ); Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ); @@ -4671,7 +4774,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C, OffloadAction::DeviceDependences DDeps; const Action::OffloadKind OffloadKinds[] = { - Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP}; + Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL}; for (Action::OffloadKind Kind : OffloadKinds) { SmallVector<const ToolChain *, 2> ToolChains; @@ -4708,6 +4811,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C, if (DeviceActions.empty()) return HostAction; + // FIXME: Do not collapse the host side for Darwin targets with SYCL offload + // compilations. The toolchain is not properly initialized for the target. + if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL && + HostAction->getType() != types::TY_Nothing && + C.getSingleOffloadToolChain<Action::OFK_Host>() + ->getTriple() + .isOSDarwin()) + HostAction->setCannotBeCollapsedWithNextDependentAction(); + auto PL = types::getCompilationPhases(*this, Args, InputType); for (phases::ID Phase : PL) { @@ -4716,6 +4828,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C, break; } + // Assemble actions are not used for the SYCL device side. Both compile + // and backend actions are used to generate IR and textual IR if needed. + if (Kind == Action::OFK_SYCL && Phase == phases::Assemble) + continue; + auto TCAndArch = TCAndArchs.begin(); for (Action *&A : DeviceActions) { if (A->getType() == types::TY_Nothing) @@ -4954,6 +5071,7 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction<BackendJobAction>(Input, Output); } if (Args.hasArg(options::OPT_emit_llvm) || + TargetDeviceOffloadKind == Action::OFK_SYCL || (((Input->getOffloadingToolChain() && Input->getOffloadingToolChain()->getTriple().isAMDGPU()) || TargetDeviceOffloadKind == Action::OFK_HIP) && @@ -6603,6 +6721,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args); else if (Target.isOSBinFormatELF()) TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args); + else if (Target.isAppleMachO()) + TC = std::make_unique<toolchains::AppleMachO>(*this, Target, Args); else if (Target.isOSBinFormatMachO()) TC = std::make_unique<toolchains::MachO>(*this, Target, Args); else @@ -6640,11 +6760,16 @@ const ToolChain &Driver::getOffloadingDeviceToolChain( HostTC, Args); break; } + case Action::OFK_SYCL: + if (Target.isSPIROrSPIRV()) + TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, HostTC, + Args); + break; default: break; } } - + assert(TC && "Could not create offloading device tool chain."); return *TC; } |