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; 285ffd83dbSDimitry 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. 455ffd83dbSDimitry Andric class DeviceVarFlags { 465ffd83dbSDimitry Andric public: 475ffd83dbSDimitry Andric enum DeviceVarKind { 485ffd83dbSDimitry Andric Variable, // Variable 495ffd83dbSDimitry Andric Surface, // Builtin surface 505ffd83dbSDimitry Andric Texture, // Builtin texture 515ffd83dbSDimitry Andric }; 525ffd83dbSDimitry Andric 535ffd83dbSDimitry Andric private: 545ffd83dbSDimitry Andric unsigned Kind : 2; 555ffd83dbSDimitry Andric unsigned Extern : 1; 565ffd83dbSDimitry Andric unsigned Constant : 1; // Constant variable. 57*e8d8bef9SDimitry Andric unsigned Managed : 1; // Managed variable. 585ffd83dbSDimitry Andric unsigned Normalized : 1; // Normalized texture. 595ffd83dbSDimitry Andric int SurfTexType; // Type of surface/texutre. 605ffd83dbSDimitry Andric 615ffd83dbSDimitry Andric public: 62*e8d8bef9SDimitry Andric DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool M, bool N, int T) 63*e8d8bef9SDimitry Andric : Kind(K), Extern(E), Constant(C), Managed(M), Normalized(N), 64*e8d8bef9SDimitry Andric SurfTexType(T) {} 655ffd83dbSDimitry Andric 665ffd83dbSDimitry Andric DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); } 675ffd83dbSDimitry Andric bool isExtern() const { return Extern; } 685ffd83dbSDimitry Andric bool isConstant() const { return Constant; } 69*e8d8bef9SDimitry Andric bool isManaged() const { return Managed; } 705ffd83dbSDimitry Andric bool isNormalized() const { return Normalized; } 715ffd83dbSDimitry Andric int getSurfTexType() const { return SurfTexType; } 720b57cec5SDimitry Andric }; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {} 750b57cec5SDimitry Andric virtual ~CGCUDARuntime(); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, 780b57cec5SDimitry Andric const CUDAKernelCallExpr *E, 790b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Emits a kernel launch stub. 820b57cec5SDimitry Andric virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0; 830b57cec5SDimitry Andric virtual void registerDeviceVar(const VarDecl *VD, llvm::GlobalVariable &Var, 845ffd83dbSDimitry Andric bool Extern, bool Constant) = 0; 855ffd83dbSDimitry Andric virtual void registerDeviceSurf(const VarDecl *VD, llvm::GlobalVariable &Var, 865ffd83dbSDimitry Andric bool Extern, int Type) = 0; 875ffd83dbSDimitry Andric virtual void registerDeviceTex(const VarDecl *VD, llvm::GlobalVariable &Var, 885ffd83dbSDimitry Andric bool Extern, int Type, bool Normalized) = 0; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// Constructs and returns a module initialization function or nullptr if it's 910b57cec5SDimitry Andric /// not needed. Must be called after all kernels have been emitted. 920b57cec5SDimitry Andric virtual llvm::Function *makeModuleCtorFunction() = 0; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// Returns a module cleanup function or nullptr if it's not needed. 950b57cec5SDimitry Andric /// Must be called after ModuleCtorFunction 960b57cec5SDimitry Andric virtual llvm::Function *makeModuleDtorFunction() = 0; 970b57cec5SDimitry Andric 985ffd83dbSDimitry Andric /// Returns function or variable name on device side even if the current 995ffd83dbSDimitry Andric /// compilation is for host. 1005ffd83dbSDimitry Andric virtual std::string getDeviceSideName(const NamedDecl *ND) = 0; 1010b57cec5SDimitry Andric }; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// Creates an instance of a CUDA runtime class. 1040b57cec5SDimitry Andric CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric #endif 110