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: 57*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(DeviceVarKind) 585ffd83dbSDimitry Andric unsigned Kind : 2; 59*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 605ffd83dbSDimitry Andric unsigned Extern : 1; 61*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 625ffd83dbSDimitry Andric unsigned Constant : 1; // Constant variable. 63*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 64e8d8bef9SDimitry Andric unsigned Managed : 1; // Managed variable. 65*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 665ffd83dbSDimitry Andric unsigned Normalized : 1; // Normalized texture. 675ffd83dbSDimitry Andric int SurfTexType; // Type of surface/texutre. 685ffd83dbSDimitry Andric 695ffd83dbSDimitry Andric public: DeviceVarFlags(DeviceVarKind K,bool E,bool C,bool M,bool N,int T)70e8d8bef9SDimitry Andric DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool M, bool N, int T) 71e8d8bef9SDimitry Andric : Kind(K), Extern(E), Constant(C), Managed(M), Normalized(N), 72e8d8bef9SDimitry Andric SurfTexType(T) {} 735ffd83dbSDimitry Andric getKind()745ffd83dbSDimitry Andric DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); } isExtern()755ffd83dbSDimitry Andric bool isExtern() const { return Extern; } isConstant()765ffd83dbSDimitry Andric bool isConstant() const { return Constant; } isManaged()77e8d8bef9SDimitry Andric bool isManaged() const { return Managed; } isNormalized()785ffd83dbSDimitry Andric bool isNormalized() const { return Normalized; } getSurfTexType()795ffd83dbSDimitry Andric int getSurfTexType() const { return SurfTexType; } 800b57cec5SDimitry Andric }; 810b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule & CGM)820b57cec5SDimitry Andric CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {} 830b57cec5SDimitry Andric virtual ~CGCUDARuntime(); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, 860b57cec5SDimitry Andric const CUDAKernelCallExpr *E, 870b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// Emits a kernel launch stub. 900b57cec5SDimitry Andric virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0; 910b57cec5SDimitry Andric 92fe6060f1SDimitry Andric /// Check whether a variable is a device variable and register it if true. 93fe6060f1SDimitry Andric virtual void handleVarRegistration(const VarDecl *VD, 94fe6060f1SDimitry Andric llvm::GlobalVariable &Var) = 0; 950b57cec5SDimitry Andric 96fe6060f1SDimitry Andric /// Finalize generated LLVM module. Returns a module constructor function 97fe6060f1SDimitry Andric /// to be added or a null pointer. 98fe6060f1SDimitry Andric virtual llvm::Function *finalizeModule() = 0; 990b57cec5SDimitry Andric 1005ffd83dbSDimitry Andric /// Returns function or variable name on device side even if the current 1015ffd83dbSDimitry Andric /// compilation is for host. 1025ffd83dbSDimitry Andric virtual std::string getDeviceSideName(const NamedDecl *ND) = 0; 103fe6060f1SDimitry Andric 104fe6060f1SDimitry Andric /// Get kernel handle by stub function. 105fe6060f1SDimitry Andric virtual llvm::GlobalValue *getKernelHandle(llvm::Function *Stub, 106fe6060f1SDimitry Andric GlobalDecl GD) = 0; 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric /// Get kernel stub by kernel handle. 109fe6060f1SDimitry Andric virtual llvm::Function *getKernelStub(llvm::GlobalValue *Handle) = 0; 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric /// Adjust linkage of shadow variables in host compilation. 112fe6060f1SDimitry Andric virtual void 113fe6060f1SDimitry Andric internalizeDeviceSideVar(const VarDecl *D, 114fe6060f1SDimitry Andric llvm::GlobalValue::LinkageTypes &Linkage) = 0; 1150b57cec5SDimitry Andric }; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// Creates an instance of a CUDA runtime class. 1180b57cec5SDimitry Andric CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric #endif 124