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

This commit is contained in:
Ashley Hauck 2021-09-01 08:05:43 +02:00 committed by GitHub
parent 66d6c554d8
commit 032286e217
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 33 deletions

View File

@ -228,6 +228,13 @@ 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,
@ -235,7 +242,7 @@ pub struct CodegenArgs {
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,
@ -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", "");
@ -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");
@ -306,6 +308,17 @@ 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,
@ -313,7 +326,7 @@ impl CodegenArgs {
disassemble_entry,
disassemble_globals,
name_variables,
spirv_metadata,
relax_struct_store,
relax_logical_pointer,

View File

@ -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,
};
@ -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");
@ -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);
@ -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);

View File

@ -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};
@ -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 {
@ -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);
}

View File

@ -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;
@ -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());

View File

@ -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,
@ -143,6 +137,17 @@ 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,
@ -150,7 +155,7 @@ pub struct SpirvBuilder {
target: String,
deny_warnings: bool,
multimodule: bool,
name_variables: bool,
spirv_metadata: SpirvMetadata,
capabilities: Vec<Capability>,
extensions: Vec<String>,
@ -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(),
@ -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
}
@ -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");