diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains')
30 files changed, 255 insertions, 594 deletions
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 7fc34f4..0781683 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -31,6 +31,68 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; +RocmInstallationDetector::CommonBitcodeLibsPreferences:: + CommonBitcodeLibsPreferences(const Driver &D, + const llvm::opt::ArgList &DriverArgs, + StringRef GPUArch, + const Action::OffloadKind DeviceOffloadingKind, + const bool NeedsASanRT) + : ABIVer(DeviceLibABIVersion::fromCodeObjectVersion( + tools::getAMDGPUCodeObjectVersion(D, DriverArgs))) { + const auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch); + const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind); + + IsOpenMP = DeviceOffloadingKind == Action::OFK_OpenMP; + + const bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32); + Wave64 = + !HasWave32 || DriverArgs.hasFlag(options::OPT_mwavefrontsize64, + options::OPT_mno_wavefrontsize64, false); + + const bool IsKnownOffloading = DeviceOffloadingKind == Action::OFK_OpenMP || + DeviceOffloadingKind == Action::OFK_HIP; + + // Default to enabling f32 denormals on subtargets where fma is fast with + // denormals + const bool DefaultDAZ = + (Kind == llvm::AMDGPU::GK_NONE) + ? false + : !((ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) && + (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32)); + // TODO: There are way too many flags that change this. Do we need to + // check them all? + DAZ = IsKnownOffloading + ? DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero, + options::OPT_fno_gpu_flush_denormals_to_zero, + DefaultDAZ) + : DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || DefaultDAZ; + + FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only) || + DriverArgs.hasFlag(options::OPT_ffinite_math_only, + options::OPT_fno_finite_math_only, false); + + UnsafeMathOpt = + DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations) || + DriverArgs.hasFlag(options::OPT_funsafe_math_optimizations, + options::OPT_fno_unsafe_math_optimizations, false); + + FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math) || + DriverArgs.hasFlag(options::OPT_ffast_math, + options::OPT_fno_fast_math, false); + + const bool DefaultSqrt = IsKnownOffloading ? true : false; + CorrectSqrt = + DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt) || + DriverArgs.hasFlag( + options::OPT_fhip_fp32_correctly_rounded_divide_sqrt, + options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, DefaultSqrt); + // GPU Sanitizer currently only supports ASan and is enabled through host + // ASan. + GPUSan = (DriverArgs.hasFlag(options::OPT_fgpu_sanitize, + options::OPT_fno_gpu_sanitize, true) && + NeedsASanRT); +} + void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { assert(!Path.empty()); @@ -841,7 +903,7 @@ AMDGPUToolChain::getSystemGPUArchs(const ArgList &Args) const { else Program = GetProgramPath("amdgpu-arch"); - auto StdoutOrErr = executeToolChainProgram(Program); + auto StdoutOrErr = getDriver().executeProgram({Program}); if (!StdoutOrErr) return StdoutOrErr.takeError(); @@ -884,33 +946,14 @@ void ROCMToolChain::addClangTargetOptions( ABIVer)) return; - bool Wave64 = isWave64(DriverArgs, Kind); - // TODO: There are way too many flags that change this. Do we need to check - // them all? - bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || - getDefaultDenormsAreZeroForTarget(Kind); - bool FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only); - - bool UnsafeMathOpt = - DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations); - bool FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math); - bool CorrectSqrt = - DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt); - - // GPU Sanitizer currently only supports ASan and is enabled through host - // ASan. - bool GPUSan = DriverArgs.hasFlag(options::OPT_fgpu_sanitize, - options::OPT_fno_gpu_sanitize, true) && - getSanitizerArgs(DriverArgs).needsAsanRt(); - // Add the OpenCL specific bitcode library. llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs; BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str()); // Add the generic set of libraries. BCLibs.append(RocmInstallation->getCommonBitcodeLibs( - DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, - FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, false)); + DriverArgs, LibDeviceFile, GpuArch, DeviceOffloadingKind, + getSanitizerArgs(DriverArgs).needsAsanRt())); for (auto [BCFile, Internalize] : BCLibs) { if (Internalize) @@ -947,35 +990,37 @@ bool RocmInstallationDetector::checkCommonBitcodeLibs( llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> RocmInstallationDetector::getCommonBitcodeLibs( - const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64, - bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath, - bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool GPUSan, - bool isOpenMP) const { + const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, + StringRef GPUArch, const Action::OffloadKind DeviceOffloadingKind, + const bool NeedsASanRT) const { llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> BCLibs; + CommonBitcodeLibsPreferences Pref{D, DriverArgs, GPUArch, + DeviceOffloadingKind, NeedsASanRT}; + auto AddBCLib = [&](ToolChain::BitCodeLibraryInfo BCLib, bool Internalize = true) { BCLib.ShouldInternalize = Internalize; BCLibs.emplace_back(BCLib); }; auto AddSanBCLibs = [&]() { - if (GPUSan) + if (Pref.GPUSan) AddBCLib(getAsanRTLPath(), false); }; AddSanBCLibs(); AddBCLib(getOCMLPath()); - if (!isOpenMP) + if (!Pref.IsOpenMP) AddBCLib(getOCKLPath()); - else if (GPUSan && isOpenMP) + else if (Pref.GPUSan && Pref.IsOpenMP) AddBCLib(getOCKLPath(), false); - AddBCLib(getDenormalsAreZeroPath(DAZ)); - AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath)); - AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath)); - AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt)); - AddBCLib(getWavefrontSize64Path(Wave64)); + AddBCLib(getDenormalsAreZeroPath(Pref.DAZ)); + AddBCLib(getUnsafeMathPath(Pref.UnsafeMathOpt || Pref.FastRelaxedMath)); + AddBCLib(getFiniteOnlyPath(Pref.FiniteOnly || Pref.FastRelaxedMath)); + AddBCLib(getCorrectlyRoundedSqrtPath(Pref.CorrectSqrt)); + AddBCLib(getWavefrontSize64Path(Pref.Wave64)); AddBCLib(LibDeviceFile); - auto ABIVerPath = getABIVersionPath(ABIVer); + auto ABIVerPath = getABIVersionPath(Pref.ABIVer); if (!ABIVerPath.empty()) AddBCLib(ABIVerPath); @@ -983,9 +1028,9 @@ RocmInstallationDetector::getCommonBitcodeLibs( } llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> -ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, - const std::string &GPUArch, - bool isOpenMP) const { +ROCMToolChain::getCommonDeviceLibNames( + const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch, + Action::OffloadKind DeviceOffloadingKind) const { auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch); const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); @@ -996,33 +1041,9 @@ ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, ABIVer)) return {}; - // If --hip-device-lib is not set, add the default bitcode libraries. - // TODO: There are way too many flags that change this. Do we need to check - // them all? - bool DAZ = DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero, - options::OPT_fno_gpu_flush_denormals_to_zero, - getDefaultDenormsAreZeroForTarget(Kind)); - bool FiniteOnly = DriverArgs.hasFlag( - options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, false); - bool UnsafeMathOpt = - DriverArgs.hasFlag(options::OPT_funsafe_math_optimizations, - options::OPT_fno_unsafe_math_optimizations, false); - bool FastRelaxedMath = DriverArgs.hasFlag(options::OPT_ffast_math, - options::OPT_fno_fast_math, false); - bool CorrectSqrt = DriverArgs.hasFlag( - options::OPT_fhip_fp32_correctly_rounded_divide_sqrt, - options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, true); - bool Wave64 = isWave64(DriverArgs, Kind); - - // GPU Sanitizer currently only supports ASan and is enabled through host - // ASan. - bool GPUSan = DriverArgs.hasFlag(options::OPT_fgpu_sanitize, - options::OPT_fno_gpu_sanitize, true) && - getSanitizerArgs(DriverArgs).needsAsanRt(); - return RocmInstallation->getCommonBitcodeLibs( - DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, - FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, isOpenMP); + DriverArgs, LibDeviceFile, GPUArch, DeviceOffloadingKind, + getSanitizerArgs(DriverArgs).needsAsanRt()); } bool AMDGPUToolChain::shouldSkipSanitizeOption( diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h index 08bd4fa..e5d41e2 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.h +++ b/clang/lib/Driver/ToolChains/AMDGPU.h @@ -10,7 +10,6 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H #include "Gnu.h" -#include "ROCm.h" #include "clang/Basic/TargetID.h" #include "clang/Driver/Options.h" #include "clang/Driver/Tool.h" @@ -147,7 +146,7 @@ public: llvm::SmallVector<BitCodeLibraryInfo, 12> getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch, - bool isOpenMP = false) const; + Action::OffloadKind DeviceOffloadingKind) const; SanitizerMask getSupportedSanitizers() const override { return SanitizerKind::Address; diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index 7ffa3f0..2b41d54 100644 --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -44,7 +44,7 @@ void AMDGPUOpenMPToolChain::addClangTargetOptions( true)) return; - for (auto BCFile : getDeviceLibs(DriverArgs)) { + for (auto BCFile : getDeviceLibs(DriverArgs, DeviceOffloadingKind)) { CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode" : "-mlink-bitcode-file"); CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path)); @@ -132,7 +132,9 @@ AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D, } llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> -AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const { +AMDGPUOpenMPToolChain::getDeviceLibs( + const llvm::opt::ArgList &Args, + const Action::OffloadKind DeviceOffloadingKind) const { if (!Args.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true)) return {}; @@ -140,8 +142,8 @@ AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const { getTriple(), Args.getLastArgValue(options::OPT_march_EQ)); SmallVector<BitCodeLibraryInfo, 12> BCLibs; - for (auto BCLib : getCommonDeviceLibNames(Args, GpuArch.str(), - /*IsOpenMP=*/true)) + for (auto BCLib : + getCommonDeviceLibNames(Args, GpuArch.str(), DeviceOffloadingKind)) BCLibs.emplace_back(BCLib); return BCLibs; diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h index 0536c9f..cbafdf5 100644 --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h @@ -58,7 +58,8 @@ public: const llvm::opt::ArgList &Args) const override; llvm::SmallVector<BitCodeLibraryInfo, 12> - getDeviceLibs(const llvm::opt::ArgList &Args) const override; + getDeviceLibs(const llvm::opt::ArgList &Args, + const Action::OffloadKind DeviceOffloadKind) const override; const ToolChain &HostTC; }; diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 6bd710e..418f9fd 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -467,3 +467,18 @@ void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args, break; } } + +/// Is the triple {aarch64.aarch64_be}-none-elf? +bool aarch64::isAArch64BareMetal(const llvm::Triple &Triple) { + if (Triple.getArch() != llvm::Triple::aarch64 && + Triple.getArch() != llvm::Triple::aarch64_be) + return false; + + if (Triple.getVendor() != llvm::Triple::UnknownVendor) + return false; + + if (Triple.getOS() != llvm::Triple::UnknownOS) + return false; + + return Triple.getEnvironmentName() == "elf"; +} diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h index 2057272..2765ee8 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -30,6 +30,7 @@ std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple); +bool isAArch64BareMetal(const llvm::Triple &Triple); } // end namespace aarch64 } // end namespace target diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 9595ee8..94a94f1 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -23,7 +23,9 @@ const char *sparc::getSparcAsmModeForCPU(StringRef Name, if (Triple.getArch() == llvm::Triple::sparcv9) { const char *DefV9CPU; - if (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()) + if (Triple.isOSSolaris()) + DefV9CPU = "-Av9b"; + else if (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()) DefV9CPU = "-Av9a"; else DefV9CPU = "-Av9"; @@ -35,6 +37,13 @@ const char *sparc::getSparcAsmModeForCPU(StringRef Name, .Case("niagara4", "-Av9d") .Default(DefV9CPU); } else { + const char *DefV8CPU; + + if (Triple.isOSSolaris()) + DefV8CPU = "-Av8plus"; + else + DefV8CPU = "-Av8"; + return llvm::StringSwitch<const char *>(Name) .Case("v8", "-Av8") .Case("supersparc", "-Av8") @@ -70,7 +79,7 @@ const char *sparc::getSparcAsmModeForCPU(StringRef Name, .Case("gr712rc", "-Aleon") .Case("leon4", "-Aleon") .Case("gr740", "-Aleon") - .Default("-Av8"); + .Default(DefV8CPU); } } @@ -130,7 +139,8 @@ std::string sparc::getSparcTargetCPU(const Driver &D, const ArgList &Args, return ""; } -void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args, +void sparc::getSparcTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, std::vector<StringRef> &Features) { sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args); if (FloatABI == sparc::FloatABI::Soft) @@ -150,11 +160,22 @@ void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args, Features.push_back("-popc"); } + // Those OSes default to enabling VIS on 64-bit SPARC. + // See also the corresponding code for external assemblers in + // sparc::getSparcAsmModeForCPU(). + bool IsSparcV9ATarget = + (Triple.getArch() == llvm::Triple::sparcv9) && + (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()); + bool IsSparcV9BTarget = Triple.isOSSolaris(); + bool IsSparcV8PlusTarget = + Triple.getArch() == llvm::Triple::sparc && Triple.isOSSolaris(); if (Arg *A = Args.getLastArg(options::OPT_mvis, options::OPT_mno_vis)) { if (A->getOption().matches(options::OPT_mvis)) Features.push_back("+vis"); else Features.push_back("-vis"); + } else if (IsSparcV9ATarget) { + Features.push_back("+vis"); } if (Arg *A = Args.getLastArg(options::OPT_mvis2, options::OPT_mno_vis2)) { @@ -162,6 +183,8 @@ void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args, Features.push_back("+vis2"); else Features.push_back("-vis2"); + } else if (IsSparcV9BTarget) { + Features.push_back("+vis2"); } if (Arg *A = Args.getLastArg(options::OPT_mvis3, options::OPT_mno_vis3)) { @@ -182,6 +205,8 @@ void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args, if (Arg *A = Args.getLastArg(options::OPT_mv8plus, options::OPT_mno_v8plus)) { if (A->getOption().matches(options::OPT_mv8plus)) Features.push_back("+v8plus"); + } else if (IsSparcV8PlusTarget) { + Features.push_back("+v8plus"); } if (Args.hasArg(options::OPT_ffixed_g1)) diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.h b/clang/lib/Driver/ToolChains/Arch/Sparc.h index 2b178d9..fa25b49 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.h +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.h @@ -31,7 +31,8 @@ FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args); std::string getSparcTargetCPU(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple); -void getSparcTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, +void getSparcTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, std::vector<llvm::StringRef> &Features); const char *getSparcAsmModeForCPU(llvm::StringRef Name, const llvm::Triple &Triple); diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index e670696..207150e 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -12,6 +12,7 @@ #include "clang/Driver/CommonArgs.h" #include "clang/Driver/InputInfo.h" +#include "Arch/AArch64.h" #include "Arch/ARM.h" #include "Arch/RISCV.h" #include "clang/Driver/Compilation.h" @@ -31,21 +32,6 @@ using namespace clang::driver; using namespace clang::driver::tools; using namespace clang::driver::toolchains; -/// Is the triple {aarch64.aarch64_be}-none-elf? -static bool isAArch64BareMetal(const llvm::Triple &Triple) { - if (Triple.getArch() != llvm::Triple::aarch64 && - Triple.getArch() != llvm::Triple::aarch64_be) - return false; - - if (Triple.getVendor() != llvm::Triple::UnknownVendor) - return false; - - if (Triple.getOS() != llvm::Triple::UnknownOS) - return false; - - return Triple.getEnvironmentName() == "elf"; -} - static bool isRISCVBareMetal(const llvm::Triple &Triple) { if (!Triple.isRISCV()) return false; @@ -363,8 +349,9 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, } bool BareMetal::handlesTarget(const llvm::Triple &Triple) { - return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) || - isRISCVBareMetal(Triple) || isPPCBareMetal(Triple); + return arm::isARMEABIBareMetal(Triple) || + aarch64::isAArch64BareMetal(Triple) || isRISCVBareMetal(Triple) || + isPPCBareMetal(Triple); } Tool *BareMetal::buildLinker() const { @@ -694,9 +681,6 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, NeedCRTs) CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd))); - if (TC.getTriple().isRISCV()) - CmdArgs.push_back("-X"); - // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and // arm*-*-*bsd). diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8880c93..f4674a5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -16,6 +16,7 @@ #include "Arch/SystemZ.h" #include "Hexagon.h" #include "PS4CPU.h" +#include "ToolChains/Cuda.h" #include "clang/Basic/CLWarnings.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/HeaderInclude.h" @@ -97,32 +98,15 @@ forAllAssociatedToolChains(Compilation &C, const JobAction &JA, // Apply Work on all the offloading tool chains associated with the current // action. - if (JA.isHostOffloading(Action::OFK_Cuda)) - Work(*C.getSingleOffloadToolChain<Action::OFK_Cuda>()); - else if (JA.isDeviceOffloading(Action::OFK_Cuda)) - Work(*C.getSingleOffloadToolChain<Action::OFK_Host>()); - else if (JA.isHostOffloading(Action::OFK_HIP)) - Work(*C.getSingleOffloadToolChain<Action::OFK_HIP>()); - else if (JA.isDeviceOffloading(Action::OFK_HIP)) - Work(*C.getSingleOffloadToolChain<Action::OFK_Host>()); - - if (JA.isHostOffloading(Action::OFK_OpenMP)) { - auto TCs = C.getOffloadToolChains<Action::OFK_OpenMP>(); - for (auto II = TCs.first, IE = TCs.second; II != IE; ++II) - Work(*II->second); - } else if (JA.isDeviceOffloading(Action::OFK_OpenMP)) - Work(*C.getSingleOffloadToolChain<Action::OFK_Host>()); - - if (JA.isHostOffloading(Action::OFK_SYCL)) { - auto TCs = C.getOffloadToolChains<Action::OFK_SYCL>(); - for (auto II = TCs.first, IE = TCs.second; II != IE; ++II) - Work(*II->second); - } else if (JA.isDeviceOffloading(Action::OFK_SYCL)) - Work(*C.getSingleOffloadToolChain<Action::OFK_Host>()); - - // - // TODO: Add support for other offloading programming models here. - // + for (Action::OffloadKind Kind : {Action::OFK_Cuda, Action::OFK_OpenMP, + Action::OFK_HIP, Action::OFK_SYCL}) { + if (JA.isHostOffloading(Kind)) { + auto TCs = C.getOffloadToolChains(Kind); + for (auto II = TCs.first, IE = TCs.second; II != IE; ++II) + Work(*II->second); + } else if (JA.isDeviceOffloading(Kind)) + Work(*C.getSingleOffloadToolChain<Action::OFK_Host>()); + } } static bool @@ -2731,16 +2715,6 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back(MipsTargetFeature); } - // Those OSes default to enabling VIS on 64-bit SPARC. - // See also the corresponding code for external assemblers in - // sparc::getSparcAsmModeForCPU(). - bool IsSparcV9ATarget = - (C.getDefaultToolChain().getArch() == llvm::Triple::sparcv9) && - (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()); - if (IsSparcV9ATarget && SparcTargetFeatures.empty()) { - CmdArgs.push_back("-target-feature"); - CmdArgs.push_back("+vis"); - } for (const char *Feature : SparcTargetFeatures) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back(Feature); @@ -3908,17 +3882,17 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, const ArgList &Args, const InputInfo &Input, const InputInfo &Output, bool HaveStd20, ArgStringList &CmdArgs) { - bool IsCXX = types::isCXX(Input.getType()); - bool HaveStdCXXModules = IsCXX && HaveStd20; + const bool IsCXX = types::isCXX(Input.getType()); + const bool HaveStdCXXModules = IsCXX && HaveStd20; bool HaveModules = HaveStdCXXModules; // -fmodules enables the use of precompiled modules (off by default). // Users can pass -fno-cxx-modules to turn off modules support for // C++/Objective-C++ programs. + const bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, + options::OPT_fno_cxx_modules, true); bool HaveClangModules = false; if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) { - bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules, - options::OPT_fno_cxx_modules, true); if (AllowedInCXX || !IsCXX) { CmdArgs.push_back("-fmodules"); HaveClangModules = true; @@ -3927,6 +3901,9 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, HaveModules |= HaveClangModules; + if (HaveModules && !AllowedInCXX) + CmdArgs.push_back("-fno-cxx-modules"); + // -fmodule-maps enables implicit reading of module map files. By default, // this is enabled if we are using Clang's flavor of precompiled modules. if (Args.hasFlag(options::OPT_fimplicit_module_maps, @@ -4095,31 +4072,34 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, // module fragment. CmdArgs.push_back("-fskip-odr-check-in-gmf"); - if (Args.hasArg(options::OPT_modules_reduced_bmi) && + if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) && (Input.getType() == driver::types::TY_CXXModule || - Input.getType() == driver::types::TY_PP_CXXModule)) { + Input.getType() == driver::types::TY_PP_CXXModule) && + !Args.hasArg(options::OPT__precompile)) { CmdArgs.push_back("-fmodules-reduced-bmi"); if (Args.hasArg(options::OPT_fmodule_output_EQ)) Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ); - else { - if (Args.hasArg(options::OPT__precompile) && - (!Args.hasArg(options::OPT_o) || - Args.getLastArg(options::OPT_o)->getValue() == - getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) { - D.Diag(diag::err_drv_reduced_module_output_overrided); - } - + else CmdArgs.push_back(Args.MakeArgString( "-fmodule-output=" + getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))); - } } - // Noop if we see '-fmodules-reduced-bmi' with other translation - // units than module units. This is more user friendly to allow end uers to - // enable this feature without asking for help from build systems. - Args.ClaimAllArgs(options::OPT_modules_reduced_bmi); + if (Args.hasArg(options::OPT_fmodules_reduced_bmi) && + Args.hasArg(options::OPT__precompile) && + (!Args.hasArg(options::OPT_o) || + Args.getLastArg(options::OPT_o)->getValue() == + getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) { + D.Diag(diag::err_drv_reduced_module_output_overrided); + } + + // Noop if we see '-fmodules-reduced-bmi' or `-fno-modules-reduced-bmi` with + // other translation units than module units. This is more user friendly to + // allow end uers to enable this feature without asking for help from build + // systems. + Args.ClaimAllArgs(options::OPT_fmodules_reduced_bmi); + Args.ClaimAllArgs(options::OPT_fno_modules_reduced_bmi); // We need to include the case the input file is a module file here. // Since the default compilation model for C++ module interface unit will @@ -4992,8 +4972,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, else { // Host-side compilation. NormalizedTriple = - (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>() - : C.getSingleOffloadToolChain<Action::OFK_HIP>()) + (IsCuda ? C.getOffloadToolChains(Action::OFK_Cuda).first->second + : C.getOffloadToolChains(Action::OFK_HIP).first->second) ->getTriple() .normalize(); if (IsCuda) { @@ -5965,7 +5945,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-mms-bitfields"); } - if (Triple.isWindowsGNUEnvironment()) { + if (Triple.isOSCygMing()) { Args.addOptOutFlag(CmdArgs, options::OPT_fauto_import, options::OPT_fno_auto_import); } diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 651a39c..256c266 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -23,6 +23,7 @@ #include "Hexagon.h" #include "MSP430.h" #include "Solaris.h" +#include "ToolChains/Cuda.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" @@ -547,15 +548,22 @@ const char *tools::getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::aarch64: if (T.isOSManagarm()) return "aarch64managarm"; + else if (aarch64::isAArch64BareMetal(T)) + return "aarch64elf"; return "aarch64linux"; case llvm::Triple::aarch64_be: + if (aarch64::isAArch64BareMetal(T)) + return "aarch64elfb"; return "aarch64linuxb"; case llvm::Triple::arm: case llvm::Triple::thumb: case llvm::Triple::armeb: - case llvm::Triple::thumbeb: - return tools::arm::isARMBigEndian(T, Args) ? "armelfb_linux_eabi" - : "armelf_linux_eabi"; + case llvm::Triple::thumbeb: { + bool IsBigEndian = tools::arm::isARMBigEndian(T, Args); + if (arm::isARMEABIBareMetal(T)) + return IsBigEndian ? "armelfb" : "armelf"; + return IsBigEndian ? "armelfb_linux_eabi" : "armelf_linux_eabi"; + } case llvm::Triple::m68k: return "m68kelf"; case llvm::Triple::ppc: @@ -856,7 +864,7 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::sparcv9: - sparc::getSparcTargetFeatures(D, Args, Features); + sparc::getSparcTargetFeatures(D, Triple, Args, Features); break; case llvm::Triple::r600: case llvm::Triple::amdgcn: diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 2373d94..7d803be 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -815,7 +815,7 @@ NVPTXToolChain::getSystemGPUArchs(const ArgList &Args) const { else Program = GetProgramPath("nvptx-arch"); - auto StdoutOrErr = executeToolChainProgram(Program); + auto StdoutOrErr = getDriver().executeProgram({Program}); if (!StdoutOrErr) return StdoutOrErr.takeError(); diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 259eda6..8aeba53 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -11,6 +11,7 @@ #include "clang/Basic/Cuda.h" #include "clang/Driver/Action.h" +#include "clang/Driver/CudaInstallationDetector.h" #include "clang/Driver/Multilib.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -22,61 +23,6 @@ namespace clang { namespace driver { - -/// A class to find a viable CUDA installation -class CudaInstallationDetector { -private: - const Driver &D; - bool IsValid = false; - CudaVersion Version = CudaVersion::UNKNOWN; - std::string InstallPath; - std::string BinPath; - std::string LibDevicePath; - std::string IncludePath; - llvm::StringMap<std::string> LibDeviceMap; - - // CUDA architectures for which we have raised an error in - // CheckCudaVersionSupportsArch. - mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion; - -public: - CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, - const llvm::opt::ArgList &Args); - - void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const; - - /// Emit an error if Version does not support the given Arch. - /// - /// If either Version or Arch is unknown, does not emit an error. Emits at - /// most one error per Arch. - void CheckCudaVersionSupportsArch(OffloadArch Arch) const; - - /// Check whether we detected a valid Cuda install. - bool isValid() const { return IsValid; } - /// Print information about the detected CUDA installation. - void print(raw_ostream &OS) const; - - /// Get the detected Cuda install's version. - CudaVersion version() const { - return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED - : Version; - } - /// Get the detected Cuda installation path. - StringRef getInstallPath() const { return InstallPath; } - /// Get the detected path to Cuda's bin directory. - StringRef getBinPath() const { return BinPath; } - /// Get the detected Cuda Include path. - StringRef getIncludePath() const { return IncludePath; } - /// Get the detected Cuda device library path. - StringRef getLibDevicePath() const { return LibDevicePath; } - /// Get libdevice file for given architecture - std::string getLibDeviceFile(StringRef Gpu) const { - return LibDeviceMap.lookup(Gpu); - } - void WarnIfUnsupportedVersion() const; -}; - namespace tools { namespace NVPTX { diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index b38bfe6..d1cfb6f 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -9,12 +9,12 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H -#include "Cuda.h" -#include "LazyDetector.h" -#include "ROCm.h" -#include "SYCL.h" #include "clang/Basic/DarwinSDKInfo.h" #include "clang/Basic/LangOptions.h" +#include "clang/Driver/CudaInstallationDetector.h" +#include "clang/Driver/LazyDetector.h" +#include "clang/Driver/RocmInstallationDetector.h" +#include "clang/Driver/SyclInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "clang/Driver/XRayArgs.h" diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 1edb83f..7ab41e9 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -447,6 +447,7 @@ void Flang::addTargetOptions(const ArgList &Args, // Add the target features. switch (TC.getArch()) { default: + getTargetFeatures(D, Triple, Args, CmdArgs, /*ForAs*/ false); break; case llvm::Triple::aarch64: getTargetFeatures(D, Triple, Args, CmdArgs, /*ForAs*/ false); diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 3b8df71..4c42a5e5 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -9,10 +9,10 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H -#include "Cuda.h" -#include "LazyDetector.h" -#include "ROCm.h" -#include "SYCL.h" +#include "clang/Driver/CudaInstallationDetector.h" +#include "clang/Driver/LazyDetector.h" +#include "clang/Driver/RocmInstallationDetector.h" +#include "clang/Driver/SyclInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include <set> diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp index 5fe0f85..b4c6da0 100644 --- a/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -264,7 +264,7 @@ void HIPAMDToolChain::addClangTargetOptions( return; // No DeviceLibs for SPIR-V. } - for (auto BCFile : getDeviceLibs(DriverArgs)) { + for (auto BCFile : getDeviceLibs(DriverArgs, DeviceOffloadingKind)) { CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode" : "-mlink-bitcode-file"); CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path)); @@ -355,7 +355,8 @@ VersionTuple HIPAMDToolChain::computeMSVCVersion(const Driver *D, } llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> -HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { +HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs, + Action::OffloadKind DeviceOffloadingKind) const { llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs; if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true) || @@ -397,7 +398,8 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { assert(!GpuArch.empty() && "Must have an explicit GPU arch."); // Add common device libraries like ocml etc. - for (auto N : getCommonDeviceLibNames(DriverArgs, GpuArch.str())) + for (auto N : getCommonDeviceLibNames(DriverArgs, GpuArch.str(), + DeviceOffloadingKind)) BCLibs.emplace_back(N); // Add instrument lib. diff --git a/clang/lib/Driver/ToolChains/HIPAMD.h b/clang/lib/Driver/ToolChains/HIPAMD.h index 3630b11..30fc01a 100644 --- a/clang/lib/Driver/ToolChains/HIPAMD.h +++ b/clang/lib/Driver/ToolChains/HIPAMD.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_HIPAMD_H #include "AMDGPU.h" +#include "clang/Driver/SyclInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -80,7 +81,8 @@ public: void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; llvm::SmallVector<BitCodeLibraryInfo, 12> - getDeviceLibs(const llvm::opt::ArgList &Args) const override; + getDeviceLibs(const llvm::opt::ArgList &Args, + Action::OffloadKind DeviceOffloadKind) const override; SanitizerMask getSupportedSanitizers() const override; diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp index 53649ca..62bca04 100644 --- a/clang/lib/Driver/ToolChains/HIPSPV.cpp +++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp @@ -69,8 +69,17 @@ void HIPSPV::Linker::constructLinkAndEmitSpirvCommand( // Link LLVM bitcode. ArgStringList LinkArgs{}; + for (auto Input : Inputs) LinkArgs.push_back(Input.getFilename()); + + // Add static device libraries using the common helper function. + // This handles unbundling archives (.a) containing bitcode bundles. + StringRef Arch = getToolChain().getTriple().getArchName(); + StringRef Target = + "generic"; // SPIR-V is generic, no specific target ID like -mcpu + tools::AddStaticDeviceLibsLinking(C, *this, JA, Inputs, Args, LinkArgs, Arch, + Target, /*IsBitCodeSDL=*/true); LinkArgs.append({"-o", TempFile}); const char *LlvmLink = Args.MakeArgString(getToolChain().GetProgramPath("llvm-link")); @@ -149,7 +158,8 @@ void HIPSPVToolChain::addClangTargetOptions( CC1Args.append( {"-fvisibility=hidden", "-fapply-global-visibility-to-externs"}); - for (const BitCodeLibraryInfo &BCFile : getDeviceLibs(DriverArgs)) + for (const BitCodeLibraryInfo &BCFile : + getDeviceLibs(DriverArgs, DeviceOffloadingKind)) CC1Args.append( {"-mlink-builtin-bitcode", DriverArgs.MakeArgString(BCFile.Path)}); } @@ -200,7 +210,9 @@ void HIPSPVToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, } llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> -HIPSPVToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { +HIPSPVToolChain::getDeviceLibs( + const llvm::opt::ArgList &DriverArgs, + const Action::OffloadKind DeviceOffloadingKind) const { llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> BCLibs; if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true)) diff --git a/clang/lib/Driver/ToolChains/HIPSPV.h b/clang/lib/Driver/ToolChains/HIPSPV.h index ecd82e7..caf6924 100644 --- a/clang/lib/Driver/ToolChains/HIPSPV.h +++ b/clang/lib/Driver/ToolChains/HIPSPV.h @@ -69,7 +69,8 @@ public: void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; llvm::SmallVector<BitCodeLibraryInfo, 12> - getDeviceLibs(const llvm::opt::ArgList &Args) const override; + getDeviceLibs(const llvm::opt::ArgList &Args, + const Action::OffloadKind DeviceOffloadKind) const override; SanitizerMask getSupportedSanitizers() const override; diff --git a/clang/lib/Driver/ToolChains/LazyDetector.h b/clang/lib/Driver/ToolChains/LazyDetector.h deleted file mode 100644 index 813d00a..0000000 --- a/clang/lib/Driver/ToolChains/LazyDetector.h +++ /dev/null @@ -1,45 +0,0 @@ -//===--- LazyDetector.h - Lazy ToolChain Detection --------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H -#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H - -#include "clang/Driver/Tool.h" -#include "clang/Driver/ToolChain.h" -#include <optional> - -namespace clang { - -/// Simple wrapper for toolchain detector with costly initialization. This -/// delays the creation of the actual detector until its first usage. - -template <class T> class LazyDetector { - const driver::Driver &D; - llvm::Triple Triple; - const llvm::opt::ArgList &Args; - - std::optional<T> Detector; - -public: - LazyDetector(const driver::Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args) - : D(D), Triple(Triple), Args(Args) {} - T *operator->() { - if (!Detector) - Detector.emplace(D, Triple, Args); - return &*Detector; - } - const T *operator->() const { - return const_cast<T const *>( - const_cast<LazyDetector &>(*this).operator->()); - } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 7d31eea..bb469ff 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -279,8 +279,8 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args); } - StringRef Linker = - Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); + StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, + TC.getDriver().getPreferredLinker()); if (Linker.empty()) Linker = "link"; // We need to translate 'lld' into 'lld-link'. diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h index b35390c..5c17edc 100644 --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -9,11 +9,11 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H -#include "AMDGPU.h" -#include "Cuda.h" -#include "LazyDetector.h" -#include "SYCL.h" #include "clang/Driver/Compilation.h" +#include "clang/Driver/CudaInstallationDetector.h" +#include "clang/Driver/LazyDetector.h" +#include "clang/Driver/RocmInstallationDetector.h" +#include "clang/Driver/SyclInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/Frontend/Debug/Options.h" diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index b2e36ae..1bb9bcf 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -85,11 +85,18 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, CmdArgs.push_back("-lmoldname"); CmdArgs.push_back("-lmingwex"); - for (auto Lib : Args.getAllArgValues(options::OPT_l)) + for (auto Lib : Args.getAllArgValues(options::OPT_l)) { if (StringRef(Lib).starts_with("msvcr") || StringRef(Lib).starts_with("ucrt") || - StringRef(Lib).starts_with("crtdll")) + StringRef(Lib).starts_with("crtdll")) { + std::string CRTLib = (llvm::Twine("-l") + Lib).str(); + // Respect the user's chosen crt variant, but still provide it + // again as the last linker argument, because some of the libraries + // we added above may depend on it. + CmdArgs.push_back(Args.MakeArgStringRef(CRTLib)); return; + } + } CmdArgs.push_back("-lmsvcrt"); } @@ -548,7 +555,7 @@ toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, getFilePaths().push_back(Base + "lib"); NativeLLVMSupport = - Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER) + Args.getLastArgValue(options::OPT_fuse_ld_EQ, D.getPreferredLinker()) .equals_insensitive("lld"); } diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h index a9963d8..1730da4 100644 --- a/clang/lib/Driver/ToolChains/MinGW.h +++ b/clang/lib/Driver/ToolChains/MinGW.h @@ -11,8 +11,9 @@ #include "Cuda.h" #include "Gnu.h" -#include "LazyDetector.h" -#include "ROCm.h" +#include "clang/Driver/CudaInstallationDetector.h" +#include "clang/Driver/LazyDetector.h" +#include "clang/Driver/RocmInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/Support/ErrorOr.h" diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp index 79b1b69..8f58918 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -161,7 +161,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Nopie || Profiling) CmdArgs.push_back("-nopie"); - if (Triple.isRISCV64()) { + if (Triple.isLoongArch64() || Triple.isRISCV64()) { CmdArgs.push_back("-X"); if (Args.hasArg(options::OPT_mno_relax)) CmdArgs.push_back("--no-relax"); diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h deleted file mode 100644 index 2a09da01..0000000 --- a/clang/lib/Driver/ToolChains/ROCm.h +++ /dev/null @@ -1,294 +0,0 @@ -//===--- ROCm.h - ROCm installation detector --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H -#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H - -#include "clang/Basic/Cuda.h" -#include "clang/Basic/LLVM.h" -#include "clang/Driver/Driver.h" -#include "clang/Driver/Options.h" -#include "clang/Driver/SanitizerArgs.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Option/ArgList.h" -#include "llvm/Support/VersionTuple.h" -#include "llvm/TargetParser/Triple.h" - -namespace clang { -namespace driver { - -/// ABI version of device library. -struct DeviceLibABIVersion { - unsigned ABIVersion = 0; - DeviceLibABIVersion(unsigned V) : ABIVersion(V) {} - static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion) { - if (CodeObjectVersion < 4) - CodeObjectVersion = 4; - return DeviceLibABIVersion(CodeObjectVersion * 100); - } - /// Whether ABI version bc file is requested. - /// ABIVersion is code object version multiplied by 100. Code object v4 - /// and below works with ROCm 5.0 and below which does not have - /// abi_version_*.bc. Code object v5 requires abi_version_500.bc. - bool requiresLibrary() { return ABIVersion >= 500; } - std::string toString() { return Twine(getAsCodeObjectVersion()).str(); } - - unsigned getAsCodeObjectVersion() const { - assert(ABIVersion % 100 == 0 && "Not supported"); - return ABIVersion / 100; - } -}; - -/// A class to find a viable ROCM installation -/// TODO: Generalize to handle libclc. -class RocmInstallationDetector { -private: - struct ConditionalLibrary { - SmallString<0> On; - SmallString<0> Off; - - bool isValid() const { return !On.empty() && !Off.empty(); } - - StringRef get(bool Enabled) const { - assert(isValid()); - return Enabled ? On : Off; - } - }; - - // Installation path candidate. - struct Candidate { - llvm::SmallString<0> Path; - bool StrictChecking; - // Release string for ROCm packages built with SPACK if not empty. The - // installation directories of ROCm packages built with SPACK follow the - // convention <package_name>-<rocm_release_string>-<hash>. - std::string SPACKReleaseStr; - - bool isSPACK() const { return !SPACKReleaseStr.empty(); } - Candidate(std::string Path, bool StrictChecking = false, - StringRef SPACKReleaseStr = {}) - : Path(Path), StrictChecking(StrictChecking), - SPACKReleaseStr(SPACKReleaseStr.str()) {} - }; - - const Driver &D; - bool HasHIPRuntime = false; - bool HasDeviceLibrary = false; - bool HasHIPStdParLibrary = false; - bool HasRocThrustLibrary = false; - bool HasRocPrimLibrary = false; - - // Default version if not detected or specified. - const unsigned DefaultVersionMajor = 3; - const unsigned DefaultVersionMinor = 5; - const char *DefaultVersionPatch = "0"; - - // The version string in Major.Minor.Patch format. - std::string DetectedVersion; - // Version containing major and minor. - llvm::VersionTuple VersionMajorMinor; - // Version containing patch. - std::string VersionPatch; - - // ROCm path specified by --rocm-path. - StringRef RocmPathArg; - // ROCm device library paths specified by --rocm-device-lib-path. - std::vector<std::string> RocmDeviceLibPathArg; - // HIP runtime path specified by --hip-path. - StringRef HIPPathArg; - // HIP Standard Parallel Algorithm acceleration library specified by - // --hipstdpar-path - StringRef HIPStdParPathArg; - // rocThrust algorithm library specified by --hipstdpar-thrust-path - StringRef HIPRocThrustPathArg; - // rocPrim algorithm library specified by --hipstdpar-prim-path - StringRef HIPRocPrimPathArg; - // HIP version specified by --hip-version. - StringRef HIPVersionArg; - // Wheter -nogpulib is specified. - bool NoBuiltinLibs = false; - - // Paths - SmallString<0> InstallPath; - SmallString<0> BinPath; - SmallString<0> LibPath; - SmallString<0> LibDevicePath; - SmallString<0> IncludePath; - SmallString<0> SharePath; - llvm::StringMap<std::string> LibDeviceMap; - - // Libraries that are always linked. - SmallString<0> OCML; - SmallString<0> OCKL; - - // Libraries that are always linked depending on the language - SmallString<0> OpenCL; - - // Asan runtime library - SmallString<0> AsanRTL; - - // Libraries swapped based on compile flags. - ConditionalLibrary WavefrontSize64; - ConditionalLibrary FiniteOnly; - ConditionalLibrary UnsafeMath; - ConditionalLibrary DenormalsAreZero; - ConditionalLibrary CorrectlyRoundedSqrt; - - // Maps ABI version to library path. The version number is in the format of - // three digits as used in the ABI version library name. - std::map<unsigned, std::string> ABIVersionMap; - - // Cache ROCm installation search paths. - SmallVector<Candidate, 4> ROCmSearchDirs; - bool PrintROCmSearchDirs; - bool Verbose; - - bool allGenericLibsValid() const { - return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() && - WavefrontSize64.isValid() && FiniteOnly.isValid() && - UnsafeMath.isValid() && DenormalsAreZero.isValid() && - CorrectlyRoundedSqrt.isValid(); - } - - void scanLibDevicePath(llvm::StringRef Path); - bool parseHIPVersionFile(llvm::StringRef V); - const SmallVectorImpl<Candidate> &getInstallationPathCandidates(); - - /// Find the path to a SPACK package under the ROCm candidate installation - /// directory if the candidate is a SPACK ROCm candidate. \returns empty - /// string if the candidate is not SPACK ROCm candidate or the requested - /// package is not found. - llvm::SmallString<0> findSPACKPackage(const Candidate &Cand, - StringRef PackageName); - -public: - RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, - const llvm::opt::ArgList &Args, - bool DetectHIPRuntime = true, - bool DetectDeviceLib = false); - - /// Get file paths of default bitcode libraries common to AMDGPU based - /// toolchains. - llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> getCommonBitcodeLibs( - const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, - bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, - bool FastRelaxedMath, bool CorrectSqrt, DeviceLibABIVersion ABIVer, - bool GPUSan, bool isOpenMP) const; - /// Check file paths of default bitcode libraries common to AMDGPU based - /// toolchains. \returns false if there are invalid or missing files. - bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile, - DeviceLibABIVersion ABIVer) const; - - /// Check whether we detected a valid HIP runtime. - bool hasHIPRuntime() const { return HasHIPRuntime; } - - /// Check whether we detected a valid ROCm device library. - bool hasDeviceLibrary() const { return HasDeviceLibrary; } - - /// Check whether we detected a valid HIP STDPAR Acceleration library. - bool hasHIPStdParLibrary() const { return HasHIPStdParLibrary; } - - /// Print information about the detected ROCm installation. - void print(raw_ostream &OS) const; - - /// Get the detected Rocm install's version. - // RocmVersion version() const { return Version; } - - /// Get the detected Rocm installation path. - StringRef getInstallPath() const { return InstallPath; } - - /// Get the detected path to Rocm's bin directory. - // StringRef getBinPath() const { return BinPath; } - - /// Get the detected Rocm Include path. - StringRef getIncludePath() const { return IncludePath; } - - /// Get the detected Rocm library path. - StringRef getLibPath() const { return LibPath; } - - /// Get the detected Rocm device library path. - StringRef getLibDevicePath() const { return LibDevicePath; } - - StringRef getOCMLPath() const { - assert(!OCML.empty()); - return OCML; - } - - StringRef getOCKLPath() const { - assert(!OCKL.empty()); - return OCKL; - } - - StringRef getOpenCLPath() const { - assert(!OpenCL.empty()); - return OpenCL; - } - - /// Returns empty string of Asan runtime library is not available. - StringRef getAsanRTLPath() const { return AsanRTL; } - - StringRef getWavefrontSize64Path(bool Enabled) const { - return WavefrontSize64.get(Enabled); - } - - StringRef getFiniteOnlyPath(bool Enabled) const { - return FiniteOnly.get(Enabled); - } - - StringRef getUnsafeMathPath(bool Enabled) const { - return UnsafeMath.get(Enabled); - } - - StringRef getDenormalsAreZeroPath(bool Enabled) const { - return DenormalsAreZero.get(Enabled); - } - - StringRef getCorrectlyRoundedSqrtPath(bool Enabled) const { - return CorrectlyRoundedSqrt.get(Enabled); - } - - StringRef getABIVersionPath(DeviceLibABIVersion ABIVer) const { - auto Loc = ABIVersionMap.find(ABIVer.ABIVersion); - if (Loc == ABIVersionMap.end()) - return StringRef(); - return Loc->second; - } - - /// Get libdevice file for given architecture - StringRef getLibDeviceFile(StringRef Gpu) const { - auto Loc = LibDeviceMap.find(Gpu); - if (Loc == LibDeviceMap.end()) - return ""; - return Loc->second; - } - - void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const; - - void detectDeviceLibrary(); - void detectHIPRuntime(); - - /// Get the values for --rocm-device-lib-path arguments - ArrayRef<std::string> getRocmDeviceLibPathArg() const { - return RocmDeviceLibPathArg; - } - - /// Get the value for --rocm-path argument - StringRef getRocmPathArg() const { return RocmPathArg; } - - /// Get the value for --hip-version argument - StringRef getHIPVersionArg() const { return HIPVersionArg; } - - StringRef getHIPVersion() const { return DetectedVersion; } -}; - -} // end namespace driver -} // end namespace clang - -#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h index 2a8b4ec..be4ba47 100644 --- a/clang/lib/Driver/ToolChains/SYCL.h +++ b/clang/lib/Driver/ToolChains/SYCL.h @@ -9,21 +9,12 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H +#include "clang/Driver/SyclInstallationDetector.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" namespace clang { namespace driver { - -class SYCLInstallationDetector { -public: - SYCLInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, - const llvm::opt::ArgList &Args); - - void addSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const; -}; - namespace toolchains { class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain { diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index a3574e1..02aa598 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -39,7 +39,7 @@ void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, bool solaris::isLinkerGnuLd(const ToolChain &TC, const ArgList &Args) { // Only used if targetting Solaris. const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ); - StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; + StringRef UseLinker = A ? A->getValue() : TC.getDriver().getPreferredLinker(); return UseLinker == "bfd" || UseLinker == "gld"; } @@ -52,7 +52,7 @@ static bool getPIE(const ArgList &Args, const ToolChain &TC) { TC.isPIEDefault(Args)); } -// FIXME: Need to handle CLANG_DEFAULT_LINKER here? +// FIXME: Need to handle PreferredLinker here? std::string solaris::Linker::getLinkerPath(const ArgList &Args) const { const ToolChain &ToolChain = getToolChain(); if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { @@ -345,7 +345,7 @@ SanitizerMask Solaris::getSupportedSanitizers() const { const char *Solaris::getDefaultLinker() const { // FIXME: Only handle Solaris ld and GNU ld here. - return llvm::StringSwitch<const char *>(CLANG_DEFAULT_LINKER) + return llvm::StringSwitch<const char *>(getDriver().getPreferredLinker()) .Cases("bfd", "gld", "/usr/gnu/bin/ld") .Default("/usr/bin/ld"); } diff --git a/clang/lib/Driver/ToolChains/UEFI.cpp b/clang/lib/Driver/ToolChains/UEFI.cpp index ac6668e..2b41173 100644 --- a/clang/lib/Driver/ToolChains/UEFI.cpp +++ b/clang/lib/Driver/ToolChains/UEFI.cpp @@ -83,8 +83,8 @@ void tools::uefi::Linker::ConstructJob(Compilation &C, const JobAction &JA, // This should ideally be handled by ToolChain::GetLinkerPath but we need // to special case some linker paths. In the case of lld, we need to // translate 'lld' into 'lld-link'. - StringRef Linker = - Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); + StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ, + TC.getDriver().getPreferredLinker()); if (Linker.empty() || Linker == "lld") Linker = "lld-link"; |