1 //===----- CGCUDARuntime.h - Interface to CUDA Runtimes ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This provides an abstract class for CUDA code generation.  Concrete
10 // subclasses of this implement code generation for specific CUDA
11 // runtime libraries.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H
16 #define LLVM_CLANG_LIB_CODEGEN_CGCUDARUNTIME_H
17 
18 #include "llvm/ADT/StringRef.h"
19 
20 namespace llvm {
21 class Function;
22 class GlobalVariable;
23 }
24 
25 namespace clang {
26 
27 class CUDAKernelCallExpr;
28 class NamedDecl;
29 class VarDecl;
30 
31 namespace CodeGen {
32 
33 class CodeGenFunction;
34 class CodeGenModule;
35 class FunctionArgList;
36 class ReturnValueSlot;
37 class RValue;
38 
39 class CGCUDARuntime {
40 protected:
41   CodeGenModule &CGM;
42 
43 public:
44   // Global variable properties that must be passed to CUDA runtime.
45   class DeviceVarFlags {
46   public:
47     enum DeviceVarKind {
48       Variable, // Variable
49       Surface,  // Builtin surface
50       Texture,  // Builtin texture
51     };
52 
53   private:
54     unsigned Kind : 2;
55     unsigned Extern : 1;
56     unsigned Constant : 1;   // Constant variable.
57     unsigned Normalized : 1; // Normalized texture.
58     int SurfTexType;         // Type of surface/texutre.
59 
60   public:
DeviceVarFlags(DeviceVarKind K,bool E,bool C,bool N,int T)61     DeviceVarFlags(DeviceVarKind K, bool E, bool C, bool N, int T)
62         : Kind(K), Extern(E), Constant(C), Normalized(N), SurfTexType(T) {}
63 
getKind()64     DeviceVarKind getKind() const { return static_cast<DeviceVarKind>(Kind); }
isExtern()65     bool isExtern() const { return Extern; }
isConstant()66     bool isConstant() const { return Constant; }
isNormalized()67     bool isNormalized() const { return Normalized; }
getSurfTexType()68     int getSurfTexType() const { return SurfTexType; }
69   };
70 
CGCUDARuntime(CodeGenModule & CGM)71   CGCUDARuntime(CodeGenModule &CGM) : CGM(CGM) {}
72   virtual ~CGCUDARuntime();
73 
74   virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF,
75                                         const CUDAKernelCallExpr *E,
76                                         ReturnValueSlot ReturnValue);
77 
78   /// Emits a kernel launch stub.
79   virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0;
80   virtual void registerDeviceVar(const VarDecl *VD, llvm::GlobalVariable &Var,
81                                  bool Extern, bool Constant) = 0;
82   virtual void registerDeviceSurf(const VarDecl *VD, llvm::GlobalVariable &Var,
83                                   bool Extern, int Type) = 0;
84   virtual void registerDeviceTex(const VarDecl *VD, llvm::GlobalVariable &Var,
85                                  bool Extern, int Type, bool Normalized) = 0;
86 
87   /// Constructs and returns a module initialization function or nullptr if it's
88   /// not needed. Must be called after all kernels have been emitted.
89   virtual llvm::Function *makeModuleCtorFunction() = 0;
90 
91   /// Returns a module cleanup function or nullptr if it's not needed.
92   /// Must be called after ModuleCtorFunction
93   virtual llvm::Function *makeModuleDtorFunction() = 0;
94 
95   /// Returns function or variable name on device side even if the current
96   /// compilation is for host.
97   virtual std::string getDeviceSideName(const NamedDecl *ND) = 0;
98 };
99 
100 /// Creates an instance of a CUDA runtime class.
101 CGCUDARuntime *CreateNVCUDARuntime(CodeGenModule &CGM);
102 
103 }
104 }
105 
106 #endif
107