diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp | 135 |
1 files changed, 97 insertions, 38 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp index 10ae76cb4161..0971a2da62a3 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -9,6 +9,7 @@ #include "AMDGPU.h" #include "CommonArgs.h" #include "InputInfo.h" +#include "clang/Basic/TargetID.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/DriverDiagnostic.h" #include "llvm/Option/ArgList.h" @@ -87,23 +88,30 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { } } -void RocmInstallationDetector::ParseHIPVersionFile(llvm::StringRef V) { +// Parse and extract version numbers from `.hipVersion`. Return `true` if +// the parsing fails. +bool RocmInstallationDetector::parseHIPVersionFile(llvm::StringRef V) { SmallVector<StringRef, 4> VersionParts; V.split(VersionParts, '\n'); - unsigned Major; - unsigned Minor; + unsigned Major = ~0U; + unsigned Minor = ~0U; for (auto Part : VersionParts) { - auto Splits = Part.split('='); - if (Splits.first == "HIP_VERSION_MAJOR") - Splits.second.getAsInteger(0, Major); - else if (Splits.first == "HIP_VERSION_MINOR") - Splits.second.getAsInteger(0, Minor); - else if (Splits.first == "HIP_VERSION_PATCH") + auto Splits = Part.rtrim().split('='); + if (Splits.first == "HIP_VERSION_MAJOR") { + if (Splits.second.getAsInteger(0, Major)) + return true; + } else if (Splits.first == "HIP_VERSION_MINOR") { + if (Splits.second.getAsInteger(0, Minor)) + return true; + } else if (Splits.first == "HIP_VERSION_PATCH") VersionPatch = Splits.second.str(); } + if (Major == ~0U || Minor == ~0U) + return true; VersionMajorMinor = llvm::VersionTuple(Major, Minor); DetectedVersion = (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str(); + return false; } // For candidate specified by --rocm-path we do not do strict check. @@ -244,9 +252,9 @@ void RocmInstallationDetector::detectDeviceLibrary() { // - ${ROCM_ROOT}/lib/* // - ${ROCM_ROOT}/lib/bitcode/* // so try to detect these layouts. - static llvm::SmallVector<const char *, 2> SubDirsList[] = { + static constexpr std::array<const char *, 2> SubDirsList[] = { {"amdgcn", "bitcode"}, - {"lib"}, + {"lib", ""}, {"lib", "bitcode"}, }; @@ -289,7 +297,8 @@ void RocmInstallationDetector::detectHIPRuntime() { continue; if (HIPVersionArg.empty() && VersionFile) - ParseHIPVersionFile((*VersionFile)->getBuffer()); + if (parseHIPVersionFile((*VersionFile)->getBuffer())) + continue; HasHIPRuntime = true; return; @@ -355,27 +364,40 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-shared"); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand( - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(), - Args.MakeArgString(Linker), CmdArgs, Inputs)); + C.addCommand(std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), + CmdArgs, Inputs, Output)); } void amdgpu::getAMDGPUTargetFeatures(const Driver &D, + const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector<StringRef> &Features) { - if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) - D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args); + // Add target ID features to -target-feature options. No diagnostics should + // be emitted here since invalid target ID is diagnosed at other places. + StringRef TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ); + if (!TargetID.empty()) { + llvm::StringMap<bool> FeatureMap; + auto OptionalGpuArch = parseTargetID(Triple, TargetID, &FeatureMap); + if (OptionalGpuArch) { + StringRef GpuArch = OptionalGpuArch.getValue(); + // Iterate through all possible target ID features for the given GPU. + // If it is mapped to true, add +feature. + // If it is mapped to false, add -feature. + // If it is not in the map (default), do not add it + for (auto &&Feature : getAllPossibleTargetIDFeatures(Triple, GpuArch)) { + auto Pos = FeatureMap.find(Feature); + if (Pos == FeatureMap.end()) + continue; + Features.push_back(Args.MakeArgStringRef( + (Twine(Pos->second ? "+" : "-") + Feature).str())); + } + } + } - if (Args.getLastArg(options::OPT_mwavefrontsize64)) { - Features.push_back("-wavefrontsize16"); - Features.push_back("-wavefrontsize32"); + if (Args.hasFlag(options::OPT_mwavefrontsize64, + options::OPT_mno_wavefrontsize64, false)) Features.push_back("+wavefrontsize64"); - } - if (Args.getLastArg(options::OPT_mno_wavefrontsize64)) { - Features.push_back("-wavefrontsize16"); - Features.push_back("+wavefrontsize32"); - Features.push_back("-wavefrontsize64"); - } handleTargetFeaturesGroup( Args, Features, options::OPT_m_amdgpu_Features_Group); @@ -385,8 +407,14 @@ void amdgpu::getAMDGPUTargetFeatures(const Driver &D, AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args), - OptionsDefault({{options::OPT_O, "3"}, - {options::OPT_cl_std_EQ, "CL1.2"}}) {} + OptionsDefault( + {{options::OPT_O, "3"}, {options::OPT_cl_std_EQ, "CL1.2"}}) { + // Check code object version options. Emit warnings for legacy options + // and errors for the last invalid code object version options. + // It is done here to avoid repeated warning or error messages for + // each tool invocation. + (void)getOrCheckAMDGPUCodeObjectVersion(D, Args, /*Diagnose=*/true); +} Tool *AMDGPUToolChain::buildLinker() const { return new tools::amdgpu::Linker(*this); @@ -399,16 +427,20 @@ AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, DerivedArgList *DAL = Generic_ELF::TranslateArgs(Args, BoundArch, DeviceOffloadKind); - // Do nothing if not OpenCL (-x cl) - if (!Args.getLastArgValue(options::OPT_x).equals("cl")) - return DAL; + const OptTable &Opts = getDriver().getOpts(); if (!DAL) DAL = new DerivedArgList(Args.getBaseArgs()); - for (auto *A : Args) - DAL->append(A); - const OptTable &Opts = getDriver().getOpts(); + for (Arg *A : Args) { + if (!shouldSkipArgument(A)) + DAL->append(A); + } + + checkTargetID(*DAL); + + if (!Args.getLastArgValue(options::OPT_x).equals("cl")) + return DAL; // Phase 1 (.cl -> .bc) if (Args.hasArg(options::OPT_c) && Args.hasArg(options::OPT_emit_llvm)) { @@ -453,7 +485,8 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( if (JA.getOffloadingDeviceKind() == Action::OFK_HIP || JA.getOffloadingDeviceKind() == Action::OFK_Cuda) { - auto Kind = llvm::AMDGPU::parseArchAMDGCN(JA.getOffloadingArch()); + auto Arch = getProcessorFromTargetID(getTriple(), JA.getOffloadingArch()); + auto Kind = llvm::AMDGPU::parseArchAMDGCN(Arch); if (FPType && FPType == &llvm::APFloat::IEEEsingle() && DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, options::OPT_fno_cuda_flush_denormals_to_zero, @@ -463,7 +496,7 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( return llvm::DenormalMode::getIEEE(); } - const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + const StringRef GpuArch = getGPUArch(DriverArgs); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); // TODO: There are way too many flags that change this. Do we need to check @@ -480,7 +513,7 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs, llvm::AMDGPU::GPUKind Kind) { const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind); - static bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32); + bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32); return !HasWave32 || DriverArgs.hasFlag( options::OPT_mwavefrontsize64, options::OPT_mno_wavefrontsize64, false); @@ -508,6 +541,25 @@ void AMDGPUToolChain::addClangTargetOptions( } } +StringRef +AMDGPUToolChain::getGPUArch(const llvm::opt::ArgList &DriverArgs) const { + return getProcessorFromTargetID( + getTriple(), DriverArgs.getLastArgValue(options::OPT_mcpu_EQ)); +} + +void AMDGPUToolChain::checkTargetID( + const llvm::opt::ArgList &DriverArgs) const { + StringRef TargetID = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + if (TargetID.empty()) + return; + + llvm::StringMap<bool> FeatureMap; + auto OptionalGpuArch = parseTargetID(getTriple(), TargetID, &FeatureMap); + if (!OptionalGpuArch) { + getDriver().Diag(clang::diag::err_drv_bad_target_id) << TargetID; + } +} + void ROCMToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadingKind) const { @@ -529,7 +581,7 @@ void ROCMToolChain::addClangTargetOptions( } // Get the device name and canonicalize it - const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + const StringRef GpuArch = getGPUArch(DriverArgs); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); @@ -595,3 +647,10 @@ void RocmInstallationDetector::addCommonBitcodeLibCC1Args( CC1Args.push_back(LinkBitcodeFlag); CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile)); } + +bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const { + Option O = A->getOption(); + if (O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) + return true; + return false; +} |