clang 24.0.0git
TargetUtils.cpp
Go to the documentation of this file.
1//===--- TargetUtils.cpp - Shared target-specific AST queries ---*- 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
10#include "clang/AST/Attr.h"
11#include "clang/AST/Decl.h"
12#include "clang/AST/Type.h"
17#include "llvm/ADT/APFloat.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/TargetParser/Triple.h"
20
21namespace clang::CodeGenUtils {
22
23//===----------------------------------------------------------------------===//
24// Library builtins (PowerPC64 and AIX)
25//===----------------------------------------------------------------------===//
26
27StringRef getTargetBuiltinLibFunctionName(unsigned BuiltinID,
28 const TargetInfo &Target) {
29 const llvm::Triple &Triple = Target.getTriple();
30
31 // TODO: This mutation should also be applied to other targets other than
32 // PPC, after backend supports IEEE 128-bit style libcalls.
33 if (Triple.isPPC64() &&
34 &Target.getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) {
35 // TODO: This list should be expanded or refactored after all
36 // GCC-compatible std libcall builtins are implemented.
37 static const llvm::SmallDenseMap<unsigned, StringRef, 64> F128Builtins{
38 {Builtin::BI__builtin___fprintf_chk, "__fprintf_chkieee128"},
39 {Builtin::BI__builtin___printf_chk, "__printf_chkieee128"},
40 {Builtin::BI__builtin___snprintf_chk, "__snprintf_chkieee128"},
41 {Builtin::BI__builtin___sprintf_chk, "__sprintf_chkieee128"},
42 {Builtin::BI__builtin___vfprintf_chk, "__vfprintf_chkieee128"},
43 {Builtin::BI__builtin___vprintf_chk, "__vprintf_chkieee128"},
44 {Builtin::BI__builtin___vsnprintf_chk, "__vsnprintf_chkieee128"},
45 {Builtin::BI__builtin___vsprintf_chk, "__vsprintf_chkieee128"},
46 {Builtin::BI__builtin_fprintf, "__fprintfieee128"},
47 {Builtin::BI__builtin_printf, "__printfieee128"},
48 {Builtin::BI__builtin_snprintf, "__snprintfieee128"},
49 {Builtin::BI__builtin_sprintf, "__sprintfieee128"},
50 {Builtin::BI__builtin_vfprintf, "__vfprintfieee128"},
51 {Builtin::BI__builtin_vprintf, "__vprintfieee128"},
52 {Builtin::BI__builtin_vsnprintf, "__vsnprintfieee128"},
53 {Builtin::BI__builtin_vsprintf, "__vsprintfieee128"},
54 {Builtin::BI__builtin_fscanf, "__fscanfieee128"},
55 {Builtin::BI__builtin_scanf, "__scanfieee128"},
56 {Builtin::BI__builtin_sscanf, "__sscanfieee128"},
57 {Builtin::BI__builtin_vfscanf, "__vfscanfieee128"},
58 {Builtin::BI__builtin_vscanf, "__vscanfieee128"},
59 {Builtin::BI__builtin_vsscanf, "__vsscanfieee128"},
60 {Builtin::BI__builtin_nexttowardf128, "__nexttowardieee128"},
61 };
62 return F128Builtins.lookup(BuiltinID);
63 }
64
65 // The AIX library functions frexpl, ldexpl, and modfl are for 128-bit
66 // IBM 'long double' (i.e. __ibm128). Map to the 'double' versions
67 // if it is 64-bit 'long double' mode.
68 if (Triple.isOSAIX() &&
69 &Target.getLongDoubleFormat() == &llvm::APFloat::IEEEdouble()) {
70 static const llvm::SmallDenseMap<unsigned, StringRef, 4>
71 AIXLongDouble64Builtins{
72 {Builtin::BI__builtin_frexpl, "frexp"},
73 {Builtin::BI__builtin_ldexpl, "ldexp"},
74 {Builtin::BI__builtin_modfl, "modf"},
75 };
76 return AIXLongDouble64Builtins.lookup(BuiltinID);
77 }
78
79 return StringRef();
80}
81
82//===----------------------------------------------------------------------===//
83// Arm and AArch64
84//===----------------------------------------------------------------------===//
85
86static bool isStreamingCompatible(const FunctionDecl *F) {
87 if (const auto *T = F->getType()->getAs<FunctionProtoType>())
88 return T->getAArch64SMEAttributes() &
90 return false;
91}
92
94 const FunctionDecl *Callee) {
95 bool CallerIsStreaming =
96 IsArmStreamingFunction(Caller, /*IncludeLocallyStreaming=*/true);
97 bool CalleeIsStreaming =
98 IsArmStreamingFunction(Callee, /*IncludeLocallyStreaming=*/true);
99 bool CallerIsStreamingCompatible = isStreamingCompatible(Caller);
100 bool CalleeIsStreamingCompatible = isStreamingCompatible(Callee);
101
103
104 if (!CalleeIsStreamingCompatible &&
105 (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) {
106 if (CalleeIsStreaming)
108 else
110 }
111 if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) {
112 if (NewAttr->isNewZA())
114 if (NewAttr->isNewZT0())
116 }
117
118 return Inlinability;
119}
120
121bool hasExtraNeonArgument(unsigned BuiltinID) {
122 // Required by the headers included below, but not in this particular
123 // function.
124 [[maybe_unused]] int PtrArgNum = -1;
125 [[maybe_unused]] bool HasConstPtr = false;
126
127 // The mask encodes the type. We don't care about the actual value. Instead,
128 // we just check whether its been set.
129 uint64_t mask = 0;
130 switch (BuiltinID) {
131#define GET_NEON_OVERLOAD_CHECK
132#include "clang/Basic/arm_fp16.inc"
133#include "clang/Basic/arm_neon.inc"
134#undef GET_NEON_OVERLOAD_CHECK
135 // Non-neon builtins for controling VFP that take extra argument for
136 // discriminating the type.
137 case ARM::BI__builtin_arm_vcvtr_f:
138 case ARM::BI__builtin_arm_vcvtr_d:
139 mask = 1;
140 }
141
142 return mask != 0;
143}
144
146 return TargetInfo.getABI().starts_with("aapcs");
147}
148
149//===----------------------------------------------------------------------===//
150// AMDGPU
151//===----------------------------------------------------------------------===//
152
154 bool HasHiddenVisibility) {
155 if (!HasHiddenVisibility)
156 return false;
157
158 return !D->hasAttr<OMPDeclareTargetDeclAttr>() &&
159 (D->hasAttr<DeviceKernelAttr>() ||
160 (isa<FunctionDecl>(D) && D->hasAttr<CUDAGlobalAttr>()) ||
161 (isa<VarDecl>(D) &&
162 (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
163 cast<VarDecl>(D)->getType()->isCUDADeviceBuiltinSurfaceType() ||
164 cast<VarDecl>(D)->getType()->isCUDADeviceBuiltinTextureType())));
165}
166
167//===----------------------------------------------------------------------===//
168// SPIR-V
169//===----------------------------------------------------------------------===//
170
171bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple) {
172 // LLVM address space of the SPIR-V CodeSectionINTEL storage class.
173 constexpr unsigned SPIRVCodeSectionINTELAddrSpace = 9;
177 if (AS == LangAS::Default || AS == LangAS::opencl_generic ||
179 return false;
180 // As per SPV_INTEL_function_pointers, it is illegal to addrspacecast
181 // function pointers to/from the generic AS.
182 return !(Triple.isSPIRV() && isTargetAddressSpace(AS) &&
183 toTargetAddressSpace(AS) == SPIRVCodeSectionINTELAddrSpace);
184}
185
186} // namespace clang::CodeGenUtils
Provides definitions for the various language-specific address spaces.
Defines enum values for all the target-independent builtin functions.
Enumerates target-specific builtins in their own namespaces within namespace clang.
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool hasAttr() const
Definition DeclBase.h:586
Represents a function declaration or definition.
Definition Decl.h:2071
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5416
A (possibly-)qualified type.
Definition TypeBase.h:938
LangAS getAddressSpace() const
Return the address space of this type.
Definition TypeBase.h:8572
Exposes information about the current target.
Definition TargetInfo.h:228
virtual StringRef getABI() const
Get the ABI currently in use.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:885
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9299
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
Definition Type.cpp:786
bool isNullPtrType() const
Definition TypeBase.h:9109
QualType getType() const
Definition Decl.h:725
Defines the clang::TargetInfo interface.
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
bool requiresAMDGPUProtectedVisibility(const Decl *D, bool HasHiddenVisibility)
Returns whether D must be given protected visibility on AMDGPU.
bool hasExtraNeonArgument(unsigned BuiltinID)
Returns whether the Neon builtin BuiltinID takes a trailing argument that discriminates the operand t...
bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple)
Return true if a SPIR(-V) null pointer of type QT must be materialized as an addrspacecast from a gen...
llvm::StringRef getTargetBuiltinLibFunctionName(unsigned BuiltinID, const TargetInfo &Target)
Returns the library function name that should be called for the library builtin BuiltinID when the ta...
ArmSMEInlinability
The Arm SME ABI issues that can prevent inlining one function into another.
Definition TargetUtils.h:40
static bool isStreamingCompatible(const FunctionDecl *F)
ArmSMEInlinability getArmSMEInlinability(const FunctionDecl *Caller, const FunctionDecl *Callee)
Determines if there are any Arm SME ABI issues with inlining Callee into Caller.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool isTargetAddressSpace(LangAS AS)
unsigned toTargetAddressSpace(LangAS AS)
const FunctionProtoType * T
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
Definition Address.h:327
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
Definition Decl.cpp:6196