1 //===----- CGHLSLRuntime.h - Interface to HLSL 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 HLSL code generation.  Concrete
10 // subclasses of this implement code generation for specific HLSL
11 // runtime libraries.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H
16 #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H
17 
18 #include "llvm/IR/IRBuilder.h"
19 
20 #include "clang/Basic/HLSLRuntime.h"
21 
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Frontend/HLSL/HLSLResource.h"
25 
26 #include <optional>
27 #include <vector>
28 
29 namespace llvm {
30 class GlobalVariable;
31 class Function;
32 class StructType;
33 } // namespace llvm
34 
35 namespace clang {
36 class VarDecl;
37 class ParmVarDecl;
38 class HLSLBufferDecl;
39 class HLSLResourceBindingAttr;
40 class Type;
41 class DeclContext;
42 
43 class FunctionDecl;
44 
45 namespace CodeGen {
46 
47 class CodeGenModule;
48 
49 class CGHLSLRuntime {
50 public:
51   struct BufferResBinding {
52     // The ID like 2 in register(b2, space1).
53     std::optional<unsigned> Reg;
54     // The Space like 1 is register(b2, space1).
55     // Default value is 0.
56     unsigned Space;
57     BufferResBinding(HLSLResourceBindingAttr *Attr);
58   };
59   struct Buffer {
60     Buffer(const HLSLBufferDecl *D);
61     llvm::StringRef Name;
62     // IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer).
63     bool IsCBuffer;
64     BufferResBinding Binding;
65     // Global variable and offset for each constant.
66     std::vector<std::pair<llvm::GlobalVariable *, unsigned>> Constants;
67     llvm::StructType *LayoutStruct = nullptr;
68   };
69 
70 protected:
71   CodeGenModule &CGM;
72 
73   llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D,
74                                  llvm::Type *Ty);
75 
76 public:
CGHLSLRuntime(CodeGenModule & CGM)77   CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
~CGHLSLRuntime()78   virtual ~CGHLSLRuntime() {}
79 
80   void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV);
81   void generateGlobalCtorDtorCalls();
82 
83   void addBuffer(const HLSLBufferDecl *D);
84   void finishCodeGen();
85 
86   void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn);
87 
88   void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
89   void setHLSLFunctionAttributes(llvm::Function *, const FunctionDecl *);
90 
91 private:
92   void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
93                                    llvm::hlsl::ResourceClass RC,
94                                    llvm::hlsl::ResourceKind RK, bool IsROV,
95                                    llvm::hlsl::ElementType ET,
96                                    BufferResBinding &Binding);
97   void addConstant(VarDecl *D, Buffer &CB);
98   void addBufferDecls(const DeclContext *DC, Buffer &CB);
99   llvm::SmallVector<Buffer> Buffers;
100 };
101 
102 } // namespace CodeGen
103 } // namespace clang
104 
105 #endif
106