clang 24.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
49 const auto *rd = t->getAsRecordDecl();
50 if (!rd)
51 return false;
52 if (rd->hasFlexibleArrayMember())
53 return false;
54
55 if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
56 // A vtable pointer is neither a base nor a field, so clang's predicate
57 // calls a polymorphic class empty and leans on its callers rejecting one as
58 // non-trivially-copyable beforehand. This answer is read off the record
59 // type without that precondition, so rule it out here instead.
60 if (cxxrd->isDynamicClass())
61 return false;
62
63 for (const auto &i : cxxrd->bases())
64 if (!isEmptyRecordForABI(context, i.getType()))
65 return false;
66 }
67
68 for (const auto *i : rd->fields())
69 if (!isEmptyFieldForABI(context, i))
70 return false;
71 return true;
72}
73
75 const FieldDecl *fd) {
76 // A zero-width bit-field holds no bits, so it holds no data. Any other
77 // unnamed bit-field is real storage that the x86-64 classifier gives the
78 // eightbyte classes of a named bit-field, so it does hold data.
79 //
80 // FIXME: this needs an ABI compatibility check. Clang used to ignore every
81 // unnamed bit-field here, and the older compatibility levels have to keep
82 // that answer once there is a switch to ask.
83 if (fd->isUnnamedBitField())
84 return fd->isZeroLengthBitField();
85
86 QualType ft = fd->getType();
87
88 // An array of empty records is empty, and a zero-length array always is.
89 bool wasArray = false;
90 while (const ConstantArrayType *at = context.getAsConstantArrayType(ft)) {
91 if (at->isZeroSize())
92 return true;
93 ft = at->getElementType();
94 wasArray = true;
95 }
96
97 const auto *rt = ft->getAsCanonical<RecordType>();
98 if (!rt)
99 return false;
100
101 // A C++ record field is never empty under the Itanium ABI unless
102 // [[no_unique_address]] makes it so, and that exception covers a record
103 // rather than an array of them.
104 if (isa<CXXRecordDecl>(rt->getDecl()) &&
105 (wasArray || !fd->hasAttr<NoUniqueAddressAttr>()))
106 return false;
107
108 return isEmptyRecordForABI(context, ft);
109}
110
111namespace {
112
113class AMDGPUABIInfo : public ABIInfo {
114public:
115 AMDGPUABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
116};
117
118class AMDGPUTargetCIRGenInfo : public TargetCIRGenInfo {
119public:
120 AMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
121 : TargetCIRGenInfo(std::make_unique<AMDGPUABIInfo>(cgt)) {}
122
123 bool supportsLibCall() const override { return false; }
124
125 void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global,
126 CIRGenModule &cgm) const override {
127 if (auto func = mlir::dyn_cast<cir::FuncOp>(global)) {
128 if (requiresAMDGPUProtectedVisibility(decl, func.getGlobalVisibility())) {
129 func.setGlobalVisibility(cir::VisibilityKind::Protected);
130 func.setDSOLocal(true);
131 }
133 } else if (auto gv = mlir::dyn_cast<cir::GlobalOp>(global)) {
134 if (requiresAMDGPUProtectedVisibility(decl, gv.getGlobalVisibility())) {
135 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
136 gv.setDSOLocal(true);
137 }
138 }
139 }
140
142 getGlobalVarAddressSpace(CIRGenModule &cgm,
143 const clang::VarDecl *decl) const override {
144 using clang::LangAS;
145 assert(!cgm.getLangOpts().OpenCL &&
146 !(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
147 "Address space agnostic languages only");
148 LangAS defaultGlobalAS = LangAS::opencl_global;
149 if (!decl)
150 return defaultGlobalAS;
151
152 LangAS addrSpace = decl->getType().getAddressSpace();
153 if (addrSpace != LangAS::Default)
154 return addrSpace;
155
156 // Only promote to address space 4 if VarDecl has constant initialization.
157 if (decl->getType().isConstantStorage(cgm.getASTContext(), false, false) &&
158 decl->hasConstantInitialization())
159 return LangAS::opencl_constant;
160
161 return defaultGlobalAS;
162 }
163
164 mlir::ptr::MemorySpaceAttrInterface
165 getCIRAllocaAddressSpace() const override {
166 return cir::LangAddressSpaceAttr::get(
167 &getABIInfo().cgt.getMLIRContext(),
168 cir::LangAddressSpace::OffloadPrivate);
169 }
170};
171
172} // namespace
173
174namespace {
175
176class X8664ABIInfo : public ABIInfo {
177public:
178 X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
179};
180
181class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
182public:
183 X8664TargetCIRGenInfo(CIRGenTypes &cgt)
184 : TargetCIRGenInfo(std::make_unique<X8664ABIInfo>(cgt)) {}
185};
186} // namespace
187
188std::unique_ptr<TargetCIRGenInfo>
190 return std::make_unique<AMDGPUTargetCIRGenInfo>(cgt);
191}
192
193std::unique_ptr<TargetCIRGenInfo>
195 return std::make_unique<X8664TargetCIRGenInfo>(cgt);
196}
197
198ABIInfo::~ABIInfo() noexcept = default;
199
201 const FunctionNoProtoType *fnType) const {
202 // The following conventions are known to require this to be false:
203 // x86_stdcall
204 // MIPS
205 // For everything else, we just prefer false unless we opt out.
206 return false;
207}
208
210 // Device kernels are entered through a runtime API, not called as normal
211 // sub-functions, so a modified C calling convention is used.
212 assert(getABIInfo().cgt.getASTContext().getLangOpts().OpenCL &&
213 "Kernel calling convention only defined for OpenCL");
214 return cir::CallingConv::C;
215}
216
219 const clang::VarDecl *d) const {
220 assert(!cgm.getLangOpts().OpenCL &&
221 !(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
222 "Address space agnostic languages only");
223 return d ? d->getType().getAddressSpace() : LangAS::Default;
224}
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:239
const ConstantArrayType * getAsConstantArrayType(QualType T) const
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:51
const ABIInfo & getABIInfo() const
Returns ABI info helper for the target.
Definition TargetInfo.h:65
TargetCIRGenInfo(std::unique_ptr< ABIInfo > info)
Definition TargetInfo.h:60
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 cir::CallingConv getDeviceKernelCallingConv() const
Returns the calling convention used for device kernels on this target.
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 the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3843
bool hasAttr() const
Definition DeclBase.h:585
Represents a member of a struct/union/class.
Definition Decl.h:3295
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition Decl.h:3401
bool isZeroLengthBitField() const
Is this a zero-length bit-field?
Definition Decl.cpp:4825
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4968
A (possibly-)qualified type.
Definition TypeBase.h:938
LangAS getAddressSpace() const
Return the address space of this type.
Definition TypeBase.h:8584
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2998
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
void setAMDGPUTargetFunctionAttributes(const clang::Decl *decl, cir::FuncOp func, CIRGenModule &cgm)
Set AMDGPU-specific function attributes for HIP kernels.
Definition AMDGPU.cpp:228
bool isEmptyRecordForABI(const ASTContext &context, QualType t)
isEmptyRecordForABI - Return true if a structure contains only empty base classes and fields.
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
bool isEmptyFieldForABI(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForABI - Return true if the field is "empty", that is, it is a zero-width bit-field or an...
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
LangAS
Defines the address space values used by the address space qualifier of QualType.