1//===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
10#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
11
12#include "Gnu.h"
13#include "ROCm.h"
14#include "clang/Basic/TargetID.h"
15#include "clang/Driver/Options.h"
16#include "clang/Driver/Tool.h"
17#include "clang/Driver/ToolChain.h"
18#include "llvm/ADT/SmallString.h"
19#include "llvm/Support/TargetParser.h"
20
21#include <map>
22
23namespace clang {
24namespace driver {
25
26namespace tools {
27namespace amdgpu {
28
29class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
30public:
31  Linker(const ToolChain &TC) : Tool("amdgpu::Linker", "ld.lld", TC) {}
32  bool isLinkJob() const override { return true; }
33  bool hasIntegratedCPP() const override { return false; }
34  void ConstructJob(Compilation &C, const JobAction &JA,
35                    const InputInfo &Output, const InputInfoList &Inputs,
36                    const llvm::opt::ArgList &TCArgs,
37                    const char *LinkingOutput) const override;
38};
39
40void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple,
41                             const llvm::opt::ArgList &Args,
42                             std::vector<StringRef> &Features);
43
44} // end namespace amdgpu
45} // end namespace tools
46
47namespace toolchains {
48
49class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
50protected:
51  const std::map<options::ID, const StringRef> OptionsDefault;
52
53  Tool *buildLinker() const override;
54  StringRef getOptionDefault(options::ID OptID) const {
55    auto opt = OptionsDefault.find(OptID);
56    assert(opt != OptionsDefault.end() && "No Default for Option");
57    return opt->second;
58  }
59
60public:
61  AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
62                  const llvm::opt::ArgList &Args);
63  unsigned GetDefaultDwarfVersion() const override { return 5; }
64
65  bool IsMathErrnoDefault() const override { return false; }
66  bool isCrossCompiling() const override { return true; }
67  bool isPICDefault() const override { return false; }
68  bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
69    return false;
70  }
71  bool isPICDefaultForced() const override { return false; }
72  bool SupportsProfiling() const override { return false; }
73
74  llvm::opt::DerivedArgList *
75  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
76                Action::OffloadKind DeviceOffloadKind) const override;
77
78  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
79                             llvm::opt::ArgStringList &CC1Args,
80                             Action::OffloadKind DeviceOffloadKind) const override;
81
82  /// Return whether denormals should be flushed, and treated as 0 by default
83  /// for the subtarget.
84  static bool getDefaultDenormsAreZeroForTarget(llvm::AMDGPU::GPUKind GPUKind);
85
86  llvm::DenormalMode getDefaultDenormalModeForType(
87      const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
88      const llvm::fltSemantics *FPType = nullptr) const override;
89
90  static bool isWave64(const llvm::opt::ArgList &DriverArgs,
91                       llvm::AMDGPU::GPUKind Kind);
92  /// Needed for using lto.
93  bool HasNativeLLVMSupport() const override {
94    return true;
95  }
96
97  /// Needed for translating LTO options.
98  const char *getDefaultLinker() const override { return "ld.lld"; }
99
100  /// Should skip argument.
101  bool shouldSkipArgument(const llvm::opt::Arg *Arg) const;
102
103  /// Uses amdgpu-arch tool to get arch of the system GPU. Will return error
104  /// if unable to find one.
105  virtual Expected<SmallVector<std::string>>
106  getSystemGPUArchs(const llvm::opt::ArgList &Args) const override;
107
108protected:
109  /// Check and diagnose invalid target ID specified by -mcpu.
110  virtual void checkTargetID(const llvm::opt::ArgList &DriverArgs) const;
111
112  /// The struct type returned by getParsedTargetID.
113  struct ParsedTargetIDType {
114    std::optional<std::string> OptionalTargetID;
115    std::optional<std::string> OptionalGPUArch;
116    std::optional<llvm::StringMap<bool>> OptionalFeatures;
117  };
118
119  /// Get target ID, GPU arch, and target ID features if the target ID is
120  /// specified and valid.
121  ParsedTargetIDType
122  getParsedTargetID(const llvm::opt::ArgList &DriverArgs) const;
123
124  /// Get GPU arch from -mcpu without checking.
125  StringRef getGPUArch(const llvm::opt::ArgList &DriverArgs) const;
126
127};
128
129class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
130public:
131  ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
132                const llvm::opt::ArgList &Args);
133  void
134  addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
135                        llvm::opt::ArgStringList &CC1Args,
136                        Action::OffloadKind DeviceOffloadKind) const override;
137
138  // Returns a list of device library names shared by different languages
139  llvm::SmallVector<std::string, 12>
140  getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
141                          const std::string &GPUArch,
142                          bool isOpenMP = false) const;
143};
144
145} // end namespace toolchains
146} // end namespace driver
147} // end namespace clang
148
149#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
150