184 lines · cpp
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-exception6//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 "clang/Basic/MacroBuilder.h"16#include "clang/Basic/TargetBuiltins.h"17#include "llvm/TargetParser/TargetParser.h"18 19using namespace clang;20using namespace clang::targets;21 22static constexpr int NumBuiltins =23 clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin;24 25#define GET_BUILTIN_STR_TABLE26#include "clang/Basic/BuiltinsSPIRVCommon.inc"27#undef GET_BUILTIN_STR_TABLE28 29static constexpr Builtin::Info BuiltinInfos[] = {30#define GET_BUILTIN_INFOS31#include "clang/Basic/BuiltinsSPIRVCommon.inc"32#undef GET_BUILTIN_INFOS33};34 35namespace CL {36#define GET_BUILTIN_STR_TABLE37#include "clang/Basic/BuiltinsSPIRVCL.inc"38#undef GET_BUILTIN_STR_TABLE39 40static constexpr Builtin::Info BuiltinInfos[] = {41#define GET_BUILTIN_INFOS42#include "clang/Basic/BuiltinsSPIRVCL.inc"43#undef GET_BUILTIN_INFOS44};45} // namespace CL46 47namespace VK {48#define GET_BUILTIN_STR_TABLE49#include "clang/Basic/BuiltinsSPIRVVK.inc"50#undef GET_BUILTIN_STR_TABLE51 52static constexpr Builtin::Info BuiltinInfos[] = {53#define GET_BUILTIN_INFOS54#include "clang/Basic/BuiltinsSPIRVVK.inc"55#undef GET_BUILTIN_INFOS56};57} // namespace VK58 59static_assert(std::size(BuiltinInfos) + std::size(CL::BuiltinInfos) +60 std::size(VK::BuiltinInfos) ==61 NumBuiltins);62 63llvm::SmallVector<Builtin::InfosShard>64BaseSPIRVTargetInfo::getTargetBuiltins() const {65 return {{&BuiltinStrings, BuiltinInfos},66 {&VK::BuiltinStrings, VK::BuiltinInfos},67 {&CL::BuiltinStrings, CL::BuiltinInfos}};68}69 70void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,71 MacroBuilder &Builder) const {72 DefineStd(Builder, "SPIR", Opts);73}74 75void SPIR32TargetInfo::getTargetDefines(const LangOptions &Opts,76 MacroBuilder &Builder) const {77 SPIRTargetInfo::getTargetDefines(Opts, Builder);78 DefineStd(Builder, "SPIR32", Opts);79}80 81void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts,82 MacroBuilder &Builder) const {83 SPIRTargetInfo::getTargetDefines(Opts, Builder);84 DefineStd(Builder, "SPIR64", Opts);85}86 87void BaseSPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,88 MacroBuilder &Builder) const {89 DefineStd(Builder, "SPIRV", Opts);90 if (Opts.HLSL)91 DefineStd(Builder, "spirv", Opts);92}93 94void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,95 MacroBuilder &Builder) const {96 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);97}98 99void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts,100 MacroBuilder &Builder) const {101 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);102 DefineStd(Builder, "SPIRV32", Opts);103}104 105void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,106 MacroBuilder &Builder) const {107 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);108 DefineStd(Builder, "SPIRV64", Opts);109}110 111static const AMDGPUTargetInfo AMDGPUTI(llvm::Triple("amdgcn-amd-amdhsa"), {});112 113ArrayRef<const char *> SPIRV64AMDGCNTargetInfo::getGCCRegNames() const {114 return AMDGPUTI.getGCCRegNames();115}116 117bool SPIRV64AMDGCNTargetInfo::initFeatureMap(118 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef,119 const std::vector<std::string> &FeatureVec) const {120 llvm::AMDGPU::fillAMDGPUFeatureMap({}, getTriple(), Features);121 122 return TargetInfo::initFeatureMap(Features, Diags, {}, FeatureVec);123}124 125bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint(126 const char *&Name, TargetInfo::ConstraintInfo &Info) const {127 return AMDGPUTI.validateAsmConstraint(Name, Info);128}129 130std::string131SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const {132 return AMDGPUTI.convertConstraint(Constraint);133}134 135llvm::SmallVector<Builtin::InfosShard>136SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {137 return AMDGPUTI.getTargetBuiltins();138}139 140void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts,141 MacroBuilder &Builder) const {142 BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);143 DefineStd(Builder, "SPIRV64", Opts);144 145 Builder.defineMacro("__AMD__");146 Builder.defineMacro("__AMDGPU__");147 Builder.defineMacro("__AMDGCN__");148}149 150void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) {151 assert(Aux && "Cannot invoke setAuxTarget without a valid auxiliary target!");152 153 // This is a 1:1 copy of AMDGPUTargetInfo::setAuxTarget()154 assert(HalfFormat == Aux->HalfFormat);155 assert(FloatFormat == Aux->FloatFormat);156 assert(DoubleFormat == Aux->DoubleFormat);157 158 // On x86_64 long double is 80-bit extended precision format, which is159 // not supported by AMDGPU. 128-bit floating point format is also not160 // supported by AMDGPU. Therefore keep its own format for these two types.161 auto SaveLongDoubleFormat = LongDoubleFormat;162 auto SaveFloat128Format = Float128Format;163 auto SaveLongDoubleWidth = LongDoubleWidth;164 auto SaveLongDoubleAlign = LongDoubleAlign;165 copyAuxTarget(Aux);166 LongDoubleFormat = SaveLongDoubleFormat;167 Float128Format = SaveFloat128Format;168 LongDoubleWidth = SaveLongDoubleWidth;169 LongDoubleAlign = SaveLongDoubleAlign;170 // For certain builtin types support on the host target, claim they are171 // supported to pass the compilation of the host code during the device-side172 // compilation.173 // FIXME: As the side effect, we also accept `__float128` uses in the device174 // code. To reject these builtin types supported in the host target but not in175 // the device target, one approach would support `device_builtin` attribute176 // so that we could tell the device builtin types from the host ones. This177 // also solves the different representations of the same builtin type, such178 // as `size_t` in the MSVC environment.179 if (Aux->hasFloat128Type()) {180 HasFloat128 = true;181 Float128Format = DoubleFormat;182 }183}184