Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a spirv-builder option to include all debug info #742

Merged
merged 3 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions crates/rustc_codegen_spirv/src/codegen_cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,21 @@ impl<'tcx> CodegenCx<'tcx> {
}
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SpirvMetadata {
None,
NameVariables,
Full,
}

pub struct CodegenArgs {
pub module_output_type: ModuleOutputType,
pub disassemble: bool,
pub disassemble_fn: Option<String>,
pub disassemble_entry: Option<String>,
pub disassemble_globals: bool,

pub name_variables: bool,
pub spirv_metadata: SpirvMetadata,

// spirv-val flags
pub relax_struct_store: bool,
Expand Down Expand Up @@ -273,12 +280,7 @@ impl CodegenArgs {
);
opts.optflagopt("", "disassemble-globals", "print globals to stderr", "");

opts.optflagopt(
"",
"name-variables",
"Keep OpName for OpVariables, strip all others.",
"",
);
opts.optopt("", "spirv-metadata", "how much metadata to include", "");

opts.optflagopt("", "relax-struct-store", "Allow store from one struct type to a different type with compatible layout and members.", "");
opts.optflagopt("", "relax-logical-pointer", "Allow allocating an object of a pointer type and returning a pointer value from a function in logical addressing mode", "");
Expand All @@ -295,7 +297,7 @@ impl CodegenArgs {
let disassemble_entry = matches.opt_str("disassemble-entry");
let disassemble_globals = matches.opt_present("disassemble-globals");

let name_variables = matches.opt_present("name-variables");
let spirv_metadata = matches.opt_str("spirv-metadata");

let relax_struct_store = matches.opt_present("relax-struct-store");
let relax_logical_pointer = matches.opt_present("relax-logical-pointer");
Expand All @@ -306,14 +308,25 @@ impl CodegenArgs {

let relax_block_layout = if relax_block_layout { Some(true) } else { None };

let spirv_metadata = match spirv_metadata.as_deref() {
None => SpirvMetadata::None,
Some("full") => SpirvMetadata::Full,
Some("name-variables") => SpirvMetadata::NameVariables,
Some(v) => {
return Err(rustc_session::getopts::Fail::UnrecognizedOption(
v.to_string(),
))
}
};

Ok(Self {
module_output_type,
disassemble,
disassemble_fn,
disassemble_entry,
disassemble_globals,

name_variables,
spirv_metadata,

relax_struct_store,
relax_logical_pointer,
Expand Down
8 changes: 4 additions & 4 deletions crates/rustc_codegen_spirv/src/link.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::codegen_cx::{CodegenArgs, ModuleOutputType};
use crate::codegen_cx::{CodegenArgs, ModuleOutputType, SpirvMetadata};
use crate::{
linker, CompileResult, ModuleResult, SpirvCodegenBackend, SpirvModuleBuffer, SpirvThinBuffer,
};
Expand Down Expand Up @@ -210,7 +210,7 @@ fn post_link_single_module(
};

let spv_binary = if sess.opts.optimize != OptLevel::No
|| (sess.opts.debuginfo == DebugInfo::None && !cg_args.name_variables)
|| (sess.opts.debuginfo == DebugInfo::None && cg_args.spirv_metadata == SpirvMetadata::None)
{
if env::var("NO_SPIRV_OPT").is_err() {
let _timer = sess.timer("link_spirv_opt");
Expand Down Expand Up @@ -273,7 +273,7 @@ fn do_spirv_opt(
}
}

if sess.opts.debuginfo == DebugInfo::None && !cg_args.name_variables {
if sess.opts.debuginfo == DebugInfo::None && cg_args.spirv_metadata == SpirvMetadata::None {
optimizer
.register_pass(opt::Passes::EliminateDeadConstant)
.register_pass(opt::Passes::StripDebugInfo);
Expand Down Expand Up @@ -528,7 +528,7 @@ fn do_link(
compact_ids: env::var("NO_COMPACT_IDS").is_err(),
structurize: env::var("NO_STRUCTURIZE").is_err(),
emit_multiple_modules: cg_args.module_output_type == ModuleOutputType::Multiple,
name_variables: cg_args.name_variables,
spirv_metadata: cg_args.spirv_metadata,
};

let link_result = linker::link(sess, modules, &options);
Expand Down
5 changes: 3 additions & 2 deletions crates/rustc_codegen_spirv/src/linker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod specializer;
mod structurizer;
mod zombies;

use crate::codegen_cx::SpirvMetadata;
use crate::decorations::{CustomDecoration, UnrollLoopsDecoration};
use rspirv::binary::{Assemble, Consumer};
use rspirv::dr::{Block, Instruction, Loader, Module, ModuleHeader, Operand};
Expand All @@ -30,7 +31,7 @@ pub struct Options {
pub dce: bool,
pub structurize: bool,
pub emit_multiple_modules: bool,
pub name_variables: bool,
pub spirv_metadata: SpirvMetadata,
}

pub enum LinkResult {
Expand Down Expand Up @@ -246,7 +247,7 @@ pub fn link(sess: &Session, mut inputs: Vec<Module>, opts: &Options) -> Result<L
}
}

if opts.name_variables {
if opts.spirv_metadata == SpirvMetadata::NameVariables {
let _timer = sess.timer("link_name_variables");
simple_passes::name_variables_pass(&mut output);
}
Expand Down
3 changes: 2 additions & 1 deletion crates/rustc_codegen_spirv/src/linker/test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{link, LinkResult, Options};
use crate::codegen_cx::SpirvMetadata;
use pipe::pipe;
use rspirv::dr::{Loader, Module};
use rustc_driver::handle_options;
Expand Down Expand Up @@ -93,7 +94,7 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, String> {
dce: false,
structurize: false,
emit_multiple_modules: false,
name_variables: false,
spirv_metadata: SpirvMetadata::None,
},
);
assert_eq!(compiler.session().has_errors(), res.is_err());
Expand Down
39 changes: 22 additions & 17 deletions crates/spirv-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,7 @@ impl fmt::Display for SpirvBuilderError {

impl Error for SpirvBuilderError {}

pub enum MemoryModel {
Simple,
Vulkan,
GLSL450,
}

#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum MetadataPrintout {
/// Print no cargo metadata.
None,
Expand All @@ -143,14 +137,25 @@ pub enum MetadataPrintout {
Full,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SpirvMetadata {
/// Strip all names and other debug information from SPIR-V output.
None,
/// Only include OpNames for public interface variables (uniforms and the like), to allow
/// shader reflection.
NameVariables,
/// Include all OpNames for everything, and OpLines. Significantly increases binary size.
Full,
}

pub struct SpirvBuilder {
path_to_crate: PathBuf,
print_metadata: MetadataPrintout,
release: bool,
target: String,
deny_warnings: bool,
multimodule: bool,
name_variables: bool,
spirv_metadata: SpirvMetadata,
capabilities: Vec<Capability>,
extensions: Vec<String>,

Expand All @@ -172,7 +177,7 @@ impl SpirvBuilder {
target: target.into(),
deny_warnings: false,
multimodule: false,
name_variables: false,
spirv_metadata: SpirvMetadata::None,
capabilities: Vec::new(),
extensions: Vec::new(),

Expand Down Expand Up @@ -210,12 +215,10 @@ impl SpirvBuilder {
self
}

/// Keep `OpName` reflection information for global `OpVariable`s (which means things like
/// uniforms and shader input/outputs) but strip `OpName`s for everything else (functions,
/// types, and so on). This is useful if you want a small binary size without debugging
/// information, but need variable name reflection to work.
pub fn name_variables(mut self, v: bool) -> Self {
self.name_variables = v;
/// Sets the level of metadata (primarily `OpName` and `OpLine`) included in the SPIR-V binary.
/// Including metadata significantly increases binary size.
pub fn spirv_metadata(mut self, v: SpirvMetadata) -> Self {
self.spirv_metadata = v;
self
}

Expand Down Expand Up @@ -399,8 +402,10 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
if builder.multimodule {
llvm_args.push("--module-output=multiple");
}
if builder.name_variables {
llvm_args.push("--name-variables");
match builder.spirv_metadata {
SpirvMetadata::None => (),
SpirvMetadata::NameVariables => llvm_args.push("--spirv-metadata=name-variables"),
SpirvMetadata::Full => llvm_args.push("--spirv-metadata=full"),
}
if builder.relax_struct_store {
llvm_args.push("--relax-struct-store");
Expand Down