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#include "llvm/IR/Intrinsics.h"
20#include "llvm/IR/IntrinsicsDirectX.h"
21#include "llvm/IR/IntrinsicsSPIRV.h"
22
23#include "clang/Basic/Builtins.h"
24#include "clang/Basic/HLSLRuntime.h"
25
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/Frontend/HLSL/HLSLResource.h"
29
30#include <optional>
31#include <vector>
32
33// A function generator macro for picking the right intrinsic
34// for the target backend
35#define GENERATE_HLSL_INTRINSIC_FUNCTION(FunctionName, IntrinsicPostfix) \
36 llvm::Intrinsic::ID get##FunctionName##Intrinsic() { \
37 llvm::Triple::ArchType Arch = getArch(); \
38 switch (Arch) { \
39 case llvm::Triple::dxil: \
40 return llvm::Intrinsic::dx_##IntrinsicPostfix; \
41 case llvm::Triple::spirv: \
42 return llvm::Intrinsic::spv_##IntrinsicPostfix; \
43 default: \
44 llvm_unreachable("Intrinsic " #IntrinsicPostfix \
45 " not supported by target architecture"); \
46 } \
47 }
48
49namespace llvm {
50class GlobalVariable;
51class Function;
52class StructType;
53} // namespace llvm
54
55namespace clang {
56class VarDecl;
57class ParmVarDecl;
58class HLSLBufferDecl;
59class HLSLResourceBindingAttr;
60class Type;
61class DeclContext;
62
63class FunctionDecl;
64
65namespace CodeGen {
66
67class CodeGenModule;
68
69class CGHLSLRuntime {
70public:
71 //===----------------------------------------------------------------------===//
72 // Start of reserved area for HLSL intrinsic getters.
73 //===----------------------------------------------------------------------===//
74
75 GENERATE_HLSL_INTRINSIC_FUNCTION(All, all)
76 GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any)
77 GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp)
78 GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id)
79
80 //===----------------------------------------------------------------------===//
81 // End of reserved area for HLSL intrinsic getters.
82 //===----------------------------------------------------------------------===//
83
84 struct BufferResBinding {
85 // The ID like 2 in register(b2, space1).
86 std::optional<unsigned> Reg;
87 // The Space like 1 is register(b2, space1).
88 // Default value is 0.
89 unsigned Space;
90 BufferResBinding(HLSLResourceBindingAttr *Attr);
91 };
92 struct Buffer {
93 Buffer(const HLSLBufferDecl *D);
94 llvm::StringRef Name;
95 // IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer).
96 bool IsCBuffer;
97 BufferResBinding Binding;
98 // Global variable and offset for each constant.
99 std::vector<std::pair<llvm::GlobalVariable *, unsigned>> Constants;
100 llvm::StructType *LayoutStruct = nullptr;
101 };
102
103protected:
104 CodeGenModule &CGM;
105
106 llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D,
107 llvm::Type *Ty);
108
109public:
110 CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
111 virtual ~CGHLSLRuntime() {}
112
113 void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV);
114 void generateGlobalCtorDtorCalls();
115
116 void addBuffer(const HLSLBufferDecl *D);
117 void finishCodeGen();
118
119 void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn);
120
121 void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
122 void setHLSLFunctionAttributes(llvm::Function *, const FunctionDecl *);
123
124private:
125 void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
126 llvm::hlsl::ResourceClass RC,
127 llvm::hlsl::ResourceKind RK, bool IsROV,
128 llvm::hlsl::ElementType ET,
129 BufferResBinding &Binding);
130 void addConstant(VarDecl *D, Buffer &CB);
131 void addBufferDecls(const DeclContext *DC, Buffer &CB);
132 llvm::Triple::ArchType getArch();
133 llvm::SmallVector<Buffer> Buffers;
134};
135
136} // namespace CodeGen
137} // namespace clang
138
139#endif
140

source code of clang/lib/CodeGen/CGHLSLRuntime.h