10b57cec5SDimitry Andric //===----- CGCUDARuntime.h - Interface to CUDA Runtimes ---------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This provides an abstract class for CUDA code generation. Concrete 100b57cec5SDimitry Andric // subclasses of this implement code generation for specific CUDA 110b57cec5SDimitry Andric // runtime libraries. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H 160b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace llvm { 210b57cec5SDimitry Andric class Function; 220b57cec5SDimitry Andric class GlobalVariable; 230b57cec5SDimitry Andric } 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace clang { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric class CUDAKernelCallExpr; 28*5ffd83dbSDimitry Andric class NamedDecl; 290b57cec5SDimitry Andric class VarDecl; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace CodeGen { 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric class CodeGenFunction; 340b57cec5SDimitry Andric class CodeGenModule; 350b57cec5SDimitry Andric class FunctionArgList; 360b57cec5SDimitry Andric class ReturnValueSlot; 370b57cec5SDimitry Andric class RValue; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric class CGCUDARuntime { 400b57cec5SDimitry Andric protected: 410b57cec5SDimitry Andric CodeGenModule &CGM; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric public: 440b57cec5SDimitry Andric // Global variable properties that must be passed to CUDA runtime. 45*5ffd83dbSDimitry Andric class DeviceVarFlags { 46*5ffd83dbSDimitry Andric public: 47*5ffd83dbSDimitry Andric enum DeviceVarKind { 48*5ffd83dbSDimitry Andric Variable, // Variable 49*5ffd83dbSDimitry Andric Surface, // Builtin surface 50*5ffd83dbSDimitry Andric Texture, // Builtin texture 51*5ffd83dbSDimitry Andric }; 52*5ffd83dbSDimitry Andric 53*5ffd83dbSDimitry Andric private: 54*5ffd83dbSDimitry Andric unsigned Kind : 2; 55*5ffd83dbSDimitry Andric unsigned Extern : 1; 56*5ffd83dbSDimitry Andric unsigned Constant : 1; // Constant variable. 57*5ffd83dbSDimitry Andric unsigned Normalized : 1; // Normalized texture. 58*5ffd83dbSDimitry Andric int SurfTexType; // Type of surface/texutre. 59*5ffd83dbSDimitry Andric 60*5ffd83dbSDimitry Andric public: 61*5ffd83dbSDimitry Andric DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool N, int T) 62*5ffd83dbSDimitry Andric : Kind(K), Extern(E), Constant(C), Normalized(N), SurfTexType(T) {} 63*5ffd83dbSDimitry Andric 64*5ffd83dbSDimitry Andric DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); } 65*5ffd83dbSDimitry Andric bool isExtern() const { return Extern; } 66*5ffd83dbSDimitry Andric bool isConstant() const { return Constant; } 67*5ffd83dbSDimitry Andric bool isNormalized() const { return Normalized; } 68*5ffd83dbSDimitry Andric int getSurfTexType() const { return SurfTexType; } 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {} 720b57cec5SDimitry Andric virtual ~CGCUDARuntime(); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, 750b57cec5SDimitry Andric const CUDAKernelCallExpr *E, 760b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// Emits a kernel launch stub. 790b57cec5SDimitry Andric virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0; 800b57cec5SDimitry Andric virtual void registerDeviceVar(const VarDecl *VD, llvm::GlobalVariable &Var, 81*5ffd83dbSDimitry Andric bool Extern, bool Constant) = 0; 82*5ffd83dbSDimitry Andric virtual void registerDeviceSurf(const VarDecl *VD, llvm::GlobalVariable &Var, 83*5ffd83dbSDimitry Andric bool Extern, int Type) = 0; 84*5ffd83dbSDimitry Andric virtual void registerDeviceTex(const VarDecl *VD, llvm::GlobalVariable &Var, 85*5ffd83dbSDimitry Andric bool Extern, int Type, bool Normalized) = 0; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric /// Constructs and returns a module initialization function or nullptr if it's 880b57cec5SDimitry Andric /// not needed. Must be called after all kernels have been emitted. 890b57cec5SDimitry Andric virtual llvm::Function *makeModuleCtorFunction() = 0; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Returns a module cleanup function or nullptr if it's not needed. 920b57cec5SDimitry Andric /// Must be called after ModuleCtorFunction 930b57cec5SDimitry Andric virtual llvm::Function *makeModuleDtorFunction() = 0; 940b57cec5SDimitry Andric 95*5ffd83dbSDimitry Andric /// Returns function or variable name on device side even if the current 96*5ffd83dbSDimitry Andric /// compilation is for host. 97*5ffd83dbSDimitry Andric virtual std::string getDeviceSideName(const NamedDecl *ND) = 0; 980b57cec5SDimitry Andric }; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// Creates an instance of a CUDA runtime class. 1010b57cec5SDimitry Andric CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric #endif 107