1============ 2HLSL Support 3============ 4 5.. contents:: 6 :local: 7 8Introduction 9============ 10 11HLSL Support is under active development in the Clang codebase. This document 12describes the high level goals of the project, the guiding principles, as well 13as some idiosyncrasies of the HLSL language and how we intend to support them in 14Clang. 15 16Project Goals 17============= 18 19The long term goal of this project is to enable Clang to function as a 20replacement for the `DirectXShaderCompiler (DXC) 21<https://github.com/microsoft/DirectXShaderCompiler/>`_ in all its supported 22use cases. Accomplishing that goal will require Clang to be able to process most 23existing HLSL programs with a high degree of source compatibility. 24 25Non-Goals 26--------- 27 28HLSL ASTs do not need to be compatible between DXC and Clang. We do not expect 29identical code generation or that features will resemble DXC's implementation or 30architecture. In fact, we explicitly expect to deviate from DXC's implementation 31in key ways. 32 33Guiding Principles 34================== 35 36This document lacks details for architectural decisions that are not yet 37finalized. Our top priorities are quality, maintainability, and flexibility. In 38accordance with community standards we are expecting a high level of test 39coverage, and we will engineer our solutions with long term maintenance in mind. 40We are also working to limit modifications to the Clang C++ code paths and 41share as much functionality as possible. 42 43Architectural Direction 44======================= 45 46HLSL support in Clang is expressed as C++ minus unsupported C and C++ features. 47This is different from how other Clang languages are implemented. Most languages 48in Clang are additive on top of C. 49 50HLSL is not a formally or fully specified language, and while our goals require 51a high level of source compatibility, implementations can vary and we have some 52flexibility to be more or less permissive in some cases. For modern HLSL DXC is 53the reference implementation. 54 55The HLSL effort prioritizes following similar patterns for other languages, 56drivers, runtimes and targets. Specifically, We will maintain separation between 57HSLS-specific code and the rest of Clang as much as possible following patterns 58in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL*.cpp...). 59We will use inline checks on language options where the code is simple and 60isolated, and prefer HLSL-specific implementation files for any code of 61reasonable complexity. 62 63In places where the HLSL language is in conflict with C and C++, we will seek to 64make minimally invasive changes guarded under the HLSL language options. We will 65seek to make HLSL language support as minimal a maintenance burden as possible. 66 67DXC Driver 68---------- 69 70A DXC driver mode will provide command-line compatibility with DXC, supporting 71DXC's options and flags. The DXC driver is HLSL-specific and will create an 72HLSLToolchain which will provide the basis to support targeting both DirectX and 73Vulkan. 74 75Parser 76------ 77 78Following the examples of other parser extensions HLSL will add a ParseHLSL.cpp 79file to contain the implementations of HLSL-specific extensions to the Clang 80parser. The HLSL grammar shares most of its structure with C and C++, so we will 81use the existing C/C++ parsing code paths. 82 83Sema 84---- 85 86HLSL's Sema implementation will also provide an ``ExternalSemaSource``. In DXC, 87an ``ExternalSemaSource`` is used to provide definitions for HLSL built-in data 88types and built-in templates. Clang is already designed to allow an attached 89``ExternalSemaSource`` to lazily complete data types, which is a **huge** 90performance win for HLSL. 91 92If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource`` 93will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader`` 94and ``HLSLExternalSemaSource``. For Built-in declarations that are already 95completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the 96existing declarations and not introduce new declarations. If the built-in types 97are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will 98create new declarations and connect the de-serialized decls as the previous 99declaration. 100 101CodeGen 102------- 103 104Like 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 106be idiomatic Clang IR as much as possible. We will use IR attributes wherever we 107can, and use metadata as sparingly as possible. One example of a difference from 108DXC already implemented in Clang is the use of target triples to communicate 109shader model versions and shader stages. 110 111Our HLSL CodeGen implementation should also have an eye toward generating IR 112that will map directly to targets other than DXIL. While IR itself is generally 113not re-targetable, we want to share the Clang CodeGen implementation for HLSL 114with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU 115targets. 116 117HLSL Language 118============= 119 120The HLSL language is insufficiently documented, and not formally specified. 121Documentation is available on `Microsoft's website 122<https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl>`_. 123The language syntax is similar enough to C and C++ that carefully written C and 124C++ code is valid HLSL. HLSL has some key differences from C & C++ which we will 125need to handle in Clang. 126 127HLSL is not a conforming or valid extension or superset of C or C++. The 128language has key incompatibilities with C and C++, both syntactically and 129semantically. 130 131An Aside on GPU Languages 132------------------------- 133 134Due to HLSL being a GPU targeted language HLSL is a Single Program Multiple Data 135(SPMD) language relying on the implicit parallelism provided by GPU hardware. 136Some language features in HLSL enable programmers to take advantage of the 137parallel nature of GPUs in a hardware abstracted language. 138 139HLSL also prohibits some features of C and C++ which can have catastrophic 140performance or are not widely supportable on GPU hardware or drivers. As an 141example, register spilling is often excessively expensive on GPUs, so HLSL 142requires all functions to be inlined during code generation, and does not 143support a runtime calling convention. 144 145Pointers & References 146--------------------- 147 148HLSL does not support referring to values by address. Semantically all variables 149are value-types and behave as such. HLSL disallows the pointer dereference 150operators (unary ``*``, and ``->``), as well as the address of operator (unary 151&). While HLSL disallows pointers and references in the syntax, HLSL does use 152reference types in the AST, and we intend to use pointer decay in the AST in 153the Clang implementation. 154 155HLSL ``this`` Keyword 156--------------------- 157 158HLSL does support member functions, and (in HLSL 2021) limited operator 159overloading. With member function support, HLSL also has a ``this`` keyword. The 160``this`` keyword is an example of one of the places where HLSL relies on 161references in the AST, because ``this`` is a reference. 162 163Bitshifts 164--------- 165 166In deviation from C, HLSL bitshifts are defined to mask the shift count by the 167size of the type. In DXC, the semantics of LLVM IR were altered to accommodate 168this, in Clang we intend to generate the mask explicitly in the IR. In cases 169where the shift value is constant, this will be constant folded appropriately, 170in other cases we can clean it up in the DXIL target. 171 172Non-short Circuiting Logical Operators 173-------------------------------------- 174 175In HLSL 2018 and earlier, HLSL supported logical operators (and the ternary 176operator) on vector types. This behavior required that operators not short 177circuit. The non-short circuiting behavior applies to all data types until HLSL 1782021. In HLSL 2021, logical and ternary operators do not support vector types 179instead builtin functions ``and``, ``or`` and ``select`` are available, and 180operators short circuit matching C behavior. 181 182Precise Qualifier 183----------------- 184 185HLSL has a ``precise`` qualifier that behaves unlike anything else in the C 186language. The support for this qualifier in DXC is buggy, so our bar for 187compatibility is low. 188 189The ``precise`` qualifier applies in the inverse direction from normal 190qualifiers. Rather than signifying that the declaration containing ``precise`` 191qualifier be precise, it signifies that the operations contributing to the 192declaration's value be ``precise``. Additionally, ``precise`` is a misnomer: 193values attributed as ``precise`` comply with IEEE-754 floating point semantics, 194and are prevented from optimizations which could decrease *or increase* 195precision. 196 197Differences in Templates 198------------------------ 199 200HLSL uses templates to define builtin types and methods, but disallowed 201user-defined templates until HLSL 2021. HLSL also allows omitting empty template 202parameter lists when all template parameters are defaulted. This is an ambiguous 203syntax in C++, but Clang detects the case and issues a diagnostic. This makes 204supporting the case in Clang minimally invasive. 205 206Vector Extensions 207----------------- 208 209HLSL uses the OpenCL vector extensions, and also provides C++-style constructors 210for vectors that are not supported by Clang. 211 212Standard Library 213---------------- 214 215HLSL does not support the C or C++ standard libraries. Like OpenCL, HLSL 216describes its own library of built in types, complex data types, and functions. 217 218Unsupported C & C++ Features 219---------------------------- 220 221HLSL does not support all features of C and C++. In implementing HLSL in Clang 222use of some C and C++ features will produce diagnostics under HLSL, and others 223will be supported as language extensions. In general, any C or C++ feature that 224can be supported by the DXIL and SPIR-V code generation targets could be treated 225as a clang HLSL extension. Features that cannot be lowered to DXIL or SPIR-V, 226must be diagnosed as errors. 227 228HLSL does not support the following C features: 229 230* Pointers 231* References 232* ``goto`` or labels 233* Variable Length Arrays 234* ``_Complex`` and ``_Imaginary`` 235* C Threads or Atomics (or Obj-C blocks) 236* ``union`` types `(in progress for HLSL 202x) <https://github.com/microsoft/DirectXShaderCompiler/pull/4132>`_ 237* Most features C11 and later 238 239HLSL does not support the following C++ features: 240 241* RTTI 242* Exceptions 243* Multiple inheritance 244* Access specifiers 245* Anonymous or inline namespaces 246* ``new`` & ``delete`` operators in all of their forms (array, placement, etc) 247* Constructors and destructors 248* Any use of the ``virtual`` keyword 249* Most features C++11 and later 250