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 18fe6060f1SDimitry Andric #include "clang/AST/GlobalDecl.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 205f757f3fSDimitry Andric #include "llvm/Frontend/Offloading/Utility.h" 21fe6060f1SDimitry Andric #include "llvm/IR/GlobalValue.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace llvm { 240b57cec5SDimitry Andric class Function; 250b57cec5SDimitry Andric class GlobalVariable; 260b57cec5SDimitry Andric } 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace clang { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric class CUDAKernelCallExpr; 315ffd83dbSDimitry Andric class NamedDecl; 320b57cec5SDimitry Andric class VarDecl; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric namespace CodeGen { 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric class CodeGenFunction; 370b57cec5SDimitry Andric class CodeGenModule; 380b57cec5SDimitry Andric class FunctionArgList; 390b57cec5SDimitry Andric class ReturnValueSlot; 400b57cec5SDimitry Andric class RValue; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric class CGCUDARuntime { 430b57cec5SDimitry Andric protected: 440b57cec5SDimitry Andric CodeGenModule &CGM; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric public: 470b57cec5SDimitry Andric // Global variable properties that must be passed to CUDA runtime. 485ffd83dbSDimitry Andric class DeviceVarFlags { 495ffd83dbSDimitry Andric public: 505ffd83dbSDimitry Andric enum DeviceVarKind { 515ffd83dbSDimitry Andric Variable, // Variable 525ffd83dbSDimitry Andric Surface, // Builtin surface 535ffd83dbSDimitry Andric Texture, // Builtin texture 545ffd83dbSDimitry Andric }; 555ffd83dbSDimitry Andric 565ffd83dbSDimitry Andric private: 575ffd83dbSDimitry Andric unsigned Kind : 2; 585ffd83dbSDimitry Andric unsigned Extern : 1; 595ffd83dbSDimitry Andric unsigned Constant : 1; // Constant variable. 60e8d8bef9SDimitry Andric unsigned Managed : 1; // Managed variable. 615ffd83dbSDimitry Andric unsigned Normalized : 1; // Normalized texture. 625ffd83dbSDimitry Andric int SurfTexType; // Type of surface/texutre. 635ffd83dbSDimitry Andric 645ffd83dbSDimitry Andric public: DeviceVarFlags(DeviceVarKind K,bool E,bool C,bool M,bool N,int T)65e8d8bef9SDimitry Andric DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool M, bool N, int T) 66e8d8bef9SDimitry Andric : Kind(K), Extern(E), Constant(C), Managed(M), Normalized(N), 67e8d8bef9SDimitry Andric SurfTexType(T) {} 685ffd83dbSDimitry Andric getKind()695ffd83dbSDimitry Andric DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); } isExtern()705ffd83dbSDimitry Andric bool isExtern() const { return Extern; } isConstant()715ffd83dbSDimitry Andric bool isConstant() const { return Constant; } isManaged()72e8d8bef9SDimitry Andric bool isManaged() const { return Managed; } isNormalized()735ffd83dbSDimitry Andric bool isNormalized() const { return Normalized; } getSurfTexType()745ffd83dbSDimitry Andric int getSurfTexType() const { return SurfTexType; } 750b57cec5SDimitry Andric }; 760b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule & CGM)770b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {} 780b57cec5SDimitry Andric virtual ~CGCUDARuntime(); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, 810b57cec5SDimitry Andric const CUDAKernelCallExpr *E, 820b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// Emits a kernel launch stub. 850b57cec5SDimitry Andric virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0; 860b57cec5SDimitry Andric 87fe6060f1SDimitry Andric /// Check whether a variable is a device variable and register it if true. 88fe6060f1SDimitry Andric virtual void handleVarRegistration(const VarDecl *VD, 89fe6060f1SDimitry Andric llvm::GlobalVariable &Var) = 0; 900b57cec5SDimitry Andric 91fe6060f1SDimitry Andric /// Finalize generated LLVM module. Returns a module constructor function 92fe6060f1SDimitry Andric /// to be added or a null pointer. 93fe6060f1SDimitry Andric virtual llvm::Function *finalizeModule() = 0; 940b57cec5SDimitry Andric 955ffd83dbSDimitry Andric /// Returns function or variable name on device side even if the current 965ffd83dbSDimitry Andric /// compilation is for host. 975ffd83dbSDimitry Andric virtual std::string getDeviceSideName(const NamedDecl *ND) = 0; 98fe6060f1SDimitry Andric 99fe6060f1SDimitry Andric /// Get kernel handle by stub function. 100fe6060f1SDimitry Andric virtual llvm::GlobalValue *getKernelHandle(llvm::Function *Stub, 101fe6060f1SDimitry Andric GlobalDecl GD) = 0; 102fe6060f1SDimitry Andric 103fe6060f1SDimitry Andric /// Get kernel stub by kernel handle. 104fe6060f1SDimitry Andric virtual llvm::Function *getKernelStub(llvm::GlobalValue *Handle) = 0; 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric /// Adjust linkage of shadow variables in host compilation. 107fe6060f1SDimitry Andric virtual void 108fe6060f1SDimitry Andric internalizeDeviceSideVar(const VarDecl *D, 109fe6060f1SDimitry Andric llvm::GlobalValue::LinkageTypes &Linkage) = 0; 1100b57cec5SDimitry Andric }; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// Creates an instance of a CUDA runtime class. 1130b57cec5SDimitry Andric CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM); 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric #endif 119