Skip to content

Commit 151559c

Browse files
authored
[DirectX][docs] Architecture and design philosophy of DXIL support
This documents some of the architectural direction for DXIL and tries to provide a bit of a map for where to implement different aspects of DXIL support. Pull Request: #78221
1 parent dad50fe commit 151559c

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
===============================================
2+
Architecture and Design of DXIL Support in LLVM
3+
===============================================
4+
5+
.. contents::
6+
:local:
7+
8+
.. toctree::
9+
:hidden:
10+
11+
Introduction
12+
============
13+
14+
LLVM supports reading and writing the `DirectX Intermediate Language.
15+
<https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst>`_,
16+
or DXIL. DXIL is essentially LLVM 3.7 era bitcode with some
17+
restrictions and various semantically important operations and
18+
metadata.
19+
20+
LLVM's implementation philosophy for DXIL support is to treat DXIL as
21+
merely a representation format as much as possible. When reading DXIL,
22+
we should translate everything to generic LLVM constructs when
23+
possible. Similarly, we should introduce DXIL-specific constructs as
24+
late as possible in the process of lowering to the format.
25+
26+
There are three places to look for DXIL related code in LLVM: The
27+
`DirectX` backend, for writing DXIL; The `DXILUpgrade` pass, for
28+
reading; and in library code that is shared between writing and
29+
reading. We'll describe these in reverse order.
30+
31+
Common Code for Reading and Writing
32+
===================================
33+
34+
There's quite a bit of logic that needs to be shared between reading
35+
and writing DXIL in order to avoid code duplication. While we don't
36+
have a hard and fast rule about where such code should live, there are
37+
generally three sensible places. Simple definitions of enums and
38+
values that must stay fixed to match DXIL's ABI can be found in
39+
`Support/DXILABI.h`, utilities to translate bidirectionally between
40+
DXIL and modern LLVM constructs live in `lib/Transforms/Utils`, and
41+
more analyses that are needed to derive or preserve information are
42+
implemented as typical `lib/Analysis` passes.
43+
44+
The DXILUpgrade Pass
45+
====================
46+
47+
Translating DXIL to LLVM IR takes advantage of the fact that DXIL is
48+
compatible with LLVM 3.7 bitcode, and that modern LLVM is capable of
49+
"upgrading" older bitcode into modern IR. Simply relying on the
50+
bitcode upgrade process isn't sufficient though, since that leaves a
51+
number of DXIL specific constructs around. Thus, we have the
52+
`DXILUpgrade` pass to transform DXIL operations to LLVM operations and
53+
smooth over differences in metadata representation. We call this pass
54+
"upgrade" to reflect that it follows LLVM's standard bitcode upgrade
55+
process and simply finishes the job for DXIL constructs - while
56+
"reader" or "lifting" might also be reasonable names, they could be a
57+
bit misleading.
58+
59+
The `DXILUpgrade` pass itself is fairly lightweight. It mostly relies
60+
on the utilities described in "Common Code" above in order to share
61+
logic with both the DirectX backend and with Clang's codegen of HLSL
62+
support as much as possible.
63+
64+
The DirectX Backend
65+
===================
66+
67+
The DirectX backend lowers LLVM IR into DXIL. As we're transforming to
68+
an intermediate format rather than a specific ISA, this backend does
69+
not follow the instruction selection patterns you might be familiar
70+
with from other backends. There are two parts to lowering DXIL - a set
71+
of passes that mutate various constructs into a form that matches how
72+
DXIL represents those constructs, followed by a limited bitcode
73+
"downgrader pass".
74+
75+
Before emitting DXIL, the DirectX backend needs to modify the LLVM IR
76+
such that external operations, types, and metadata is represented in
77+
the way that DXIL expects. For example, `DXILOpLowering` translates
78+
intrinsics into `dx.op` calls. These passes are essentially the
79+
inverse of the `DXILUpgrade` pass. It's best to do this downgrading
80+
process as IR to IR passes when possible, as that means that they can
81+
be easily tested with `opt` and `FileCheck` without the need for
82+
external tooling.
83+
84+
The second part of DXIL emission is more or less an LLVM bitcode
85+
downgrader. We need to emit bitcode that matches the LLVM 3.7
86+
representation. For this, we have `DXILWriter`, which is an alternate
87+
version of LLVM's `BitcodeWriter`. At present, this is able to
88+
leverage LLVM's current bitcode libraries to do a lot of the work, but
89+
it's possible that at some point in the future it will need to be
90+
completely separate as modern LLVM bitcode evolves.
91+
92+
Testing
93+
=======
94+
95+
A lot of DXIL testing can be done with typical IR to IR tests using
96+
`opt` and `FileCheck`, since a lot of the support is implemented in
97+
terms of IR level passes as described in the previous sections. You
98+
can see examples of this in `llvm/test/CodeGen/DirectX` as well as
99+
`llvm/test/Transforms/DXILUpgrade`, and this type of testing should be
100+
leveraged as much as possible.
101+
102+
However, when it comes to testing the DXIL format itself, IR passes
103+
are insufficient for testing. For now, the best option we have
104+
available is using the DXC project's tools in order to round trip.
105+
These tests are currently found in `test/tools/dxil-dis` and are only
106+
available if the `LLVM_INCLUDE_DXIL_TESTS` cmake option is set. Note
107+
that we do not currently have the equivalent testing set up for the
108+
DXIL reading path.
109+
110+
As soon as we are able, we will also want to round trip using the DXIL
111+
writing and reading paths in order to ensure self consistency and to
112+
get test coverage when `dxil-dis` isn't available.

llvm/docs/DirectXUsage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ User Guide for the DirectX Target
1313
.. toctree::
1414
:hidden:
1515

16+
DirectX/DXILArchitecture
17+
1618
Introduction
1719
============
1820

0 commit comments

Comments
 (0)