clang 23.0.0git
TargetInfo.cpp
Go to the documentation of this file.
1#include "TargetInfo.h"
2#include "ABIInfo.h"
3#include "CIRGenFunction.h"
4#include "CIRGenModule.h"
5#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
10
11using namespace clang;
12using namespace clang::CIRGen;
13
15 QualType t) {
16 const auto *rd = t->getAsRecordDecl();
17 if (!rd)
18 return false;
19
20 // If this is a C++ record, check the bases first.
21 if (const CXXRecordDecl *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
22 if (cxxrd->isDynamicClass())
23 return false;
24
25 for (const auto &i : cxxrd->bases())
26 if (!isEmptyRecordForLayout(context, i.getType()))
27 return false;
28 }
29
30 for (const auto *i : rd->fields())
31 if (!isEmptyFieldForLayout(context, i))
32 return false;
33
34 return true;
35}
36
38 const FieldDecl *fd) {
39 if (fd->isZeroLengthBitField())
40 return true;
41
42 if (fd->isUnnamedBitField())
43 return false;
44
45 return isEmptyRecordForLayout(context, fd->getType());
46}
47
48namespace {
49
50class AMDGPUABIInfo : public ABIInfo {
51public:
52 AMDGPUABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
53};
54
55class AMDGPUTargetCIRGenInfo : public TargetCIRGenInfo {
56public:
57 AMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
58 : TargetCIRGenInfo(std::make_unique<AMDGPUABIInfo>(cgt)) {}
59
60 bool supportsLibCall() const override { return false; }
61
62 void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global,
63 CIRGenModule &cgm) const override {
64 if (auto func = mlir::dyn_cast<cir::FuncOp>(global)) {
65 if (requiresAMDGPUProtectedVisibility(decl, func.getGlobalVisibility())) {
66 func.setGlobalVisibility(cir::VisibilityKind::Protected);
67 func.setDSOLocal(true);
68 }
70 } else if (auto gv = mlir::dyn_cast<cir::GlobalOp>(global)) {
71 if (requiresAMDGPUProtectedVisibility(decl, gv.getGlobalVisibility())) {
72 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
73 gv.setDSOLocal(true);
74 }
75 }
76 }
77
79 getGlobalVarAddressSpace(CIRGenModule &cgm,
80 const clang::VarDecl *decl) const override {
81 using clang::LangAS;
82 assert(!cgm.getLangOpts().OpenCL &&
83 !(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
84 "Address space agnostic languages only");
85 LangAS defaultGlobalAS = LangAS::opencl_global;
86 if (!decl)
87 return defaultGlobalAS;
88
89 LangAS addrSpace = decl->getType().getAddressSpace();
90 if (addrSpace != LangAS::Default)
91 return addrSpace;
92
93 // Only promote to address space 4 if VarDecl has constant initialization.
94 if (decl->getType().isConstantStorage(cgm.getASTContext(), false, false) &&
95 decl->hasConstantInitialization())
96 return LangAS::opencl_constant;
97
98 return defaultGlobalAS;
99 }
100
101 mlir::ptr::MemorySpaceAttrInterface
102 getCIRAllocaAddressSpace() const override {
103 return cir::LangAddressSpaceAttr::get(
104 &getABIInfo().cgt.getMLIRContext(),
105 cir::LangAddressSpace::OffloadPrivate);
106 }
107};
108
109} // namespace
110
111namespace {
112
113class X8664ABIInfo : public ABIInfo {
114public:
115 X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
116};
117
118class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
119public:
120 X8664TargetCIRGenInfo(CIRGenTypes &cgt)
121 : TargetCIRGenInfo(std::make_unique<X8664ABIInfo>(cgt)) {}
122};
123} // namespace
124
125namespace {
126
127class NVPTXABIInfo : public ABIInfo {
128public:
129 NVPTXABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
130};
131
132class NVPTXTargetCIRGenInfo : public TargetCIRGenInfo {
133public:
134 NVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
135 : TargetCIRGenInfo(std::make_unique<NVPTXABIInfo>(cgt)) {}
136
137 void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global,
138 CIRGenModule &cgm) const override {
139 auto globalValue = mlir::dyn_cast<cir::CIRGlobalValueInterface>(global);
140 if (globalValue && globalValue.isDeclaration())
141 return;
142
143 const auto *vd = dyn_cast_or_null<VarDecl>(decl);
144 if (vd) {
145 if (cgm.getLangOpts().CUDA) {
146 if (vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
147 vd->getType()->isCUDADeviceBuiltinTextureType())
149 return;
150 }
151 }
152
153 const auto *fd = dyn_cast_or_null<FunctionDecl>(decl);
154 if (!fd)
155 return;
156
157 auto func = mlir::cast<cir::FuncOp>(global);
158
159 // Perform special handling in OpenCL/CUDA mode.
160 if (cgm.getLangOpts().OpenCL || cgm.getLangOpts().CUDA) {
161 // Use function attributes to check for kernel functions. By default, all
162 // functions are device functions.
163 if (fd->hasAttr<DeviceKernelAttr>() || fd->hasAttr<CUDAGlobalAttr>()) {
164 // OpenCL/CUDA kernel functions get kernel metadata. Kernel functions
165 // are also not subject to inlining.
166 func.setInlineKind(cir::InlineKind::NoInline);
167 if (fd->hasAttr<CUDAGlobalAttr>()) {
168 func.setCallingConv(cir::CallingConv::PTXKernel);
170 }
171 if (fd->hasAttr<CUDALaunchBoundsAttr>())
173 }
174 }
175 }
176};
177} // namespace
178
179std::unique_ptr<TargetCIRGenInfo>
181 return std::make_unique<AMDGPUTargetCIRGenInfo>(cgt);
182}
183
184std::unique_ptr<TargetCIRGenInfo>
186 return std::make_unique<NVPTXTargetCIRGenInfo>(cgt);
187}
188
189std::unique_ptr<TargetCIRGenInfo>
191 return std::make_unique<X8664TargetCIRGenInfo>(cgt);
192}
193
194ABIInfo::~ABIInfo() noexcept = default;
195
197 const FunctionNoProtoType *fnType) const {
198 // The following conventions are known to require this to be false:
199 // x86_stdcall
200 // MIPS
201 // For everything else, we just prefer false unless we opt out.
202 return false;
203}
204
207 const clang::VarDecl *d) const {
208 assert(!cgm.getLangOpts().OpenCL &&
209 !(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
210 "Address space agnostic languages only");
211 return d ? d->getType().getAddressSpace() : LangAS::Default;
212}
Provides definitions for the various language-specific address spaces.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
This class organizes the cross-function state that is used while generating CIR code.
clang::ASTContext & getASTContext() const
const clang::LangOptions & getLangOpts() const
This class organizes the cross-module state that is used while lowering AST types to CIR types.
Definition CIRGenTypes.h:50
TargetCIRGenInfo(std::unique_ptr< ABIInfo > info)
Definition TargetInfo.h:46
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual bool isNoProtoCallVariadic(const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Represents a member of a struct/union/class.
Definition Decl.h:3178
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition Decl.h:3284
bool isZeroLengthBitField() const
Is this a zero-length bit-field?
Definition Decl.cpp:4756
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4940
A (possibly-)qualified type.
Definition TypeBase.h:937
LangAS getAddressSpace() const
Return the address space of this type.
Definition TypeBase.h:8562
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:924
void setAMDGPUTargetFunctionAttributes(const clang::Decl *decl, cir::FuncOp func, CIRGenModule &cgm)
Set AMDGPU-specific function attributes for HIP kernels.
Definition AMDGPU.cpp:228
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
bool isEmptyRecordForLayout(const ASTContext &context, QualType t)
isEmptyRecordForLayout - Return true if a structure contains only empty base classes (per isEmptyReco...
bool requiresAMDGPUProtectedVisibility(const clang::Decl *d, cir::VisibilityKind visibility)
Check if AMDGPU protected visibility is required.
Definition AMDGPU.cpp:26
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
LangAS
Defines the address space values used by the address space qualifier of QualType.
static bool emitNVVMMetadata()
static bool handleCUDALaunchBoundsAttr()
static bool opFuncParameterAttributes()