xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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