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 "llvm/TargetParser/TargetParser.h"
17
18 using namespace clang;
19 using namespace clang::targets;
20
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const21 void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,
22 MacroBuilder &Builder) const {
23 DefineStd(Builder, "SPIR", Opts);
24 }
25
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const26 void SPIR32TargetInfo::getTargetDefines(const LangOptions &Opts,
27 MacroBuilder &Builder) const {
28 SPIRTargetInfo::getTargetDefines(Opts, Builder);
29 DefineStd(Builder, "SPIR32", Opts);
30 }
31
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const32 void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts,
33 MacroBuilder &Builder) const {
34 SPIRTargetInfo::getTargetDefines(Opts, Builder);
35 DefineStd(Builder, "SPIR64", Opts);
36 }
37
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const38 void BaseSPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
39 MacroBuilder &Builder) const {
40 DefineStd(Builder, "SPIRV", Opts);
41 }
42
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const43 void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
44 MacroBuilder &Builder) const {
45 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
46 }
47
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const48 void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts,
49 MacroBuilder &Builder) const {
50 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
51 DefineStd(Builder, "SPIRV32", Opts);
52 }
53
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const54 void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,
55 MacroBuilder &Builder) const {
56 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
57 DefineStd(Builder, "SPIRV64", Opts);
58 }
59
60 static const AMDGPUTargetInfo AMDGPUTI(llvm::Triple("amdgcn-amd-amdhsa"), {});
61
getGCCRegNames() const62 ArrayRef<const char *> SPIRV64AMDGCNTargetInfo::getGCCRegNames() const {
63 return AMDGPUTI.getGCCRegNames();
64 }
65
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef,const std::vector<std::string> & FeatureVec) const66 bool SPIRV64AMDGCNTargetInfo::initFeatureMap(
67 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef,
68 const std::vector<std::string> &FeatureVec) const {
69 llvm::AMDGPU::fillAMDGPUFeatureMap({}, getTriple(), Features);
70
71 return TargetInfo::initFeatureMap(Features, Diags, {}, FeatureVec);
72 }
73
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const74 bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint(
75 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
76 return AMDGPUTI.validateAsmConstraint(Name, Info);
77 }
78
79 std::string
convertConstraint(const char * & Constraint) const80 SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const {
81 return AMDGPUTI.convertConstraint(Constraint);
82 }
83
getTargetBuiltins() const84 ArrayRef<Builtin::Info> SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
85 return AMDGPUTI.getTargetBuiltins();
86 }
87
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const88 void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts,
89 MacroBuilder &Builder) const {
90 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
91 DefineStd(Builder, "SPIRV64", Opts);
92
93 Builder.defineMacro("__AMD__");
94 Builder.defineMacro("__AMDGPU__");
95 Builder.defineMacro("__AMDGCN__");
96 }
97
setAuxTarget(const TargetInfo * Aux)98 void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) {
99 assert(Aux && "Cannot invoke setAuxTarget without a valid auxiliary target!");
100
101 // This is a 1:1 copy of AMDGPUTargetInfo::setAuxTarget()
102 assert(HalfFormat == Aux->HalfFormat);
103 assert(FloatFormat == Aux->FloatFormat);
104 assert(DoubleFormat == Aux->DoubleFormat);
105
106 // On x86_64 long double is 80-bit extended precision format, which is
107 // not supported by AMDGPU. 128-bit floating point format is also not
108 // supported by AMDGPU. Therefore keep its own format for these two types.
109 auto SaveLongDoubleFormat = LongDoubleFormat;
110 auto SaveFloat128Format = Float128Format;
111 auto SaveLongDoubleWidth = LongDoubleWidth;
112 auto SaveLongDoubleAlign = LongDoubleAlign;
113 copyAuxTarget(Aux);
114 LongDoubleFormat = SaveLongDoubleFormat;
115 Float128Format = SaveFloat128Format;
116 LongDoubleWidth = SaveLongDoubleWidth;
117 LongDoubleAlign = SaveLongDoubleAlign;
118 // For certain builtin types support on the host target, claim they are
119 // supported to pass the compilation of the host code during the device-side
120 // compilation.
121 // FIXME: As the side effect, we also accept `__float128` uses in the device
122 // code. To reject these builtin types supported in the host target but not in
123 // the device target, one approach would support `device_builtin` attribute
124 // so that we could tell the device builtin types from the host ones. This
125 // also solves the different representations of the same builtin type, such
126 // as `size_t` in the MSVC environment.
127 if (Aux->hasFloat128Type()) {
128 HasFloat128 = true;
129 Float128Format = DoubleFormat;
130 }
131 }
132