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