1 | //===----- CGCUDARuntime.h - Interface to CUDA Runtimes ---------*- 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 | // |
9 | // This provides an abstract class for CUDA code generation. Concrete |
10 | // subclasses of this implement code generation for specific CUDA |
11 | // runtime libraries. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H |
16 | #define LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H |
17 | |
18 | #include "clang/AST/GlobalDecl.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/Frontend/Offloading/Utility.h" |
21 | #include "llvm/IR/GlobalValue.h" |
22 | |
23 | namespace llvm { |
24 | class CallBase; |
25 | class Function; |
26 | class GlobalVariable; |
27 | } |
28 | |
29 | namespace clang { |
30 | |
31 | class CUDAKernelCallExpr; |
32 | class NamedDecl; |
33 | class VarDecl; |
34 | |
35 | namespace CodeGen { |
36 | |
37 | class CodeGenFunction; |
38 | class CodeGenModule; |
39 | class FunctionArgList; |
40 | class ReturnValueSlot; |
41 | class RValue; |
42 | |
43 | class CGCUDARuntime { |
44 | protected: |
45 | CodeGenModule &CGM; |
46 | |
47 | public: |
48 | // Global variable properties that must be passed to CUDA runtime. |
49 | class DeviceVarFlags { |
50 | public: |
51 | enum DeviceVarKind { |
52 | Variable, // Variable |
53 | Surface, // Builtin surface |
54 | Texture, // Builtin texture |
55 | }; |
56 | |
57 | private: |
58 | LLVM_PREFERRED_TYPE(DeviceVarKind) |
59 | unsigned Kind : 2; |
60 | LLVM_PREFERRED_TYPE(bool) |
61 | unsigned Extern : 1; |
62 | LLVM_PREFERRED_TYPE(bool) |
63 | unsigned Constant : 1; // Constant variable. |
64 | LLVM_PREFERRED_TYPE(bool) |
65 | unsigned Managed : 1; // Managed variable. |
66 | LLVM_PREFERRED_TYPE(bool) |
67 | unsigned Normalized : 1; // Normalized texture. |
68 | int SurfTexType; // Type of surface/texutre. |
69 | |
70 | public: |
71 | DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool M, bool N, int T) |
72 | : Kind(K), Extern(E), Constant(C), Managed(M), Normalized(N), |
73 | SurfTexType(T) {} |
74 | |
75 | DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); } |
76 | bool isExtern() const { return Extern; } |
77 | bool isConstant() const { return Constant; } |
78 | bool isManaged() const { return Managed; } |
79 | bool isNormalized() const { return Normalized; } |
80 | int getSurfTexType() const { return SurfTexType; } |
81 | }; |
82 | |
83 | CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {} |
84 | virtual ~CGCUDARuntime(); |
85 | |
86 | virtual RValue |
87 | EmitCUDAKernelCallExpr(CodeGenFunction &CGF, const CUDAKernelCallExpr *E, |
88 | ReturnValueSlot ReturnValue, |
89 | llvm::CallBase **CallOrInvoke = nullptr); |
90 | |
91 | /// Emits a kernel launch stub. |
92 | virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0; |
93 | |
94 | /// Check whether a variable is a device variable and register it if true. |
95 | virtual void handleVarRegistration(const VarDecl *VD, |
96 | llvm::GlobalVariable &Var) = 0; |
97 | |
98 | /// Finalize generated LLVM module. Returns a module constructor function |
99 | /// to be added or a null pointer. |
100 | virtual llvm::Function *finalizeModule() = 0; |
101 | |
102 | /// Returns function or variable name on device side even if the current |
103 | /// compilation is for host. |
104 | virtual std::string getDeviceSideName(const NamedDecl *ND) = 0; |
105 | |
106 | /// Get kernel handle by stub function. |
107 | virtual llvm::GlobalValue *getKernelHandle(llvm::Function *Stub, |
108 | GlobalDecl GD) = 0; |
109 | |
110 | /// Get kernel stub by kernel handle. |
111 | virtual llvm::Function *getKernelStub(llvm::GlobalValue *Handle) = 0; |
112 | |
113 | /// Adjust linkage of shadow variables in host compilation. |
114 | virtual void |
115 | internalizeDeviceSideVar(const VarDecl *D, |
116 | llvm::GlobalValue::LinkageTypes &Linkage) = 0; |
117 | }; |
118 | |
119 | /// Creates an instance of a CUDA runtime class. |
120 | CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM); |
121 | |
122 | } |
123 | } |
124 | |
125 | #endif |
126 | |