[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / clang / docs / HLSL / HLSLSupport.rst
blob2d309ddff2f36aa8413331627eb3fd6487bdd40c
1 ============
2 HLSL Support
3 ============
5 .. contents::
6    :local:
8 Introduction
9 ============
11 HLSL Support is under active development in the Clang codebase. This document
12 describes the high level goals of the project, the guiding principles, as well
13 as some idiosyncrasies of the HLSL language and how we intend to support them in
14 Clang.
16 Project Goals
17 =============
19 The long term goal of this project is to enable Clang to function as a
20 replacement for the `DirectXShaderCompiler (DXC)
21 <https://github.com/microsoft/DirectXShaderCompiler/>`_ in all its supported
22 use cases. Accomplishing that goal will require Clang to be able to process most
23 existing HLSL programs with a high degree of source compatibility.
25 Non-Goals
26 ---------
28 HLSL ASTs do not need to be compatible between DXC and Clang. We do not expect
29 identical code generation or that features will resemble DXC's implementation or
30 architecture. In fact, we explicitly expect to deviate from DXC's implementation
31 in key ways.
33 Guiding Principles
34 ==================
36 This document lacks details for architectural decisions that are not yet
37 finalized. Our top priorities are quality, maintainability, and flexibility. In
38 accordance with community standards we are expecting a high level of test
39 coverage, and we will engineer our solutions with long term maintenance in mind.
40 We are also working to limit modifications to the Clang C++ code paths and
41 share as much functionality as possible.
43 Architectural Direction
44 =======================
46 HLSL support in Clang is expressed as C++ minus unsupported C and C++ features.
47 This is different from how other Clang languages are implemented. Most languages
48 in Clang are additive on top of C.
50 HLSL is not a formally or fully specified language, and while our goals require
51 a high level of source compatibility, implementations can vary and we have some
52 flexibility to be more or less permissive in some cases. For modern HLSL DXC is
53 the reference implementation.
55 The HLSL effort prioritizes following similar patterns for other languages,
56 drivers, runtimes and targets. Specifically, We will maintain separation between
57 HSLS-specific code and the rest of Clang as much as possible following patterns
58 in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL*.cpp...).
59 We will use inline checks on language options where the code is simple and
60 isolated, and prefer HLSL-specific implementation files for any code of
61 reasonable complexity.
63 In places where the HLSL language is in conflict with C and C++, we will seek to
64 make minimally invasive changes guarded under the HLSL language options. We will
65 seek to make HLSL language support as minimal a maintenance burden as possible.
67 DXC Driver
68 ----------
70 A DXC driver mode will provide command-line compatibility with DXC, supporting
71 DXC's options and flags. The DXC driver is HLSL-specific and will create an
72 HLSLToolchain which will provide the basis to support targeting both DirectX and
73 Vulkan.
75 Parser
76 ------
78 Following the examples of other parser extensions HLSL will add a ParseHLSL.cpp
79 file to contain the implementations of HLSL-specific extensions to the Clang
80 parser. The HLSL grammar shares most of its structure with C and C++, so we will
81 use the existing C/C++ parsing code paths.
83 Sema
84 ----
86 HLSL's Sema implementation will also provide an ``ExternalSemaSource``. In DXC,
87 an ``ExternalSemaSource`` is used to provide definitions for HLSL built-in data
88 types and built-in templates. Clang is already designed to allow an attached
89 ``ExternalSemaSource`` to lazily complete data types, which is a **huge**
90 performance win for HLSL.
92 If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource``
93 will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader``
94 and -. For Built-in declarations that are already
95 completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the
96 existing declarations and not introduce new declarations. If the built-in types
97 are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will
98 create new declarations and connect the de-serialized decls as the previous
99 declaration.
101 CodeGen
102 -------
104 Like OpenCL, HLSL relies on capturing a lot of information into IR metadata.
105 *hand wave* *hand wave* *hand wave* As a design principle here we want our IR to
106 be idiomatic Clang IR as much as possible. We will use IR attributes wherever we
107 can, and use metadata as sparingly as possible. One example of a difference from
108 DXC already implemented in Clang is the use of target triples to communicate
109 shader model versions and shader stages.
111 Our HLSL CodeGen implementation should also have an eye toward generating IR
112 that will map directly to targets other than DXIL. While IR itself is generally
113 not re-targetable, we want to share the Clang CodeGen implementation for HLSL
114 with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU
115 targets.
117 hlsl.h
118 ------
120 HLSL has a library of standalone functions. This is similar to OpenCL and CUDA,
121 and is analogous to C's standard library. The implementation approach for the
122 HLSL library functionality draws from patterns in use by OpenCL and other Clang
123 resource headers. All of the clang resource headers are part of the
124 ``ClangHeaders`` component found in the source tree under
125 `clang/lib/Headers <https://github.com/llvm/llvm-project/tree/main/clang/lib/Headers>`_.
127 .. note::
129    HLSL's complex data types are not defined in HLSL's header because many of
130    the semantics of those data types cannot be expressed in HLSL due to missing
131    language features. Data types that can't be expressed in HLSL are defined in
132    code in the ``HLSLExternalSemaSource``.
134 Similar to OpenCL, the HLSL library functionality is implicitly declared in
135 translation units without needing to include a header to provide declarations.
136 In Clang this is handled by making ``hlsl.h`` an implicitly included header
137 distributed as part of the Clang resource directory.
139 Similar to OpenCL, HLSL's implicit header will explicitly declare all overloads,
140 and each overload will map to a corresponding ``__builtin*`` compiler intrinsic
141 that is handled in ClangCodeGen. CUDA uses a similar pattern although many CUDA
142 functions have full definitions in the included headers which in turn call
143 corresponding ``__builtin*`` compiler intrinsics. By not having bodies HLSL
144 avoids the need for the inliner to clean up and inline large numbers of small
145 library functions.
147 HLSL's implicit headers also define some of HLSL's typedefs. This is consistent
148 with how the AVX vector header is implemented.
150 Concerns have been expressed that this approach may result in slower compile
151 times than the approach DXC uses where library functions are treated more like
152 Clang ``__builtin*`` intrinsics. No real world use cases have been identified
153 where parsing is a significant compile-time overhead, but the HLSL implicit
154 headers can be compiled into a module for performance if needed.
156 Further, by treating these as functions rather than ``__builtin*`` compiler
157 intrinsics, the language behaviors are more consistent and aligned with user
158 expectation because normal overload resolution rules and implicit conversions
159 apply as expected.
161 It is a feature of this design that clangd-powered "go to declaration" for
162 library functions will jump to a valid header declaration and all overloads will
163 be user readable.
165 HLSL Language
166 =============
168 The HLSL language is insufficiently documented, and not formally specified.
169 Documentation is available on `Microsoft's website
170 <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl>`_.
171 The language syntax is similar enough to C and C++ that carefully written C and
172 C++ code is valid HLSL. HLSL has some key differences from C & C++ which we will
173 need to handle in Clang.
175 HLSL is not a conforming or valid extension or superset of C or C++. The
176 language has key incompatibilities with C and C++, both syntactically and
177 semantically.
179 An Aside on GPU Languages
180 -------------------------
182 Due to HLSL being a GPU targeted language HLSL is a Single Program Multiple Data
183 (SPMD) language relying on the implicit parallelism provided by GPU hardware.
184 Some language features in HLSL enable programmers to take advantage of the
185 parallel nature of GPUs in a hardware abstracted language.
187 HLSL also prohibits some features of C and C++ which can have catastrophic
188 performance or are not widely supportable on GPU hardware or drivers. As an
189 example, register spilling is often excessively expensive on GPUs, so HLSL
190 requires all functions to be inlined during code generation, and does not
191 support a runtime calling convention.
193 Pointers & References
194 ---------------------
196 HLSL does not support referring to values by address. Semantically all variables
197 are value-types and behave as such. HLSL disallows the pointer dereference
198 operators (unary ``*``, and ``->``), as well as the address of operator (unary
199 &). While HLSL disallows pointers and references in the syntax, HLSL does use
200 reference types in the AST, and we intend to use pointer decay in the AST in
201 the Clang implementation.
203 HLSL ``this`` Keyword
204 ---------------------
206 HLSL does support member functions, and (in HLSL 2021) limited operator
207 overloading. With member function support, HLSL also has a ``this`` keyword. The
208 ``this`` keyword is an example of one of the places where HLSL relies on
209 references in the AST, because ``this`` is a reference.
211 Bitshifts
212 ---------
214 In deviation from C, HLSL bitshifts are defined to mask the shift count by the
215 size of the type. In DXC, the semantics of LLVM IR were altered to accommodate
216 this, in Clang we intend to generate the mask explicitly in the IR. In cases
217 where the shift value is constant, this will be constant folded appropriately,
218 in other cases we can clean it up in the DXIL target.
220 Non-short Circuiting Logical Operators
221 --------------------------------------
223 In HLSL 2018 and earlier, HLSL supported logical operators (and the ternary
224 operator) on vector types. This behavior required that operators not short
225 circuit. The non-short circuiting behavior applies to all data types until HLSL
226 2021. In HLSL 2021, logical and ternary operators do not support vector types
227 instead builtin functions ``and``, ``or`` and ``select`` are available, and
228 operators short circuit matching C behavior.
230 Precise Qualifier
231 -----------------
233 HLSL has a ``precise`` qualifier that behaves unlike anything else in the C
234 language. The support for this qualifier in DXC is buggy, so our bar for
235 compatibility is low.
237 The ``precise`` qualifier applies in the inverse direction from normal
238 qualifiers. Rather than signifying that the declaration containing ``precise``
239 qualifier be precise, it signifies that the operations contributing to the
240 declaration's value be ``precise``. Additionally, ``precise`` is a misnomer:
241 values attributed as ``precise`` comply with IEEE-754 floating point semantics,
242 and are prevented from optimizations which could decrease *or increase*
243 precision.
245 Differences in Templates
246 ------------------------
248 HLSL uses templates to define builtin types and methods, but disallowed
249 user-defined templates until HLSL 2021. HLSL also allows omitting empty template
250 parameter lists when all template parameters are defaulted. This is an ambiguous
251 syntax in C++, but Clang detects the case and issues a diagnostic. This makes
252 supporting the case in Clang minimally invasive.
254 Vector Extensions
255 -----------------
257 HLSL uses the OpenCL vector extensions, and also provides C++-style constructors
258 for vectors that are not supported by Clang.
260 Standard Library
261 ----------------
263 HLSL does not support the C or C++ standard libraries. Like OpenCL, HLSL
264 describes its own library of built in types, complex data types, and functions.
266 Unsupported C & C++ Features
267 ----------------------------
269 HLSL does not support all features of C and C++. In implementing HLSL in Clang
270 use of some C and C++ features will produce diagnostics under HLSL, and others
271 will be supported as language extensions. In general, any C or C++ feature that
272 can be supported by the DXIL and SPIR-V code generation targets could be treated
273 as a clang HLSL extension. Features that cannot be lowered to DXIL or SPIR-V,
274 must be diagnosed as errors.
276 HLSL does not support the following C features:
278 * Pointers
279 * References
280 * ``goto`` or labels
281 * Variable Length Arrays
282 * ``_Complex`` and ``_Imaginary``
283 * C Threads or Atomics (or Obj-C blocks)
284 * ``union`` types `(in progress for HLSL 202x) <https://github.com/microsoft/DirectXShaderCompiler/pull/4132>`_
285 * Most features C11 and later
287 HLSL does not support the following C++ features:
289 * RTTI
290 * Exceptions
291 * Multiple inheritance
292 * Access specifiers
293 * Anonymous or inline namespaces
294 * ``new`` & ``delete`` operators in all of their forms (array, placement, etc)
295 * Constructors and destructors
296 * Any use of the ``virtual`` keyword
297 * Most features C++11 and later