"Codegen args" (flags/options) supported by the Rust-GPU codegen backend
Please keep in mind that many of these flags/options are for internal development, and may break output unexpectedly and generally muck things up. Please only use these if you know what you're doing.
Help is also appreciated keeping this document up to date, "codegen args" flags/options may be added/removed on an ad-hoc basis without much thought, as they're internal development tools, not a public API - this documentation is only here because these flags/options may be helpful diagnosing problems for others.
It's recommended that "codegen args" options that take paths to files or directories are set to full paths, as the working directory of the compiler might be something wonky and unexpected, and it's easier to set the full path.
How to set "codegen args" flags/options
The most convenient method is relying on spirv-builder
reading the RUSTGPU_CODEGEN_ARGS
environment variable, e.g.:
$ RUSTGPU_CODEGEN_ARGS="--no-spirv-val --dump-post-link=$PWD/postlink" cargo run -p example-runner-wgpu
...
Finished release [optimized] target(s) in 15.15s
$ file postlink/*
postlink/module: Khronos SPIR-V binary, little-endian, version 0x010300, generator 0x1b0000
Notably, RUSTGPU_CODEGEN_ARGS="--help"
can be used to see a "usage" message (which lists all the flags/options, including ones not listed in this document), via e.g. running a Cargo build that relies on spirv-builder
.
However, it's only a convenient alias for for RUSTGPU_RUSTFLAGS=-Cllvm-args="..."
(without having to expose the fact that LLVM's name is still attached to rustc
's interface for this functionality), and if in direct control of rustc
, you can still pass such "codegen args" flags/options wrapped in -C llvm-args="..."
.
Historical note about past "environment variables"
Many of these flags/options were at one point, individual environment variable (e.g. the --dump-pre-link
option used to be the environment variable DUMP_PRE_LINK
).
However, that approach is prone to various failure modes, because the environment variables would not get registered as a "dependency" (without extra work that never happened), and the idea of "codegen args" fits better with existing practices (e.g. rustc -C llvm-args="..."
for the LLVM codegen backend of rustc
).
For more context see also PR #959, which made the transition to this system.
Where are all the rest of the flags/options documented?
If you do run a build with RUSTGPU_CODEGEN_ARGS="--help"
(or -C llvm-args="--help"
), you will notice more flags/options than are listed in this documented.
This is a historical artifact: as mentioned above, these used to be environment variables, and this document only described those, without talking about the older "codegen args" at all.
While most of those flags are usually only exposed through higher-level spirv-builder
APIs, it would be nice to have all of them documented in one place (eventually?).
Debugging "codegen args" flags/options
As mentioned above, these form the bulk of "codegen args", but keep in mind the list is not exhaustive and you will want to check the full list with e.g. RUSTGPU_CODEGEN_ARGS="--help"
.
--dump-mir DIR
Dumps the MIR of every function rust-gpu encounters, to files in DIR
. Yes, rustc does have options to do
this by default, but I always forget the syntax, and plumbing through the option to spirv-builder
is annoying, so this is handy to just hack an output.
FIXME(@eddyb) this may be irrelevant now given RUSTGPU_RUSTFLAGS
--dump-module-on-panic FILE
If codegen panics, then write the (partially) emitted module to FILE
. Note that this only exists
for codegen, if the linker panics, this option does nothing, sadly.
--dump-pre-link DIR
Dumps all input modules to the linker, to files in DIR
, before the linker touches them at all.
--dump-post-merge DIR
Dumps the merged module, to a file in DIR
, immediately after merging, but before the linker has done anything else
(including, well, linking the methods - LinkageAttributes
will still exist, etc.). This is very
similar to --dump-pre-link
, except it outputs only a single file, which might make grepping through
for stuff easier.
--dump-post-split DIR
Dumps the modules, to files in DIR
, immediately after multimodule splitting, but before final cleanup passes (e.g.
DCE to remove the other entry points).
--dump-post-link DIR
Takes: path to directory
Dumps all output modules from the linker, to files in DIR
. This may be multiple files due to the multimodule/module
splitting option, hence it takes a directory instead of a file path. This is the final output
binary before spirv-opt
is executed, so it may be useful to output this to check if an issue is in
Rust-GPU, or in spirv-opt
.
--specializer-debug
Enables debug logging for the specializer.
FIXME(@eddyb) use log
/tracing
instead for this purpose
--specializer-dump-instances FILE
Dumps to FILE
all instances inferred by the specializer.
--print-zombie
Prints to rustc stdout which functions were removed due to being zombies, and why.
FIXME(@eddyb) use log
/tracing
instead for this purpose
--print-all-zombie
Prints to rustc stdout everything that was removed due to being zombies, why, and if it was an original zombie or if it was infected. (prints a lot!)
FIXME(@eddyb) use log
/tracing
instead for this purpose
--no-spirv-val
Disables running spirv-val
on the final output. Spooky scary option, can cause invalid modules!
--no-spirv-opt
Forcibly disables running spirv-opt
on the final output, even if optimizations are enabled.
--no-dce
Disables running dead code elimination. Can and probably will generate invalid modules or crash the linker, hasn't been tested for a while.
--no-compact-ids
Disables compaction of SPIR-V IDs at the end of linking. Causes absolutely ginormous IDs to be emitted. Useful if you're println debugging IDs in the linker (although spirv-opt will compact them anyway, be careful).
--no-early-report-zombies
Delays reporting zombies (aka "deferred errors") even further, to allow more legalization. Currently this also replaces the zombie reporting with a SPIR-T-based version (which may become the default in the future).
--no-infer-storage-classes
Disables the old SPIR-V "Storage Class" (i.e. address space) inference pass,
to allow testing alternatives to it (such as SPIR-T qptr
passes).
Note that this will produce illegal SPIR-V by default, and you need e.g.
--spirt-passes=qptr
in order to regain legal "Storage Class" assignments
(see SPIR-T qptr
PR for more information on qptr
in general)
--no-structurize
Disables CFG structurization. Probably results in invalid modules.
--spirt
(until 0.6.0)
Note: as of
Note: as of rust-gpu 0.6.0
, SPIR-🇹
is enabled by default. Use --no-spirt
to disable.rust-gpu 0.8.0
, SPIR-🇹
is always being used and cannot be disabled
(to reduce the cost of maintenance, testing and further feature development).
Enables using the experimental SPIR-🇹
shader IR framework in the linker - more specifically, this:
- adds a
SPIR-V -> SPIR-🇹 -> SPIR-V
roundtrip
(futureSPIR-🇹
passes would go in the middle of this, and eventually codegen might not produceSPIR-V
at all) - replaces the existing structurizer with
SPIR-🇹
structurization (which is more robust and can e.g. handleOpPhi
s) - runs some existing
SPIR-V
legalization/optimization passes (mem2reg
) before inlining, instead of only after (as theOpPhi
s they would produce are no longer an issue for structurization)
For more information, also see the SPIR-🇹
repository.
--no-spirt
(0.6.0 and 0.7.0)
Note: as of rust-gpu 0.8.0
, SPIR-🇹
is always being used and cannot be disabled
(to reduce the cost of maintenance, testing and further feature development).
Note: if you were using --no-spirt
to work around naga
issue #1977
(valid loops causing The 'break' is used outside of a 'loop' or 'switch' context
),
you may be able to cargo update -p naga
to update to a fixed naga
version
(0.11.1
for wgpu 0.15
, 0.12.1
for wgpu 0.16
, and any later versions).
Disables the SPIR-🇹
shader IR framework in the linker.
--spirt-passes PASSES
Enable additional SPIR-🇹
passes, as listed in PASSES
(comma-separated).
Their implementation can be found in rustc_codegen_spirv::linker::spirt_passes
.
Note: passes that are not already enabled by default are considered experimental and likely not ready for production use, this flag exists primarily for testing.
--dump-spirt-passes DIR
Dump the SPIR-🇹
module across passes (i.e. all of the versions before/after each pass), as a combined report, to a pair of files (.spirt
and .spirt.html
) in DIR
.
(the .spirt.html
version of the report is the recommended form for viewing, as it uses tabling for versions, syntax-highlighting-like styling, and use->def linking)
--spirt-strip-custom-debuginfo-from-dumps
When dumping (pretty-printed) SPIR-🇹
(e.g. with --dump-spirt-passes
), strip
all the custom (Rust-GPU-specific) debuginfo instructions, by converting them
to the standard SPIR-V debuginfo (which SPIR-🇹
understands more directly).
The default (keeping the custom instructions) is more verbose, but also lossless,
if you want to see all instructions exactly as e.g. --spirt-passes
see them.
--spirt-keep-debug-sources-in-dumps
When dumping (pretty-printed) SPIR-🇹
(e.g. with --dump-spirt-passes
), preserve
all the "file contents debuginfo" (i.e. from SPIR-V OpSource
instructions),
which will end up being included, in full, at the start of the dump.
The default (of hiding the file contents) is less verbose, but (arguably) lossier.
--spirt-keep-unstructured-cfg-in-dumps
When dumping (pretty-printed) SPIR-🇹
(e.g. with --dump-spirt-passes
), include
the initial unstructured state, as well (i.e. just after lowering from SPIR-V).
The default (of only dumping structured SPIR-T) can have far less noisy dataflow, but unstructured SPIR-T may be needed for e.g. debugging the structurizer itself.