mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 06:45:13 +00:00
Add name_variables option to spirv-builder (#660)
This commit is contained in:
parent
b072b5ebdc
commit
c3eff4d4a5
@ -277,6 +277,8 @@ pub struct CodegenArgs {
|
|||||||
pub disassemble_entry: Option<String>,
|
pub disassemble_entry: Option<String>,
|
||||||
pub disassemble_globals: bool,
|
pub disassemble_globals: bool,
|
||||||
|
|
||||||
|
pub name_variables: bool,
|
||||||
|
|
||||||
// spirv-val flags
|
// spirv-val flags
|
||||||
pub relax_struct_store: bool,
|
pub relax_struct_store: bool,
|
||||||
pub relax_logical_pointer: bool,
|
pub relax_logical_pointer: bool,
|
||||||
@ -313,6 +315,13 @@ impl CodegenArgs {
|
|||||||
);
|
);
|
||||||
opts.optflagopt("", "disassemble-globals", "print globals to stderr", "");
|
opts.optflagopt("", "disassemble-globals", "print globals to stderr", "");
|
||||||
|
|
||||||
|
opts.optflagopt(
|
||||||
|
"",
|
||||||
|
"name-variables",
|
||||||
|
"Keep OpName for OpVariables, strip all others.",
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
|
||||||
opts.optflagopt("", "relax-struct-store", "Allow store from one struct type to a different type with compatible layout and members.", "");
|
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", "");
|
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", "");
|
||||||
opts.optflagopt("", "relax-block-layout", "Enable VK_KHR_relaxed_block_layout when checking standard uniform, storage buffer, and push constant layouts. This is the default when targeting Vulkan 1.1 or later.", "");
|
opts.optflagopt("", "relax-block-layout", "Enable VK_KHR_relaxed_block_layout when checking standard uniform, storage buffer, and push constant layouts. This is the default when targeting Vulkan 1.1 or later.", "");
|
||||||
@ -328,6 +337,8 @@ impl CodegenArgs {
|
|||||||
let disassemble_entry = matches.opt_str("disassemble-entry");
|
let disassemble_entry = matches.opt_str("disassemble-entry");
|
||||||
let disassemble_globals = matches.opt_present("disassemble-globals");
|
let disassemble_globals = matches.opt_present("disassemble-globals");
|
||||||
|
|
||||||
|
let name_variables = matches.opt_present("name-variables");
|
||||||
|
|
||||||
let relax_struct_store = matches.opt_present("relax-struct-store");
|
let relax_struct_store = matches.opt_present("relax-struct-store");
|
||||||
let relax_logical_pointer = matches.opt_present("relax-logical-pointer");
|
let relax_logical_pointer = matches.opt_present("relax-logical-pointer");
|
||||||
let relax_block_layout = matches.opt_present("relax-block-layout");
|
let relax_block_layout = matches.opt_present("relax-block-layout");
|
||||||
@ -344,6 +355,8 @@ impl CodegenArgs {
|
|||||||
disassemble_entry,
|
disassemble_entry,
|
||||||
disassemble_globals,
|
disassemble_globals,
|
||||||
|
|
||||||
|
name_variables,
|
||||||
|
|
||||||
relax_struct_store,
|
relax_struct_store,
|
||||||
relax_logical_pointer,
|
relax_logical_pointer,
|
||||||
relax_block_layout,
|
relax_block_layout,
|
||||||
|
@ -137,10 +137,17 @@ fn link_exe(
|
|||||||
codegen_results,
|
codegen_results,
|
||||||
);
|
);
|
||||||
|
|
||||||
let spv_binary = do_link(sess, &objects, &rlibs, legalize, emit_multiple_modules);
|
|
||||||
|
|
||||||
let cg_args = crate::codegen_cx::CodegenArgs::from_session(sess);
|
let cg_args = crate::codegen_cx::CodegenArgs::from_session(sess);
|
||||||
|
|
||||||
|
let spv_binary = do_link(
|
||||||
|
sess,
|
||||||
|
&cg_args,
|
||||||
|
&objects,
|
||||||
|
&rlibs,
|
||||||
|
legalize,
|
||||||
|
emit_multiple_modules,
|
||||||
|
);
|
||||||
|
|
||||||
let mut root_file_name = out_filename.file_name().unwrap().to_owned();
|
let mut root_file_name = out_filename.file_name().unwrap().to_owned();
|
||||||
root_file_name.push(".dir");
|
root_file_name.push(".dir");
|
||||||
let out_dir = out_filename.with_file_name(root_file_name);
|
let out_dir = out_filename.with_file_name(root_file_name);
|
||||||
@ -221,10 +228,11 @@ fn post_link_single_module(
|
|||||||
preserve_spec_constants: false,
|
preserve_spec_constants: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let spv_binary = if sess.opts.optimize != OptLevel::No || sess.opts.debuginfo == DebugInfo::None
|
let spv_binary = if sess.opts.optimize != OptLevel::No
|
||||||
|
|| (sess.opts.debuginfo == DebugInfo::None && !cg_args.name_variables)
|
||||||
{
|
{
|
||||||
let _timer = sess.timer("link_spirv_opt");
|
let _timer = sess.timer("link_spirv_opt");
|
||||||
do_spirv_opt(sess, spv_binary, out_filename, opt_options)
|
do_spirv_opt(sess, cg_args, spv_binary, out_filename, opt_options)
|
||||||
} else {
|
} else {
|
||||||
spv_binary
|
spv_binary
|
||||||
};
|
};
|
||||||
@ -249,6 +257,7 @@ fn post_link_single_module(
|
|||||||
|
|
||||||
fn do_spirv_opt(
|
fn do_spirv_opt(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
cg_args: &crate::codegen_cx::CodegenArgs,
|
||||||
spv_binary: Vec<u32>,
|
spv_binary: Vec<u32>,
|
||||||
filename: &Path,
|
filename: &Path,
|
||||||
options: spirv_tools::opt::Options,
|
options: spirv_tools::opt::Options,
|
||||||
@ -270,7 +279,7 @@ fn do_spirv_opt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sess.opts.debuginfo == DebugInfo::None {
|
if sess.opts.debuginfo == DebugInfo::None && !cg_args.name_variables {
|
||||||
optimizer
|
optimizer
|
||||||
.register_pass(opt::Passes::EliminateDeadConstant)
|
.register_pass(opt::Passes::EliminateDeadConstant)
|
||||||
.register_pass(opt::Passes::StripDebugInfo);
|
.register_pass(opt::Passes::StripDebugInfo);
|
||||||
@ -484,6 +493,7 @@ pub fn read_metadata(rlib: &Path) -> Result<MetadataRef, String> {
|
|||||||
/// shenanigans to collect all the object files we need to link.
|
/// shenanigans to collect all the object files we need to link.
|
||||||
fn do_link(
|
fn do_link(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
cg_args: &crate::codegen_cx::CodegenArgs,
|
||||||
objects: &[PathBuf],
|
objects: &[PathBuf],
|
||||||
rlibs: &[PathBuf],
|
rlibs: &[PathBuf],
|
||||||
legalize: bool,
|
legalize: bool,
|
||||||
@ -540,6 +550,7 @@ fn do_link(
|
|||||||
mem2reg: legalize,
|
mem2reg: legalize,
|
||||||
structurize: env::var("NO_STRUCTURIZE").is_err(),
|
structurize: env::var("NO_STRUCTURIZE").is_err(),
|
||||||
emit_multiple_modules,
|
emit_multiple_modules,
|
||||||
|
name_variables: cg_args.name_variables,
|
||||||
};
|
};
|
||||||
|
|
||||||
let link_result = linker::link(sess, modules, &options);
|
let link_result = linker::link(sess, modules, &options);
|
||||||
|
@ -29,6 +29,7 @@ pub struct Options {
|
|||||||
pub mem2reg: bool,
|
pub mem2reg: bool,
|
||||||
pub structurize: bool,
|
pub structurize: bool,
|
||||||
pub emit_multiple_modules: bool,
|
pub emit_multiple_modules: bool,
|
||||||
|
pub name_variables: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum LinkResult {
|
pub enum LinkResult {
|
||||||
@ -251,6 +252,11 @@ pub fn link(sess: &Session, mut inputs: Vec<Module>, opts: &Options) -> Result<L
|
|||||||
duplicates::remove_duplicate_lines(&mut output);
|
duplicates::remove_duplicate_lines(&mut output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.name_variables {
|
||||||
|
let _timer = sess.timer("link_name_variables");
|
||||||
|
simple_passes::name_variables_pass(&mut output);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let _timer = sess.timer("link_sort_globals");
|
let _timer = sess.timer("link_sort_globals");
|
||||||
simple_passes::sort_globals(&mut output);
|
simple_passes::sort_globals(&mut output);
|
||||||
|
@ -129,3 +129,25 @@ pub fn sort_globals(module: &mut Module) {
|
|||||||
// have a function declaration without a body in a fully linked module?
|
// have a function declaration without a body in a fully linked module?
|
||||||
module.functions.sort_by_key(|f| !f.blocks.is_empty());
|
module.functions.sort_by_key(|f| !f.blocks.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name_variables_pass(module: &mut Module) {
|
||||||
|
let variables = module
|
||||||
|
.types_global_values
|
||||||
|
.iter()
|
||||||
|
.filter(|inst| inst.class.opcode == Op::Variable)
|
||||||
|
.map(|inst| inst.result_id.unwrap())
|
||||||
|
.collect::<FxHashSet<Word>>();
|
||||||
|
module
|
||||||
|
.debug_names
|
||||||
|
.retain(|inst| variables.contains(&inst.operands[0].unwrap_id_ref()));
|
||||||
|
module
|
||||||
|
.types_global_values
|
||||||
|
.retain(|inst| inst.class.opcode != Op::Line);
|
||||||
|
for func in &mut module.functions {
|
||||||
|
for block in &mut func.blocks {
|
||||||
|
block
|
||||||
|
.instructions
|
||||||
|
.retain(|inst| inst.class.opcode != Op::Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -95,6 +95,7 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, String> {
|
|||||||
mem2reg: false,
|
mem2reg: false,
|
||||||
structurize: false,
|
structurize: false,
|
||||||
emit_multiple_modules: false,
|
emit_multiple_modules: false,
|
||||||
|
name_variables: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assert_eq!(compiler.session().has_errors(), res.is_err());
|
assert_eq!(compiler.session().has_errors(), res.is_err());
|
||||||
|
@ -133,6 +133,7 @@ pub struct SpirvBuilder {
|
|||||||
target: String,
|
target: String,
|
||||||
bindless: bool,
|
bindless: bool,
|
||||||
multimodule: bool,
|
multimodule: bool,
|
||||||
|
name_variables: bool,
|
||||||
capabilities: Vec<Capability>,
|
capabilities: Vec<Capability>,
|
||||||
extensions: Vec<String>,
|
extensions: Vec<String>,
|
||||||
|
|
||||||
@ -154,6 +155,7 @@ impl SpirvBuilder {
|
|||||||
target: target.into(),
|
target: target.into(),
|
||||||
bindless: false,
|
bindless: false,
|
||||||
multimodule: false,
|
multimodule: false,
|
||||||
|
name_variables: false,
|
||||||
capabilities: Vec::new(),
|
capabilities: Vec::new(),
|
||||||
extensions: Vec::new(),
|
extensions: Vec::new(),
|
||||||
|
|
||||||
@ -193,6 +195,15 @@ impl SpirvBuilder {
|
|||||||
self
|
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;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a capability to the SPIR-V module. Checking if a capability is enabled in code can be
|
/// Adds a capability to the SPIR-V module. Checking if a capability is enabled in code can be
|
||||||
/// done via `#[cfg(target_feature = "TheCapability")]`.
|
/// done via `#[cfg(target_feature = "TheCapability")]`.
|
||||||
pub fn capability(mut self, capability: Capability) -> Self {
|
pub fn capability(mut self, capability: Capability) -> Self {
|
||||||
@ -352,6 +363,9 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
|
|||||||
if builder.multimodule {
|
if builder.multimodule {
|
||||||
llvm_args.push("--module-output=multiple");
|
llvm_args.push("--module-output=multiple");
|
||||||
}
|
}
|
||||||
|
if builder.name_variables {
|
||||||
|
llvm_args.push("--name-variables");
|
||||||
|
}
|
||||||
if builder.relax_struct_store {
|
if builder.relax_struct_store {
|
||||||
llvm_args.push("--relax-struct-store");
|
llvm_args.push("--relax-struct-store");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user