clang 24.0.0git
SemaCUDA.h
Go to the documentation of this file.
1//===----- SemaCUDA.h ----- Semantic Analysis for CUDA constructs ---------===//
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/// \file
9/// This file declares semantic analysis for CUDA constructs.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_SEMA_SEMACUDA_H
14#define LLVM_CLANG_SEMA_SEMACUDA_H
15
16#include "clang/AST/ASTFwd.h"
19#include "clang/Basic/Cuda.h"
20#include "clang/Basic/LLVM.h"
22#include "clang/Sema/Lookup.h"
24#include "clang/Sema/SemaBase.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/DenseMapInfo.h"
27#include "llvm/ADT/DenseSet.h"
28#include "llvm/ADT/Hashing.h"
29#include "llvm/ADT/SmallVector.h"
30#include <string>
31#include <utility>
32
33namespace clang {
34namespace sema {
35class Capture;
36} // namespace sema
37
38class ASTReader;
39class ASTWriter;
40enum class CUDAFunctionTarget;
41enum class CXXSpecialMemberKind;
43class Scope;
44
45class SemaCUDA : public SemaBase {
46public:
47 SemaCUDA(Sema &S);
48
49 /// Increments our count of the number of times we've seen a pragma forcing
50 /// functions to be __host__ __device__. So long as this count is greater
51 /// than zero, all functions encountered will be __host__ __device__.
53
54 /// Decrements our count of the number of times we've seen a pragma forcing
55 /// functions to be __host__ __device__. Returns false if the count is 0
56 /// before incrementing, so you can emit an error.
57 bool PopForceHostDevice();
58
60 MultiExprArg ExecConfig,
61 SourceLocation GGGLoc);
62
63 /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the
64 /// key in a hashtable, both the FD and location are hashed.
69
70 /// FunctionDecls and SourceLocations for which CheckCall has emitted a
71 /// (maybe deferred) "bad call" diagnostic. We use this to avoid emitting the
72 /// same deferred diag twice.
73 llvm::DenseSet<FunctionDeclAndLoc> LocsWithCUDACallDiags;
74
75 /// An inverse call graph, mapping known-emitted functions to their
76 /// known-emitted callers (plus the location of the call).
77 ///
78 /// Functions that we can tell a priori must be emitted aren't added to this
79 /// map. A function may have multiple callers that force it into device
80 /// context, so we store all of them to produce complete diagnostics.
81 llvm::DenseMap</* Callee = */ CanonicalDeclPtr<const FunctionDecl>,
84
85 /// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
86 /// context is "used as device code".
87 ///
88 /// - If CurContext is a __host__ function, does not emit any diagnostics
89 /// unless \p EmitOnBothSides is true.
90 /// - If CurContext is a __device__ or __global__ function, emits the
91 /// diagnostics immediately.
92 /// - If CurContext is a __host__ __device__ function and we are compiling for
93 /// the device, creates a diagnostic which is emitted if and when we realize
94 /// that the function will be codegen'ed.
95 ///
96 /// Example usage:
97 ///
98 /// // Variable-length arrays are not allowed in CUDA device code.
99 /// if (DiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentTarget())
100 /// return ExprError();
101 /// // Otherwise, continue parsing as normal.
103
104 /// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
105 /// context is "used as host code".
106 ///
107 /// Same as DiagIfDeviceCode, with "host" and "device" switched.
109
110 /// Diagnoses a use of RTTI at \p Loc if it is in device function or the
111 /// initializer of a device variable, where RTTI is not available.
112 void checkRTTIUse(SourceLocation Loc, StringRef Op);
113
114 /// Diagnoses a use of RTTI in \p Init, the default argument or default
115 /// member initializer of \p D if it is used at \p UseLoc in device code.
116 void checkRTTIInDefaultInit(const ValueDecl *D, const Expr *Init,
117 SourceLocation UseLoc);
118
119 /// Determines whether the given function is a CUDA device/host/kernel/etc.
120 /// function.
121 ///
122 /// Use this rather than examining the function's attributes yourself -- you
123 /// will get it wrong. Returns CUDAFunctionTarget::Host if D is null.
125 bool IgnoreImplicitHDAttr = false);
127
129 CVT_Device, /// Emitted on device side with a shadow variable on host side
130 CVT_Host, /// Emitted on host side only
131 CVT_Both, /// Emitted on both sides with different addresses
132 CVT_Unified, /// Emitted as a unified address, e.g. managed variables
133 };
134 /// Determines whether the given variable is emitted on host or device side.
136
137 /// Defines kinds of CUDA global host/device context where a function may be
138 /// called.
140 CTCK_Unknown, /// Unknown context
141 CTCK_InitGlobalVar, /// Function called during global variable
142 /// initialization
143 };
144
145 /// Define the current global CUDA host/device context where a function may be
146 /// called. Only used when a function is called outside of any functions.
152
160
161 /// Gets the CUDA target for the current context.
163 return IdentifyTarget(dyn_cast<FunctionDecl>(SemaRef.CurContext));
164 }
165
166 static bool isImplicitHostDeviceFunction(const FunctionDecl *D);
167
168 // CUDA function call preference. Must be ordered numerically from
169 // worst to best.
171 CFP_Never, // Invalid caller/callee combination.
172 CFP_WrongSide, // Calls from host-device to host or device
173 // function that do not match current compilation
174 // mode.
175 CFP_HostDevice, // Any calls to host/device functions.
176 CFP_SameSide, // Calls from host-device to host or device
177 // function matching current compilation mode.
178 CFP_Native, // host-to-host or device-to-device calls.
179 };
180
181 /// Identifies relative preference of a given Caller/Callee
182 /// combination, based on their host/device attributes.
183 /// \param Caller function which needs address of \p Callee.
184 /// nullptr in case of global context.
185 /// \param Callee target function
186 ///
187 /// \returns preference value for particular Caller/Callee combination.
189 const FunctionDecl *Callee);
190
191 /// Determines whether Caller may invoke Callee, based on their CUDA
192 /// host/device attributes. Returns false if the call is not allowed.
193 ///
194 /// Note: Will return true for CFP_WrongSide calls. These may appear in
195 /// semantically correct CUDA programs, but only if they're never codegen'ed.
196 bool IsAllowedCall(const FunctionDecl *Caller, const FunctionDecl *Callee) {
197 return IdentifyPreference(Caller, Callee) != CFP_Never;
198 }
199
200 /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD,
201 /// depending on FD and the current compilation settings.
203
204 /// May add implicit CUDAConstantAttr attribute to VD, depending on VD
205 /// and current compilation settings.
207
208 /// Check whether we're allowed to call Callee from the current context.
209 ///
210 /// - If the call is never allowed in a semantically-correct program
211 /// (CFP_Never), emits an error and returns false.
212 ///
213 /// - If the call is allowed in semantically-correct programs, but only if
214 /// it's never codegen'ed (CFP_WrongSide), creates a deferred diagnostic to
215 /// be emitted if and when the caller is codegen'ed, and returns true.
216 ///
217 /// Will only create deferred diagnostics for a given SourceLocation once,
218 /// so you can safely call this multiple times without generating duplicate
219 /// deferred errors.
220 ///
221 /// - Otherwise, returns true without emitting any diagnostics.
222 bool CheckCall(SourceLocation Loc, FunctionDecl *Callee);
223
225
226 /// Set __device__ or __host__ __device__ attributes on the given lambda
227 /// operator() method.
228 ///
229 /// CUDA lambdas by default is host device function unless it has explicit
230 /// host or device attribute.
232
233 /// Record \p FD if it is a CUDA/HIP implicit host device function used on
234 /// device side in device compilation.
236
237 /// Finds a function in \p Matches with highest calling priority
238 /// from \p Caller context and erases all functions with lower
239 /// calling priority.
241 const FunctionDecl *Caller,
242 llvm::SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>>
243 &Matches);
244
245 /// Given a implicit special member, infer its CUDA target from the
246 /// calls it needs to make to underlying base/field special members.
247 /// \param ClassDecl the class for which the member is being created.
248 /// \param CSM the kind of special member.
249 /// \param MemberDecl the special member itself.
250 /// \param ConstRHS true if this is a copy operation with a const object on
251 /// its RHS.
252 /// \param Diagnose true if this call should emit diagnostics.
253 /// \return true if there was an error inferring.
254 /// The result of this call is implicit CUDA target attribute(s) attached to
255 /// the member declaration.
258 CXXMethodDecl *MemberDecl,
259 bool ConstRHS, bool Diagnose);
260
261 /// \return true if \p CD can be considered empty according to CUDA
262 /// (E.2.3.1 in CUDA 7.5 Programming guide).
265
266 // \brief Checks that initializers of \p Var satisfy CUDA restrictions. In
267 // case of error emits appropriate diagnostic and invalidates \p Var.
268 //
269 // \details CUDA allows only empty constructors as initializers for global
270 // variables (see E.2.3.1, CUDA 7.5). The same restriction also applies to all
271 // __shared__ variables whether they are local or not (they all are implicitly
272 // static in CUDA). One exception is that CUDA allows constant initializers
273 // for __constant__ and __device__ variables.
275
276 /// Check whether NewFD is a valid overload for CUDA. Emits
277 /// diagnostics and invalidates NewFD if not.
279 /// Copies target attributes from the template TD to the function FD.
281
282 /// Returns the name of the launch configuration function. This is the name
283 /// of the function that will be called to configure kernel call, with the
284 /// parameters specified via <<<>>>.
285 std::string getConfigureFuncName() const;
286 /// Return the name of the parameter buffer allocation function for the
287 /// device kernel launch.
288 std::string getGetParameterBufferFuncName() const;
289 /// Return the name of the device kernel launch function.
290 std::string getLaunchDeviceFuncName() const;
291
292 /// Record variables that are potentially ODR-used in CUDA/HIP.
294 OverloadCandidateSet &CandidateSet);
295
296 /// Null-tolerant wrapper for FunctionDecl::isImplicitHDExplicitInstantiation.
297 static bool isImplicitHDExplicitInstantiation(const FunctionDecl *FD);
298
299private:
300 unsigned ForceHostDeviceDepth = 0;
301
302 /// Whether the current context is the initializer of a device variable.
303 bool isDeviceVarInit() const;
304
305 /// The default arguments and default member initializers, paired with the
306 /// function using them.
307 llvm::DenseSet<std::pair<const ValueDecl *, const FunctionDecl *>>
308 RTTICheckedDefaultInits;
309
310 friend class ASTReader;
311 friend class ASTWriter;
312};
313
314} // namespace clang
315
316namespace llvm {
317// Hash a FunctionDeclAndLoc by looking at both its FunctionDecl and its
318// SourceLocation.
319template <> struct DenseMapInfo<clang::SemaCUDA::FunctionDeclAndLoc> {
322 DenseMapInfo<clang::CanonicalDeclPtr<const clang::FunctionDecl>>;
323
324 static unsigned getHashValue(const FunctionDeclAndLoc &FDL) {
325 return hash_combine(FDBaseInfo::getHashValue(FDL.FD),
326 FDL.Loc.getHashValue());
327 }
328
329 static bool isEqual(const FunctionDeclAndLoc &LHS,
330 const FunctionDeclAndLoc &RHS) {
331 return LHS.FD == RHS.FD && LHS.Loc == RHS.Loc;
332 }
333};
334} // namespace llvm
335
336#endif // LLVM_CLANG_SEMA_SEMACUDA_H
Forward declaration of all AST node types.
FormatToken * Previous
The previous token in the unwrapped line.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Reads an AST files chain containing the contents of a translation unit.
Definition ASTReader.h:427
Writes an AST file containing the contents of a translation unit.
Definition ASTWriter.h:98
Represents a C++ constructor within a class.
Definition DeclCXX.h:2642
Represents a C++ destructor within a class.
Definition DeclCXX.h:2907
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2150
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
A wrapper class around a pointer that always points to its canonical declaration.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:114
Represents a function declaration or definition.
Definition Decl.h:2071
Declaration of a template function.
Represents the results of name lookup.
Definition Lookup.h:147
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
Definition Overload.h:1164
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
A generic diagnostic builder for errors which may or may not be deferred.
Definition SemaBase.h:111
SemaBase(Sema &S)
Definition SemaBase.cpp:7
Sema & SemaRef
Definition SemaBase.h:40
friend class ASTWriter
Definition SemaCUDA.h:311
std::string getLaunchDeviceFuncName() const
Return the name of the device kernel launch function.
void PushForceHostDevice()
Increments our count of the number of times we've seen a pragma forcing functions to be host device.
Definition SemaCUDA.cpp:41
void checkAllowedInitializer(VarDecl *VD)
Definition SemaCUDA.cpp:745
bool IsAllowedCall(const FunctionDecl *Caller, const FunctionDecl *Callee)
Determines whether Caller may invoke Callee, based on their CUDA host/device attributes.
Definition SemaCUDA.h:196
void RecordImplicitHostDeviceFuncUsedByDevice(const FunctionDecl *FD)
Record FD if it is a CUDA/HIP implicit host device function used on device side in device compilation...
Definition SemaCUDA.cpp:840
std::string getConfigureFuncName() const
Returns the name of the launch configuration function.
bool PopForceHostDevice()
Decrements our count of the number of times we've seen a pragma forcing functions to be host device.
Definition SemaCUDA.cpp:46
CUDAFunctionTarget IdentifyTarget(const FunctionDecl *D, bool IgnoreImplicitHDAttr=false)
Determines whether the given function is a CUDA device/host/kernel/etc.
Definition SemaCUDA.cpp:212
static bool isImplicitHDExplicitInstantiation(const FunctionDecl *FD)
Null-tolerant wrapper for FunctionDecl::isImplicitHDExplicitInstantiation.
Definition SemaCUDA.cpp:406
void maybeAddHostDeviceAttrs(FunctionDecl *FD, const LookupResult &Previous)
May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, depending on FD and the current co...
Definition SemaCUDA.cpp:874
ExprResult ActOnExecConfigExpr(Scope *S, SourceLocation LLLLoc, MultiExprArg ExecConfig, SourceLocation GGGLoc)
Definition SemaCUDA.cpp:54
friend class ASTReader
Definition SemaCUDA.h:310
bool isEmptyConstructor(SourceLocation Loc, CXXConstructorDecl *CD)
Definition SemaCUDA.cpp:599
std::string getGetParameterBufferFuncName() const
Return the name of the parameter buffer allocation function for the device kernel launch.
bool isEmptyDestructor(SourceLocation Loc, CXXDestructorDecl *CD)
Definition SemaCUDA.cpp:637
void checkTargetOverload(FunctionDecl *NewFD, const LookupResult &Previous)
Check whether NewFD is a valid overload for CUDA.
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
Definition SemaCUDA.h:162
SemaDiagnosticBuilder DiagIfHostCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
Definition SemaCUDA.cpp:987
bool inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, CXXMethodDecl *MemberDecl, bool ConstRHS, bool Diagnose)
Given a implicit special member, infer its CUDA target from the calls it needs to make to underlying ...
Definition SemaCUDA.cpp:463
struct clang::SemaCUDA::CUDATargetContext CurCUDATargetCtx
CUDATargetContextKind
Defines kinds of CUDA global host/device context where a function may be called.
Definition SemaCUDA.h:139
@ CTCK_InitGlobalVar
Unknown context.
Definition SemaCUDA.h:141
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
Definition SemaCUDA.cpp:953
llvm::DenseSet< FunctionDeclAndLoc > LocsWithCUDACallDiags
FunctionDecls and SourceLocations for which CheckCall has emitted a (maybe deferred) "bad call" diagn...
Definition SemaCUDA.h:73
bool CheckCall(SourceLocation Loc, FunctionDecl *Callee)
Check whether we're allowed to call Callee from the current context.
void inheritTargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD)
Copies target attributes from the template TD to the function FD.
llvm::DenseMap< CanonicalDeclPtr< const FunctionDecl >, llvm::SmallVector< FunctionDeclAndLoc, 1 > > DeviceKnownEmittedFns
An inverse call graph, mapping known-emitted functions to their known-emitted callers (plus the locat...
Definition SemaCUDA.h:83
static bool isImplicitHostDeviceFunction(const FunctionDecl *D)
Definition SemaCUDA.cpp:400
void CheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture)
void MaybeAddConstantAttr(VarDecl *VD)
May add implicit CUDAConstantAttr attribute to VD, depending on VD and current compilation settings.
Definition SemaCUDA.cpp:939
void EraseUnwantedMatches(const FunctionDecl *Caller, llvm::SmallVectorImpl< std::pair< DeclAccessPair, FunctionDecl * > > &Matches)
Finds a function in Matches with highest calling priority from Caller context and erases all function...
Definition SemaCUDA.cpp:410
SemaCUDA(Sema &S)
Definition SemaCUDA.cpp:31
void checkRTTIInDefaultInit(const ValueDecl *D, const Expr *Init, SourceLocation UseLoc)
Diagnoses a use of RTTI in Init, the default argument or default member initializer of D if it is use...
void SetLambdaAttrs(CXXMethodDecl *Method)
Set device or host device attributes on the given lambda operator() method.
void checkRTTIUse(SourceLocation Loc, StringRef Op)
Diagnoses a use of RTTI at Loc if it is in device function or the initializer of a device variable,...
CUDAFunctionPreference IdentifyPreference(const FunctionDecl *Caller, const FunctionDecl *Callee)
Identifies relative preference of a given Caller/Callee combination, based on their host/device attri...
Definition SemaCUDA.cpp:312
void recordPotentialODRUsedVariable(MultiExprArg Args, OverloadCandidateSet &CandidateSet)
Record variables that are potentially ODR-used in CUDA/HIP.
@ CVT_Host
Emitted on device side with a shadow variable on host side.
Definition SemaCUDA.h:130
@ CVT_Both
Emitted on host side only.
Definition SemaCUDA.h:131
@ CVT_Unified
Emitted on both sides with different addresses.
Definition SemaCUDA.h:132
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:862
Encodes a location in the source.
unsigned getHashValue() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:714
Represents a variable declaration or definition.
Definition Decl.h:934
Top level wrappers for InstallAPI frontend operations.
CUDAFunctionTarget
Definition Cuda.h:65
MutableArrayRef< Expr * > MultiExprArg
Definition Ownership.h:259
CXXSpecialMemberKind
Kinds of C++ special members.
Definition Decl.h:2031
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
SemaCUDA::CUDATargetContext SavedCtx
Definition SemaCUDA.h:155
CUDATargetContextRAII(SemaCUDA &S_, SemaCUDA::CUDATargetContextKind K, Decl *D)
Definition SemaCUDA.cpp:194
Define the current global CUDA host/device context where a function may be called.
Definition SemaCUDA.h:147
CUDATargetContextKind Kind
Definition SemaCUDA.h:149
A pair of a canonical FunctionDecl and a SourceLocation.
Definition SemaCUDA.h:65
CanonicalDeclPtr< const FunctionDecl > FD
Definition SemaCUDA.h:66
DenseMapInfo< clang::CanonicalDeclPtr< const clang::FunctionDecl > > FDBaseInfo
Definition SemaCUDA.h:321
static unsigned getHashValue(const FunctionDeclAndLoc &FDL)
Definition SemaCUDA.h:324
clang::SemaCUDA::FunctionDeclAndLoc FunctionDeclAndLoc
Definition SemaCUDA.h:320
static bool isEqual(const FunctionDeclAndLoc &LHS, const FunctionDeclAndLoc &RHS)
Definition SemaCUDA.h:329