xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CGCUDARuntime.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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