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/ADT/DenseMap.h"
19#include "llvm/IR/IRBuilder.h"
20#include "llvm/IR/Intrinsics.h"
21#include "llvm/IR/IntrinsicsDirectX.h"
22#include "llvm/IR/IntrinsicsSPIRV.h"
23
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/HLSLRuntime.h"
26
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/Frontend/HLSL/HLSLResource.h"
30
31#include <optional>
32#include <vector>
33
34// A function generator macro for picking the right intrinsic
35// for the target backend
36#define GENERATE_HLSL_INTRINSIC_FUNCTION(FunctionName, IntrinsicPostfix) \
37 llvm::Intrinsic::ID get##FunctionName##Intrinsic() { \
38 llvm::Triple::ArchType Arch = getArch(); \
39 switch (Arch) { \
40 case llvm::Triple::dxil: \
41 return llvm::Intrinsic::dx_##IntrinsicPostfix; \
42 case llvm::Triple::spirv: \
43 return llvm::Intrinsic::spv_##IntrinsicPostfix; \
44 default: \
45 llvm_unreachable("Intrinsic " #IntrinsicPostfix \
46 " not supported by target architecture"); \
47 } \
48 }
49
50using ResourceClass = llvm::dxil::ResourceClass;
51
52namespace llvm {
53class GlobalVariable;
54class Function;
55class StructType;
56class Metadata;
57} // namespace llvm
58
59namespace clang {
60class NamedDecl;
61class VarDecl;
62class ParmVarDecl;
63class InitListExpr;
64class HLSLBufferDecl;
65class HLSLResourceBindingAttr;
66class Type;
67class RecordType;
68class DeclContext;
69class HLSLPackOffsetAttr;
70
71class FunctionDecl;
72
73namespace CodeGen {
74
75class CodeGenModule;
76class CodeGenFunction;
77
78class CGHLSLRuntime {
79public:
80 //===----------------------------------------------------------------------===//
81 // Start of reserved area for HLSL intrinsic getters.
82 //===----------------------------------------------------------------------===//
83
84 GENERATE_HLSL_INTRINSIC_FUNCTION(All, all)
85 GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any)
86 GENERATE_HLSL_INTRINSIC_FUNCTION(Cross, cross)
87 GENERATE_HLSL_INTRINSIC_FUNCTION(Degrees, degrees)
88 GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac)
89 GENERATE_HLSL_INTRINSIC_FUNCTION(FlattenedThreadIdInGroup,
90 flattened_thread_id_in_group)
91 GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp)
92 GENERATE_HLSL_INTRINSIC_FUNCTION(Normalize, normalize)
93 GENERATE_HLSL_INTRINSIC_FUNCTION(Rsqrt, rsqrt)
94 GENERATE_HLSL_INTRINSIC_FUNCTION(Saturate, saturate)
95 GENERATE_HLSL_INTRINSIC_FUNCTION(Sign, sign)
96 GENERATE_HLSL_INTRINSIC_FUNCTION(Step, step)
97 GENERATE_HLSL_INTRINSIC_FUNCTION(Radians, radians)
98 GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id)
99 GENERATE_HLSL_INTRINSIC_FUNCTION(GroupThreadId, thread_id_in_group)
100 GENERATE_HLSL_INTRINSIC_FUNCTION(GroupId, group_id)
101 GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot)
102 GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
103 GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
104 GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed)
105 GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed)
106 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAllTrue, wave_all)
107 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any)
108 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits)
109 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
110 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveGetLaneCount, wave_get_lane_count)
111 GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
112 GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh)
113 GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh)
114 GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitLow, firstbitlow)
115 GENERATE_HLSL_INTRINSIC_FUNCTION(NClamp, nclamp)
116 GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp)
117 GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp)
118
119 GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer,
120 resource_getpointer)
121 GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter)
122 GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync,
123 group_memory_barrier_with_group_sync)
124
125 //===----------------------------------------------------------------------===//
126 // End of reserved area for HLSL intrinsic getters.
127 //===----------------------------------------------------------------------===//
128
129 // Returns ID of the intrinsic that initializes resource handle from binding
130 // and a bool value indicating whether the last argument of the intrinsic is
131 // the resource name (not all targets need that).
132 std::pair<llvm::Intrinsic::ID, bool> getCreateHandleFromBindingIntrinsic();
133
134 // Same as above but for implicit binding.
135 std::pair<llvm::Intrinsic::ID, bool>
136 getCreateHandleFromImplicitBindingIntrinsic();
137
138protected:
139 CodeGenModule &CGM;
140
141 llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D,
142 llvm::Type *Ty);
143
144public:
145 CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
146 virtual ~CGHLSLRuntime() {}
147
148 llvm::Type *
149 convertHLSLSpecificType(const Type *T,
150 SmallVector<int32_t> *Packoffsets = nullptr);
151
152 void generateGlobalCtorDtorCalls();
153
154 void addBuffer(const HLSLBufferDecl *D);
155 void finishCodeGen();
156
157 void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn);
158
159 void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
160 void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn);
161 void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var);
162
163 llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB);
164
165 llvm::TargetExtType *
166 getHLSLBufferLayoutType(const RecordType *LayoutStructTy);
167 void addHLSLBufferLayoutType(const RecordType *LayoutStructTy,
168 llvm::TargetExtType *LayoutTy);
169 void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E);
170
171private:
172 void emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
173 llvm::GlobalVariable *BufGV);
174 void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
175 llvm::GlobalVariable *GV,
176 HLSLResourceBindingAttr *RBA);
177 llvm::Triple::ArchType getArch();
178
179 llvm::DenseMap<const clang::RecordType *, llvm::TargetExtType *> LayoutTypes;
180};
181
182} // namespace CodeGen
183} // namespace clang
184
185#endif
186

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

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