10b57cec5SDimitry Andric //===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H 100b57cec5SDimitry Andric #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Gnu.h" 135ffd83dbSDimitry Andric #include "ROCm.h" 14e8d8bef9SDimitry Andric #include "clang/Basic/TargetID.h" 150b57cec5SDimitry Andric #include "clang/Driver/Options.h" 160b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 170b57cec5SDimitry Andric #include "clang/Driver/ToolChain.h" 185ffd83dbSDimitry Andric #include "llvm/ADT/SmallString.h" 1906c3fb27SDimitry Andric #include "llvm/TargetParser/TargetParser.h" 205ffd83dbSDimitry Andric 210b57cec5SDimitry Andric #include <map> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace clang { 240b57cec5SDimitry Andric namespace driver { 255ffd83dbSDimitry Andric 260b57cec5SDimitry Andric namespace tools { 270b57cec5SDimitry Andric namespace amdgpu { 280b57cec5SDimitry Andric 295f757f3fSDimitry Andric class LLVM_LIBRARY_VISIBILITY Linker final : public Tool { 300b57cec5SDimitry Andric public: 315ffd83dbSDimitry Andric Linker(const ToolChain &TC) : Tool("amdgpu::Linker", "ld.lld", TC) {} 320b57cec5SDimitry Andric bool isLinkJob() const override { return true; } 330b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 340b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 350b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 360b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 370b57cec5SDimitry Andric const char *LinkingOutput) const override; 380b57cec5SDimitry Andric }; 390b57cec5SDimitry Andric 40e8d8bef9SDimitry Andric void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple, 41e8d8bef9SDimitry Andric const llvm::opt::ArgList &Args, 420b57cec5SDimitry Andric std::vector<StringRef> &Features); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric } // end namespace amdgpu 450b57cec5SDimitry Andric } // end namespace tools 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric namespace toolchains { 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF { 505ffd83dbSDimitry Andric protected: 510b57cec5SDimitry Andric const std::map<options::ID, const StringRef> OptionsDefault; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric Tool *buildLinker() const override; 54349cc55cSDimitry Andric StringRef getOptionDefault(options::ID OptID) const { 550b57cec5SDimitry Andric auto opt = OptionsDefault.find(OptID); 560b57cec5SDimitry Andric assert(opt != OptionsDefault.end() && "No Default for Option"); 570b57cec5SDimitry Andric return opt->second; 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric public: 610b57cec5SDimitry Andric AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, 620b57cec5SDimitry Andric const llvm::opt::ArgList &Args); 63349cc55cSDimitry Andric unsigned GetDefaultDwarfVersion() const override { return 5; } 640b57cec5SDimitry Andric 65bdd1243dSDimitry Andric bool IsMathErrnoDefault() const override { return false; } 66fe6060f1SDimitry Andric bool isCrossCompiling() const override { return true; } 6706c3fb27SDimitry Andric bool isPICDefault() const override { return true; } 68349cc55cSDimitry Andric bool isPIEDefault(const llvm::opt::ArgList &Args) const override { 69349cc55cSDimitry Andric return false; 70349cc55cSDimitry Andric } 7106c3fb27SDimitry Andric bool isPICDefaultForced() const override { return true; } 72fe6060f1SDimitry Andric bool SupportsProfiling() const override { return false; } 73fe6060f1SDimitry Andric 740b57cec5SDimitry Andric llvm::opt::DerivedArgList * 750b57cec5SDimitry Andric TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 760b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 790b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 800b57cec5SDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 815ffd83dbSDimitry Andric 825ffd83dbSDimitry Andric /// Return whether denormals should be flushed, and treated as 0 by default 835ffd83dbSDimitry Andric /// for the subtarget. 845ffd83dbSDimitry Andric static bool getDefaultDenormsAreZeroForTarget(llvm::AMDGPU::GPUKind GPUKind); 855ffd83dbSDimitry Andric 865ffd83dbSDimitry Andric llvm::DenormalMode getDefaultDenormalModeForType( 875ffd83dbSDimitry Andric const llvm::opt::ArgList &DriverArgs, const JobAction &JA, 885ffd83dbSDimitry Andric const llvm::fltSemantics *FPType = nullptr) const override; 895ffd83dbSDimitry Andric 905ffd83dbSDimitry Andric static bool isWave64(const llvm::opt::ArgList &DriverArgs, 915ffd83dbSDimitry Andric llvm::AMDGPU::GPUKind Kind); 925ffd83dbSDimitry Andric /// Needed for using lto. 935ffd83dbSDimitry Andric bool HasNativeLLVMSupport() const override { 945ffd83dbSDimitry Andric return true; 955ffd83dbSDimitry Andric } 965ffd83dbSDimitry Andric 975ffd83dbSDimitry Andric /// Needed for translating LTO options. 985ffd83dbSDimitry Andric const char *getDefaultLinker() const override { return "ld.lld"; } 99e8d8bef9SDimitry Andric 100bdd1243dSDimitry Andric /// Uses amdgpu-arch tool to get arch of the system GPU. Will return error 101fe6060f1SDimitry Andric /// if unable to find one. 102bdd1243dSDimitry Andric virtual Expected<SmallVector<std::string>> 103bdd1243dSDimitry Andric getSystemGPUArchs(const llvm::opt::ArgList &Args) const override; 104fe6060f1SDimitry Andric 105e8d8bef9SDimitry Andric protected: 106e8d8bef9SDimitry Andric /// Check and diagnose invalid target ID specified by -mcpu. 107fe6060f1SDimitry Andric virtual void checkTargetID(const llvm::opt::ArgList &DriverArgs) const; 108fe6060f1SDimitry Andric 109fe6060f1SDimitry Andric /// The struct type returned by getParsedTargetID. 110fe6060f1SDimitry Andric struct ParsedTargetIDType { 111bdd1243dSDimitry Andric std::optional<std::string> OptionalTargetID; 112bdd1243dSDimitry Andric std::optional<std::string> OptionalGPUArch; 113bdd1243dSDimitry Andric std::optional<llvm::StringMap<bool>> OptionalFeatures; 114fe6060f1SDimitry Andric }; 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric /// Get target ID, GPU arch, and target ID features if the target ID is 117fe6060f1SDimitry Andric /// specified and valid. 118fe6060f1SDimitry Andric ParsedTargetIDType 119fe6060f1SDimitry Andric getParsedTargetID(const llvm::opt::ArgList &DriverArgs) const; 120e8d8bef9SDimitry Andric 121e8d8bef9SDimitry Andric /// Get GPU arch from -mcpu without checking. 122e8d8bef9SDimitry Andric StringRef getGPUArch(const llvm::opt::ArgList &DriverArgs) const; 123fe6060f1SDimitry Andric 124*0fca6ea1SDimitry Andric /// Common warning options shared by AMDGPU HIP, OpenCL and OpenMP toolchains. 125*0fca6ea1SDimitry Andric /// Language specific warning options should go to derived classes. 126*0fca6ea1SDimitry Andric void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 1275ffd83dbSDimitry Andric }; 1285ffd83dbSDimitry Andric 1295ffd83dbSDimitry Andric class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain { 1305ffd83dbSDimitry Andric public: 1315ffd83dbSDimitry Andric ROCMToolChain(const Driver &D, const llvm::Triple &Triple, 1325ffd83dbSDimitry Andric const llvm::opt::ArgList &Args); 1335ffd83dbSDimitry Andric void 1345ffd83dbSDimitry Andric addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 1355ffd83dbSDimitry Andric llvm::opt::ArgStringList &CC1Args, 1365ffd83dbSDimitry Andric Action::OffloadKind DeviceOffloadKind) const override; 13769ade1e0SDimitry Andric 13869ade1e0SDimitry Andric // Returns a list of device library names shared by different languages 13969ade1e0SDimitry Andric llvm::SmallVector<std::string, 12> 14069ade1e0SDimitry Andric getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, 14181ad6265SDimitry Andric const std::string &GPUArch, 14281ad6265SDimitry Andric bool isOpenMP = false) const; 143*0fca6ea1SDimitry Andric SanitizerMask getSupportedSanitizers() const override { 144*0fca6ea1SDimitry Andric return SanitizerKind::Address; 145*0fca6ea1SDimitry Andric } 1460b57cec5SDimitry Andric }; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric } // end namespace toolchains 1490b57cec5SDimitry Andric } // end namespace driver 1500b57cec5SDimitry Andric } // end namespace clang 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H 153