diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -701,7 +701,7 @@ ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : AMDGPUToolChain(D, Triple, Args) { - RocmInstallation.detectDeviceLibrary(); + RocmInstallation->detectDeviceLibrary(); } void AMDGPUToolChain::addClangTargetOptions( @@ -790,11 +790,11 @@ const StringRef GpuArch = getGPUArch(DriverArgs); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); - StringRef LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); + StringRef LibDeviceFile = RocmInstallation->getLibDeviceFile(CanonArch); auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion( getAMDGPUCodeObjectVersion(getDriver(), DriverArgs)); - if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile, - ABIVer)) + if (!RocmInstallation->checkCommonBitcodeLibs(CanonArch, LibDeviceFile, + ABIVer)) return; bool Wave64 = isWave64(DriverArgs, Kind); @@ -813,10 +813,10 @@ // Add the OpenCL specific bitcode library. llvm::SmallVector BCLibs; - BCLibs.push_back(RocmInstallation.getOpenCLPath().str()); + BCLibs.push_back(RocmInstallation->getOpenCLPath().str()); // Add the generic set of libraries. - BCLibs.append(RocmInstallation.getCommonBitcodeLibs( + BCLibs.append(RocmInstallation->getCommonBitcodeLibs( DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, FastRelaxedMath, CorrectSqrt, ABIVer, false)); @@ -875,11 +875,11 @@ auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch); const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); - StringRef LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); + StringRef LibDeviceFile = RocmInstallation->getLibDeviceFile(CanonArch); auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion( getAMDGPUCodeObjectVersion(getDriver(), DriverArgs)); - if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile, - ABIVer)) + if (!RocmInstallation->checkCommonBitcodeLibs(CanonArch, LibDeviceFile, + ABIVer)) return {}; // If --hip-device-lib is not set, add the default bitcode libraries. @@ -900,7 +900,7 @@ options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, true); bool Wave64 = isWave64(DriverArgs, Kind); - return RocmInstallation.getCommonBitcodeLibs( + return RocmInstallation->getCommonBitcodeLibs( DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP); } diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -160,7 +160,7 @@ if (Args.hasArg(options::OPT_nogpulib)) return {}; - if (!RocmInstallation.hasDeviceLibrary()) { + if (!RocmInstallation->hasDeviceLibrary()) { getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0; return {}; } diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -477,12 +477,12 @@ void FreeBSD::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); + CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args); } void FreeBSD::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); + RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args); } Tool *FreeBSD::buildAssembler() const { diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H #include "Cuda.h" +#include "LazyDetector.h" #include "ROCm.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -286,8 +287,8 @@ protected: GCCInstallationDetector GCCInstallation; - CudaInstallationDetector CudaInstallation; - RocmInstallationDetector RocmInstallation; + LazyDetector CudaInstallation; + LazyDetector RocmInstallation; public: Generic_GCC(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2849,8 +2849,8 @@ void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { // Print the information about how we detected the GCC installation. GCCInstallation.print(OS); - CudaInstallation.print(OS); - RocmInstallation.print(OS); + CudaInstallation->print(OS); + RocmInstallation->print(OS); } ToolChain::UnwindTableLevel diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp --- a/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -314,7 +314,7 @@ void HIPAMDToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); + RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args); } SanitizerMask HIPAMDToolChain::getSupportedSanitizers() const { @@ -343,7 +343,7 @@ ArgStringList LibraryPaths; // Find in --hip-device-lib-path and HIP_LIBRARY_PATH. - for (StringRef Path : RocmInstallation.getRocmDeviceLibPathArg()) + for (StringRef Path : RocmInstallation->getRocmDeviceLibPathArg()) LibraryPaths.push_back(DriverArgs.MakeArgString(Path)); addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH"); @@ -365,7 +365,7 @@ getDriver().Diag(diag::err_drv_no_such_file) << BCName; }); } else { - if (!RocmInstallation.hasDeviceLibrary()) { + if (!RocmInstallation->hasDeviceLibrary()) { getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0; return {}; } @@ -376,7 +376,7 @@ if (DriverArgs.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize, true) && getSanitizerArgs(DriverArgs).needsAsanRt()) { - auto AsanRTL = RocmInstallation.getAsanRTLPath(); + auto AsanRTL = RocmInstallation->getAsanRTLPath(); if (AsanRTL.empty()) { unsigned DiagID = getDriver().getDiags().getCustomDiagID( DiagnosticsEngine::Error, @@ -390,7 +390,7 @@ } // Add the HIP specific bitcode library. - BCLibs.push_back(RocmInstallation.getHIPPath()); + BCLibs.push_back(RocmInstallation->getHIPPath()); // Add common device libraries like ocml etc. for (StringRef N : getCommonDeviceLibNames(DriverArgs, GpuArch.str())) diff --git a/clang/lib/Driver/ToolChains/LazyDetector.h b/clang/lib/Driver/ToolChains/LazyDetector.h new file mode 100644 --- /dev/null +++ b/clang/lib/Driver/ToolChains/LazyDetector.h @@ -0,0 +1,45 @@ +//===--- 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 + +namespace clang { + +/// Simple wrapper for toolchain detector with costly initialization. This +/// delays the creation of the actual detector until its first usage. + +template class LazyDetector { + const driver::Driver &D; + const llvm::Triple &Triple; + const llvm::opt::ArgList &Args; + + std::optional 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( + const_cast(*this).operator->()); + } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LAZYDETECTOR_H diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -681,23 +681,23 @@ void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); + CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args); } void Linux::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); + RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args); } void Linux::AddHIPRuntimeLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { CmdArgs.push_back( - Args.MakeArgString(StringRef("-L") + RocmInstallation.getLibPath())); + Args.MakeArgString(StringRef("-L") + RocmInstallation->getLibPath())); if (Args.hasFlag(options::OPT_offload_add_rpath, options::OPT_no_offload_add_rpath, false)) CmdArgs.append( - {"-rpath", Args.MakeArgString(RocmInstallation.getLibPath())}); + {"-rpath", Args.MakeArgString(RocmInstallation->getLibPath())}); CmdArgs.push_back("-lamdhip64"); }