xref: /llvm-project/clang/lib/Basic/Targets/SPIR.cpp (revision 21edac25f09faee23015c6a69d95fcbda287efe2)
1 //===--- SPIR.cpp - Implement SPIR and SPIR-V target feature support ------===//
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 // This file implements SPIR and SPIR-V TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "SPIR.h"
14 #include "AMDGPU.h"
15 #include "Targets.h"
16 #include "clang/Basic/MacroBuilder.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/TargetParser/TargetParser.h"
19 
20 using namespace clang;
21 using namespace clang::targets;
22 
23 static constexpr Builtin::Info BuiltinInfo[] = {
24 #define BUILTIN(ID, TYPE, ATTRS)                                               \
25   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
26 #include "clang/Basic/BuiltinsSPIRV.inc"
27 };
28 
29 ArrayRef<Builtin::Info> SPIRVTargetInfo::getTargetBuiltins() const {
30   return llvm::ArrayRef(BuiltinInfo,
31                         clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin);
32 }
33 
34 void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,
35                                       MacroBuilder &Builder) const {
36   DefineStd(Builder, "SPIR", Opts);
37 }
38 
39 void SPIR32TargetInfo::getTargetDefines(const LangOptions &Opts,
40                                         MacroBuilder &Builder) const {
41   SPIRTargetInfo::getTargetDefines(Opts, Builder);
42   DefineStd(Builder, "SPIR32", Opts);
43 }
44 
45 void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts,
46                                         MacroBuilder &Builder) const {
47   SPIRTargetInfo::getTargetDefines(Opts, Builder);
48   DefineStd(Builder, "SPIR64", Opts);
49 }
50 
51 void BaseSPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
52                                            MacroBuilder &Builder) const {
53   DefineStd(Builder, "SPIRV", Opts);
54 }
55 
56 void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
57                                        MacroBuilder &Builder) const {
58   BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
59 }
60 
61 void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts,
62                                          MacroBuilder &Builder) const {
63   BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
64   DefineStd(Builder, "SPIRV32", Opts);
65 }
66 
67 void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,
68                                          MacroBuilder &Builder) const {
69   BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
70   DefineStd(Builder, "SPIRV64", Opts);
71 }
72 
73 static const AMDGPUTargetInfo AMDGPUTI(llvm::Triple("amdgcn-amd-amdhsa"), {});
74 
75 ArrayRef<const char *> SPIRV64AMDGCNTargetInfo::getGCCRegNames() const {
76   return AMDGPUTI.getGCCRegNames();
77 }
78 
79 bool SPIRV64AMDGCNTargetInfo::initFeatureMap(
80     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef,
81     const std::vector<std::string> &FeatureVec) const {
82   llvm::AMDGPU::fillAMDGPUFeatureMap({}, getTriple(), Features);
83 
84   return TargetInfo::initFeatureMap(Features, Diags, {}, FeatureVec);
85 }
86 
87 bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint(
88     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
89   return AMDGPUTI.validateAsmConstraint(Name, Info);
90 }
91 
92 std::string
93 SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const {
94   return AMDGPUTI.convertConstraint(Constraint);
95 }
96 
97 ArrayRef<Builtin::Info> SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
98   return AMDGPUTI.getTargetBuiltins();
99 }
100 
101 void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts,
102                                                MacroBuilder &Builder) const {
103   BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
104   DefineStd(Builder, "SPIRV64", Opts);
105 
106   Builder.defineMacro("__AMD__");
107   Builder.defineMacro("__AMDGPU__");
108   Builder.defineMacro("__AMDGCN__");
109 }
110 
111 void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) {
112   assert(Aux && "Cannot invoke setAuxTarget without a valid auxiliary target!");
113 
114   // This is a 1:1 copy of AMDGPUTargetInfo::setAuxTarget()
115   assert(HalfFormat == Aux->HalfFormat);
116   assert(FloatFormat == Aux->FloatFormat);
117   assert(DoubleFormat == Aux->DoubleFormat);
118 
119   // On x86_64 long double is 80-bit extended precision format, which is
120   // not supported by AMDGPU. 128-bit floating point format is also not
121   // supported by AMDGPU. Therefore keep its own format for these two types.
122   auto SaveLongDoubleFormat = LongDoubleFormat;
123   auto SaveFloat128Format = Float128Format;
124   auto SaveLongDoubleWidth = LongDoubleWidth;
125   auto SaveLongDoubleAlign = LongDoubleAlign;
126   copyAuxTarget(Aux);
127   LongDoubleFormat = SaveLongDoubleFormat;
128   Float128Format = SaveFloat128Format;
129   LongDoubleWidth = SaveLongDoubleWidth;
130   LongDoubleAlign = SaveLongDoubleAlign;
131   // For certain builtin types support on the host target, claim they are
132   // supported to pass the compilation of the host code during the device-side
133   // compilation.
134   // FIXME: As the side effect, we also accept `__float128` uses in the device
135   // code. To reject these builtin types supported in the host target but not in
136   // the device target, one approach would support `device_builtin` attribute
137   // so that we could tell the device builtin types from the host ones. This
138   // also solves the different representations of the same builtin type, such
139   // as `size_t` in the MSVC environment.
140   if (Aux->hasFloat128Type()) {
141     HasFloat128 = true;
142     Float128Format = DoubleFormat;
143   }
144 }
145