Skip to content

Commit 22a926f

Browse files
committed
Add --dump-spirt for dumping only the final SPIR-T module (unlike --dump-spirt-passes).
1 parent 2232fcb commit 22a926f

3 files changed

Lines changed: 63 additions & 14 deletions

File tree

crates/rustc_codegen_spirv/src/codegen_cx/mod.rs

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

332332
impl CodegenArgs {
333333
pub fn from_session(sess: &Session) -> Self {
334-
match CodegenArgs::parse(&sess.opts.cg.llvm_args) {
334+
match Self::parse(sess, &sess.opts.cg.llvm_args) {
335335
Ok(ok) => ok,
336+
337+
// FIXME(eddyb) this should mention `RUSTGPU_CODEGEN_ARGS`, just
338+
// like how `RUSTGPU_CODEGEN_ARGS=--help` is already special-cased.
336339
Err(err) => sess
337340
.dcx()
338341
.fatal(format!("Unable to parse llvm-args: {err}")),
339342
}
340343
}
341344

342-
// FIXME(eddyb) `structopt` would come a long way to making this nicer.
343-
pub fn parse(args: &[String]) -> Result<Self, rustc_session::getopts::Fail> {
345+
// FIXME(eddyb) switch all of this over to `clap`.
346+
pub fn parse(sess: &Session, args: &[String]) -> Result<Self, rustc_session::getopts::Fail> {
344347
use rustc_session::getopts;
345348

346349
// FIXME(eddyb) figure out what casing ("Foo bar" vs "foo bar") to use
@@ -459,6 +462,12 @@ impl CodegenArgs {
459462
"dump the SPIR-T module across passes, to a (pair of) file(s) in DIR",
460463
"DIR",
461464
);
465+
opts.optopt(
466+
"",
467+
"dump-spirt",
468+
"dump the final SPIR-T module, to a (pair of) file(s) in DIR",
469+
"DIR",
470+
);
462471
opts.optflag(
463472
"",
464473
"spirt-strip-custom-debuginfo-from-dumps",
@@ -627,7 +636,19 @@ impl CodegenArgs {
627636
dump_pre_inline: matches_opt_dump_dir_path("dump-pre-inline"),
628637
dump_post_inline: matches_opt_dump_dir_path("dump-post-inline"),
629638
dump_post_split: matches_opt_dump_dir_path("dump-post-split"),
630-
dump_spirt_passes: matches_opt_dump_dir_path("dump-spirt-passes"),
639+
dump_spirt: match ["dump-spirt-passes", "dump-spirt"].map(matches_opt_dump_dir_path) {
640+
[Some(dump_spirt_passes), dump_spirt] => {
641+
if dump_spirt.is_some() {
642+
sess.dcx()
643+
.warn("`--dump-spirt` ignored in favor of `--dump-spirt-passes`");
644+
}
645+
Some((dump_spirt_passes, crate::linker::DumpSpirtMode::AllPasses))
646+
}
647+
[None, Some(dump_spirt)] => {
648+
Some((dump_spirt, crate::linker::DumpSpirtMode::OnlyFinal))
649+
}
650+
[None, None] => None,
651+
},
631652
spirt_strip_custom_debuginfo_from_dumps: matches
632653
.opt_present("spirt-strip-custom-debuginfo-from-dumps"),
633654
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
@@ -61,13 +61,19 @@ pub struct Options {
6161
pub dump_pre_inline: Option<PathBuf>,
6262
pub dump_post_inline: Option<PathBuf>,
6363
pub dump_post_split: Option<PathBuf>,
64-
pub dump_spirt_passes: Option<PathBuf>,
64+
pub dump_spirt: Option<(PathBuf, DumpSpirtMode)>,
6565
pub spirt_strip_custom_debuginfo_from_dumps: bool,
6666
pub spirt_keep_debug_sources_in_dumps: bool,
6767
pub spirt_keep_unstructured_cfg_in_dumps: bool,
6868
pub specializer_dump_instances: Option<PathBuf>,
6969
}
7070

71+
#[derive(Copy, Clone, PartialEq, Eq)]
72+
pub enum DumpSpirtMode {
73+
AllPasses,
74+
OnlyFinal,
75+
}
76+
7177
pub enum LinkResult {
7278
SingleModule(Box<Module>),
7379
MultipleModules {
@@ -520,7 +526,7 @@ pub fn link(
520526
drop(timer);
521527
let pass_name = dump_guard.in_progress_pass_name.take().unwrap();
522528
if let Some(module) = module
523-
&& opts.dump_spirt_passes.is_some()
529+
&& matches!(opts.dump_spirt, Some((_, DumpSpirtMode::AllPasses)))
524530
{
525531
dump_guard
526532
.per_pass_module_for_dumping
@@ -801,9 +807,9 @@ impl Drop for SpirtDumpGuard<'_> {
801807

802808
let mut dump_spirt_file_path =
803809
self.linker_options
804-
.dump_spirt_passes
810+
.dump_spirt
805811
.as_ref()
806-
.map(|dump_dir| {
812+
.map(|(dump_dir, _)| {
807813
dump_dir
808814
.join(self.disambiguated_crate_name_for_dumps)
809815
.with_extension("spirt")
@@ -815,17 +821,18 @@ impl Drop for SpirtDumpGuard<'_> {
815821
// but that requires keeping around e.g. the initial SPIR-V for longer,
816822
// and probably invoking the "SPIR-T pipeline" here, as looping is hard).
817823
if self.any_spirt_bugs && dump_spirt_file_path.is_none() {
818-
if self.per_pass_module_for_dumping.is_empty() {
819-
self.per_pass_module_for_dumping
820-
.push(("".into(), self.module.clone()));
821-
}
822824
dump_spirt_file_path = Some(self.outputs.temp_path_for_diagnostic("spirt"));
823825
}
824826

825827
let Some(dump_spirt_file_path) = &dump_spirt_file_path else {
826828
return;
827829
};
828830

831+
if self.per_pass_module_for_dumping.is_empty() {
832+
self.per_pass_module_for_dumping
833+
.push(("".into(), self.module.clone()));
834+
}
835+
829836
for (_, module) in &mut self.per_pass_module_for_dumping {
830837
// FIXME(eddyb) consider catching panics in this?
831838
self.linker_options.spirt_cleanup_for_dumping(module);
@@ -835,7 +842,16 @@ impl Drop for SpirtDumpGuard<'_> {
835842
let versions = self
836843
.per_pass_module_for_dumping
837844
.iter()
838-
.map(|(pass_name, module)| (format!("after {pass_name}"), module));
845+
.map(|(pass_name, module)| {
846+
(
847+
if pass_name.is_empty() {
848+
"".into()
849+
} else {
850+
format!("after {pass_name}")
851+
},
852+
module,
853+
)
854+
});
839855

840856
let mut panicked_printing_after_passes = None;
841857
for truncate_version_count in (1..=versions.len()).rev() {
@@ -896,7 +912,11 @@ impl Drop for SpirtDumpGuard<'_> {
896912
"pretty-printed SPIR-T was saved to {}.html",
897913
dump_spirt_file_path.display()
898914
));
899-
if self.linker_options.dump_spirt_passes.is_none() {
915+
let is_dumping_spirt_passes = matches!(
916+
self.linker_options.dump_spirt,
917+
Some((_, DumpSpirtMode::AllPasses))
918+
);
919+
if !is_dumping_spirt_passes {
900920
note.help("re-run with `RUSTGPU_CODEGEN_ARGS=\"--dump-spirt-passes=$PWD\"` for more details");
901921
}
902922
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)