Skip to content

Commit ab9ca5e

Browse files
committed
Add --dump-spirt for dumping only the final SPIR-T module (unlike --dump-spirt-passes).
1 parent 003dde7 commit ab9ca5e

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

crates/rustc_codegen_spirv/src/codegen_cx/mod.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,16 +368,19 @@ pub struct CodegenArgs {
368368

369369
impl CodegenArgs {
370370
pub fn from_session(sess: &Session) -> Self {
371-
match CodegenArgs::parse(&sess.opts.cg.llvm_args) {
371+
match Self::parse(sess, &sess.opts.cg.llvm_args) {
372372
Ok(ok) => ok,
373+
374+
// FIXME(eddyb) this should mention `RUSTGPU_CODEGEN_ARGS`, just
375+
// like how `RUSTGPU_CODEGEN_ARGS=--help` is already special-cased.
373376
Err(err) => sess
374377
.dcx()
375378
.fatal(format!("Unable to parse llvm-args: {err}")),
376379
}
377380
}
378381

379-
// FIXME(eddyb) `structopt` would come a long way to making this nicer.
380-
pub fn parse(args: &[String]) -> Result<Self, rustc_session::getopts::Fail> {
382+
// FIXME(eddyb) switch all of this over to `clap`.
383+
pub fn parse(sess: &Session, args: &[String]) -> Result<Self, rustc_session::getopts::Fail> {
381384
use rustc_session::getopts;
382385

383386
// FIXME(eddyb) figure out what casing ("Foo bar" vs "foo bar") to use
@@ -496,6 +499,12 @@ impl CodegenArgs {
496499
"dump the SPIR-T module across passes, to a (pair of) file(s) in DIR",
497500
"DIR",
498501
);
502+
opts.optopt(
503+
"",
504+
"dump-spirt",
505+
"dump the final SPIR-T module, to a (pair of) file(s) in DIR",
506+
"DIR",
507+
);
499508
opts.optflag(
500509
"",
501510
"spirt-strip-custom-debuginfo-from-dumps",
@@ -663,7 +672,19 @@ impl CodegenArgs {
663672
dump_pre_inline: matches_opt_dump_dir_path("dump-pre-inline"),
664673
dump_post_inline: matches_opt_dump_dir_path("dump-post-inline"),
665674
dump_post_split: matches_opt_dump_dir_path("dump-post-split"),
666-
dump_spirt_passes: matches_opt_dump_dir_path("dump-spirt-passes"),
675+
dump_spirt: match ["dump-spirt-passes", "dump-spirt"].map(matches_opt_dump_dir_path) {
676+
[Some(dump_spirt_passes), dump_spirt] => {
677+
if dump_spirt.is_some() {
678+
sess.dcx()
679+
.warn("`--dump-spirt` ignored in favor of `--dump-spirt-passes`");
680+
}
681+
Some((dump_spirt_passes, crate::linker::DumpSpirtMode::AllPasses))
682+
}
683+
[None, Some(dump_spirt)] => {
684+
Some((dump_spirt, crate::linker::DumpSpirtMode::OnlyFinal))
685+
}
686+
[None, None] => None,
687+
},
667688
spirt_strip_custom_debuginfo_from_dumps: matches
668689
.opt_present("spirt-strip-custom-debuginfo-from-dumps"),
669690
spirt_keep_debug_sources_in_dumps: matches

crates/rustc_codegen_spirv/src/linker/mod.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,19 @@ pub struct Options {
6262
pub dump_pre_inline: Option<PathBuf>,
6363
pub dump_post_inline: Option<PathBuf>,
6464
pub dump_post_split: Option<PathBuf>,
65-
pub dump_spirt_passes: Option<PathBuf>,
65+
pub dump_spirt: Option<(PathBuf, DumpSpirtMode)>,
6666
pub spirt_strip_custom_debuginfo_from_dumps: bool,
6767
pub spirt_keep_debug_sources_in_dumps: bool,
6868
pub spirt_keep_unstructured_cfg_in_dumps: bool,
6969
pub specializer_dump_instances: Option<PathBuf>,
7070
}
7171

72+
#[derive(Copy, Clone, PartialEq, Eq)]
73+
pub enum DumpSpirtMode {
74+
AllPasses,
75+
OnlyFinal,
76+
}
77+
7278
pub enum LinkResult {
7379
SingleModule(Box<Module>),
7480
MultipleModules {
@@ -531,7 +537,7 @@ pub fn link(
531537
drop(timer);
532538
let pass_name = dump_guard.in_progress_pass_name.take().unwrap();
533539
if let Some(module) = module
534-
&& opts.dump_spirt_passes.is_some()
540+
&& matches!(opts.dump_spirt, Some((_, DumpSpirtMode::AllPasses)))
535541
{
536542
dump_guard
537543
.per_pass_module_for_dumping
@@ -812,9 +818,9 @@ impl Drop for SpirtDumpGuard<'_> {
812818

813819
let mut dump_spirt_file_path =
814820
self.linker_options
815-
.dump_spirt_passes
821+
.dump_spirt
816822
.as_ref()
817-
.map(|dump_dir| {
823+
.map(|(dump_dir, _)| {
818824
dump_dir
819825
.join(self.disambiguated_crate_name_for_dumps)
820826
.with_extension("spirt")
@@ -826,17 +832,18 @@ impl Drop for SpirtDumpGuard<'_> {
826832
// but that requires keeping around e.g. the initial SPIR-V for longer,
827833
// and probably invoking the "SPIR-T pipeline" here, as looping is hard).
828834
if self.any_spirt_bugs && dump_spirt_file_path.is_none() {
829-
if self.per_pass_module_for_dumping.is_empty() {
830-
self.per_pass_module_for_dumping
831-
.push(("".into(), self.module.clone()));
832-
}
833835
dump_spirt_file_path = Some(self.outputs.temp_path_for_diagnostic("spirt"));
834836
}
835837

836838
let Some(dump_spirt_file_path) = &dump_spirt_file_path else {
837839
return;
838840
};
839841

842+
if self.per_pass_module_for_dumping.is_empty() {
843+
self.per_pass_module_for_dumping
844+
.push(("".into(), self.module.clone()));
845+
}
846+
840847
for (_, module) in &mut self.per_pass_module_for_dumping {
841848
// FIXME(eddyb) consider catching panics in this?
842849
self.linker_options.spirt_cleanup_for_dumping(module);
@@ -846,7 +853,16 @@ impl Drop for SpirtDumpGuard<'_> {
846853
let versions = self
847854
.per_pass_module_for_dumping
848855
.iter()
849-
.map(|(pass_name, module)| (format!("after {pass_name}"), module));
856+
.map(|(pass_name, module)| {
857+
(
858+
if pass_name.is_empty() {
859+
"".into()
860+
} else {
861+
format!("after {pass_name}")
862+
},
863+
module,
864+
)
865+
});
850866

851867
let mut panicked_printing_after_passes = None;
852868
for truncate_version_count in (1..=versions.len()).rev() {
@@ -907,7 +923,11 @@ impl Drop for SpirtDumpGuard<'_> {
907923
"pretty-printed SPIR-T was saved to {}.html",
908924
dump_spirt_file_path.display()
909925
));
910-
if self.linker_options.dump_spirt_passes.is_none() {
926+
let is_dumping_spirt_passes = matches!(
927+
self.linker_options.dump_spirt,
928+
Some((_, DumpSpirtMode::AllPasses))
929+
);
930+
if !is_dumping_spirt_passes {
911931
note.help("re-run with `RUSTGPU_CODEGEN_ARGS=\"--dump-spirt-passes=$PWD\"` for more details");
912932
}
913933
note.note("pretty-printed SPIR-T is preferred when reporting Rust-GPU issues");

docs/src/codegen-args.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ _Note: passes that are not already enabled by default are considered experimenta
175175
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`.
176176
<sub>(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)</sub>
177177

178+
Mutually exclusive with `--dump-spirt` (this takes precedence over that).
179+
180+
### `--dump-spirt DIR`
181+
182+
Dump the `SPIR-🇹` module, similar to `--dump-spirt-passes`, but only the final version.
183+
184+
Mutually exclusive with `--dump-spirt-passes` (which takes precedence over this).
185+
178186
### `--spirt-strip-custom-debuginfo-from-dumps`
179187

180188
When dumping (pretty-printed) `SPIR-🇹` (e.g. with `--dump-spirt-passes`), strip

0 commit comments

Comments
 (0)