| 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 | |